[
  {
    "path": ".github/dependabot.yml",
    "content": "# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuring-dependabot-version-updates\n\nversion: 2\nupdates:\n- package-ecosystem: maven\n  directory: /\n  schedule:\n    interval: monthly\n- package-ecosystem: github-actions\n  directory: /\n  schedule:\n    interval: monthly\n"
  },
  {
    "path": ".github/workflows/cd.yaml",
    "content": "# Note: additional setup is required, see https://www.jenkins.io/redirect/continuous-delivery-of-plugins\n\nname: cd\non:\n  workflow_dispatch:\n  check_run:\n    types:\n      - completed\n\njobs:\n  maven-cd:\n    uses: jenkins-infra/github-reusable-workflows/.github/workflows/maven-cd.yml@v1\n    secrets:\n      MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }}\n      MAVEN_TOKEN: ${{ secrets.MAVEN_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/jenkins-security-scan.yml",
    "content": "name: Jenkins Security Scan\n\non:\n  push:\n    branches:\n      - master\n  pull_request:\n    types: [ opened, synchronize, reopened ]\n  workflow_dispatch:\n\npermissions:\n  security-events: write\n  contents: read\n  actions: read\n\njobs:\n  security-scan:\n    uses: jenkins-infra/jenkins-security-scan/.github/workflows/jenkins-security-scan.yaml@v2\n    with:\n      java-cache: 'maven' # Optionally enable use of a build dependency cache. Specify 'maven' or 'gradle' as appropriate.\n      # java-version: 21 # Optionally specify what version of Java to set up for the build, or remove to use a recent default.\n"
  },
  {
    "path": ".gitignore",
    "content": "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",
    "content": "<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\">\n  <extension>\n    <groupId>io.jenkins.tools.incrementals</groupId>\n    <artifactId>git-changelist-maven-extension</artifactId>\n    <version>1.13</version>\n  </extension>\n</extensions>\n"
  },
  {
    "path": ".mvn/maven.config",
    "content": "-Pconsume-incrementals\n-Pmight-produce-incrementals\n-Dchangelist.format=%d.v%s"
  },
  {
    "path": "Jenkinsfile",
    "content": "properties([\n    buildDiscarder(logRotator(numToKeepStr: '5')),\n    disableConcurrentBuilds(abortPrevious: true)\n])\n\nnode('linux-amd64') {\n    stage('Checkout') {\n        infra.checkoutSCM()\n    }\n\n    stage('Build') {\n        withEnv(['PATH+LOCAL=/home/jenkins/.local/bin']) {\n            sh 'pip install --upgrade pip'\n            sh 'pip install -r requirements.txt'\n            \n            def args = ['clean', 'install', '-Dset.changelist']\n            infra.runMaven(args, 25)\n        }\n    }\n\n    stage('Archive') {\n        junit '**/target/surefire-reports/TEST-*.xml'\n        infra.prepareToPublishIncrementals()\n    }\n}\n\ninfra.maybePublishIncrementals()\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2019 Jenkins\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
  },
  {
    "path": "README.md",
    "content": "# Performance Plugin for Jenkins CI\n\n\nLinks:\n - [Documentation](http://jenkinsci.github.io/performance-plugin/)\n   - [Running Tests](http://jenkinsci.github.io/performance-plugin/RunTests.html)\n   - [Performance Trend Reports](http://jenkinsci.github.io/performance-plugin/Reporting.html)\n - [Jenkins Plugins Entry](https://wiki.jenkins-ci.org/display/JENKINS/Performance+Plugin)\n - [Changelog](http://jenkinsci.github.io/performance-plugin/Changelog.html)\n \nExample Report:\n ![](docs/report_seclevel.png)\n"
  },
  {
    "path": "docs/.gitkeep",
    "content": ""
  },
  {
    "path": "docs/Changelog.md",
    "content": "<small>[<< Back to main page](./)</small>\n# Changelog\n\n## v3.20 (13th of July, 2021)\n- FIX: compatibility with Jenkins 2.264+ (tables to div) [JENKINS-64990](https://issues.jenkins-ci.org/browse/JENKINS-64990)\n\n## v3.19 (8th of March, 2021)\n- ADD: Option to enable/disable trend graphs within Performance Report [JENKINS-64638](https://issues.jenkins-ci.org/browse/JENKINS-64638)\n- ADD: Possibility yo explicitly set the PATH to `virtualenv`\n- FIX: travis ci\n\n## v3.18 (20th of July, 2020)\n- ADD: Locust report files parser\n- ADD: Response times scatter plot\n- ADD: Percentile and throughput chart to URI report page\n- ADD: Error chart to URI report page\n\n## v3.17 (17th of June, 2019)\n- FIX: Fix ineffective report cache [JENKINS-57997](https://issues.jenkins-ci.org/browse/JENKINS-57997)\n- FIX: Remove redundant report loading\n\n## v3.16 (28th of March, 2019)\n- 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)\n- FIX: Switch from table to entry [JENKINS-55787](https://issues.jenkins-ci.org/browse/JENKINS-55787)\n- FIX: java 9 compatibility\n\n## v3.15 (29th of January, 2019)\n- ADD: network traffic when parsing JMeter CSV. Developed by [Philippe M.](https://github.com/pmouawad) and sponsored by [Ubik Load Pack](https://ubikloadpack.com) \n\n## v3.14 (14th of December, 2018)\n- FIX: StackOverflowError for jobs with 2k+ builds\n\n## v3.13 (1st of November, 2018)\n- FIX: set default values for percentiles\n- ADD: baseline build for Performance Trend\n\n## v3.12 (11th of September, 2018)\n- FIX: pass envVars from pipeline script to Taurus\n- FIX: search report files using Ant pattern\n- ADD: JUnit timestamp parsing\n- ADD: a safe division where division by 0 can occur\n\n## v3.11 (25th of July, 2018)\n- ADD: write results xml file to disk for standard mode output\n- FIX: Support [JEP-200](https://jenkins.io/blog/2018/01/13/jep-200/)\n\n## v3.10 (1st of June, 2018)\n- FIX: relative thresholds\n\n## v3.9 (1st of June, 2018)\n- FIX: parse Taurus tool parameters;\n- FIX: hide Trend/URI graphs if report contains only summary info\n- FIX: division by zero error\n\n## v3.8 (13th of April, 2018)\n- ADD: charts to `Performance report` page\n- FIX: relative constraint failure on first build. Contributed by [Till Neunast](https://github.com/tilln)\n\n## v3.7 (skipped)\n\n## v3.6 (14th of March, 2018)\n- Support [JEP-200](https://jenkins.io/blog/2018/01/13/jep-200/)\n \n## v3.5 (29th of January, 2018)\n- FIX: Display Performance Report Per Test Case\n- FIX: NullPointerException in ConstraintFactory\n- FIX: NumberFormatException in RelativeConstraint\n- FIX: RelativeConstraint.tolerance and AbsoluteConstraint.value fields in UI\n- ADD: move some options to Advanced\n- ADD: choosing display percentiles\n\n## v3.4 (12th of December, 2017)\n- FEATURE: add LoadRunner parser. Contributed by [Till Neunast](https://github.com/tilln)\n- FEATURE: add option to write a JUnit report file to the job's workspace\n- FEATURE: add summary table of failed constraints for Publisher log in expert mode\n- FEATURE: add Descriptor Symbols for nicer Constraints BuildStep syntax\n- FEATURE: add 90th percentile difference in publisher summary table\n- 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)\n- FIX: size column width logging of relative comparision results\n- FIX: publisher JUnit output to Slave workspace\n\n## v3.3 (21th of August, 2017)\n- FEATURE: install 'bzt' from URL or path\n- FEATURE: add option to exclude response time of errored samples ([JENKINS-45288](https://issues.jenkins-ci.org/browse/JENKINS-45288))\n- FIX: summarizer parser for JMeter 3.2 \n- FIX: does not present graphs while job running \n- FIX: wrong time values for uri reports \n- FIX: unused `failBuildIfNoResultFile` flag \n- FIX: always enabled `modePerformancePerTestCase` \n- FIX: remove unused `modeRelativeThresholds` flag ([JENKINS-39050](https://issues.jenkins-ci.org/browse/JENKINS-39050))\n- FIX: wrong calculation of Average Throughput ([JENKINS-44410](https://issues.jenkins-ci.org/browse/JENKINS-44410))\n- FIX: recognize JUnit file format which wrote as single line ([JENKINS-45723](https://issues.jenkins-ci.org/browse/JENKINS-45723))\n- FIX: dependency that require code v2.62+\n- FIX: show only chart legend ([JENKINS-45539](https://issues.jenkins-ci.org/browse/JENKINS-45539))\n- FIX: virtualenv error in job which contains spaces in name\n- 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)\n- FIX: logging for expert criteria works with pipeline without throwing exceptions. Contributed by [Till Neunast](https://github.com/tilln)\n\n## v3.2 (14th of July, 2017)\n- FIX: Absolute path in Publisher ([JENKINS-45119](https://issues.jenkins-ci.org/browse/JENKINS-45119))\n- FIX: Comparison to baseline\n- FEATURE: Add `Always use virtualenv` option\n- FIX: Changing build status with default comparison option\n- FIX: Split params for build step\n- FIX: Saving RelativeUnstableThresholdNegative. Contributed by [Märt Bakhoff](https://github.com/mbakhoff)\n- FIX: add PerformanceProjectAction only to runs, which contain PerformanceBuildAction \n\n## v3.1 (2nd of June, 2017)\n- FEATURE: Snippet Generator generates nice and simple pipeline scripts for Performance Test & Performance Publisher. Contributed by [Andrew Bayer](https://github.com/abayer)\n- FEATURE: Add option to choose graphed metric. Contributed by [Märt Bakhoff](https://github.com/mbakhoff)\n- FEATURE: Add option to choose bzt version\n- FIX: Showing overall report link in pipeline mode\n\n## v3.0\n\n- FEATURE: add build step to run performance test\n- FIX: compact table stats to fit into screen\n- FIX: fix FileNotFound error\n- FIX: use proper CSV reader to read multiline and quoted CSV values\n- FIX: Pipeline Snippet Generator shows broken config\n\n## v2.2\n- FEATURE: make plugin to autodetect input file formats\n- FEATURE: add \"perfReport\" Groovy command\n- FIX: revive broken \"constraints\" gui, improve GUI display\n\n## v2.1\n- FEATURE: add support for Taurus Final Stats XML\n- FIX: improve CPU and memory usage\n- FIX: datetime format parsing and couple of NPEs\n\n## v2.0\n- FEATURE: Make it pipeline compatible \n- FIX: Testcase trend charts display the values for last sample\n\n## v1.15\n- FEATURE: Implemented absolute and relative constraints\n- FIX: Sort correctly on date values\n- FIX: Fix for uri column value not shown as link\n- FIX: Use 0 for time when no value is provided in Junit test result\n- FIX: Fix for Junit parser not handling errors\n- FIX: Fix for wrong index when calculating 90Line\n- FIX: Fix number format exception\n- FIX: Fix for Jmeter summariser parser not showing correct data\n- FIX: Fix for parsing jtl with CSV data\n\n## v1.14\n- FEATURE: Add checkbox in job config in order to choose build status when result performance file are not present\n- IMPROVEMENT: Make csv fields case insensitive\n- IMPROVEMENT: Cleaned up English localization\n- IMPROVEMENT: Compatible with flexible publisher\n- FIX: Rounding error on aggregated throughput\n- FIX: Fix conversion failure with locale using comma as decimal separator\n\n## v1.13\n- FEATURE: Added variable checking and fail to filesystem check on files\n- FIX: Allow parameter substitution in report files\n- FIX: Add class name to URIs\n- FIX: Many improvements in performance parsing files and caching results\n- FIX: Compare only against last success builds\n\n## v1.10\n- FIX: Cache preprocessed JMeter Reports to avoid performance issues.\n- FEATURE: Added comparison between builds\n- FIX: UI bug always showing same values regardless of what was saved.\n- FEATURE: Average response time thresholds per jtl file.\n- FIX: Corrected a bug where the 'All URIs' was just displaying the last entry again.\n- 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.\n\n## v1.9\n- FIX: don't use ; as separator in cookie value\n- FEATURE: added csv parser\n- FEATURE: added response time trend graph for selected build\n- FEATURE: builds trends for responce time\n- FEATURE: consider the time for each test case in a test suite\n- FEATURE: simple cache added\n- FEATURE: new response time graphs selected build and uri report\n- FEATURE: new graphs for response time trends\n- FEATURE: parse JMeter summarizer files\n\n## v1.8\n- FIX: parsing results of long running tests\n- FIX: differences not shown for old builds\n- FEATURE: more information columns in the report map\n- CHANGES: use negative values to indicate no threshold (this allows to use 0% thresholds)\n- FEATURE: graphs available on the reports\n- FEATURE: url parameter (buildCount) to control the number of builds to display\n- FEATURE: get a larger image when clicking on a graph\n\n## v1.7\n- FIX: Unstable test set final build incorrectly when a previous test failed.\n- FIX: JENKINS-9655, didn't parse JUnit reports correctly (patch: Attila-Mihaly)\n\n## v1.6\n- Fix JMeter parser when nested xml tags are in the report.\n\n## v1.5\n- Now computes median and 90% Line in jmeter test results.\n\n## v1.4\n- Just a control version published after migrating the plugin to gitHub infrastructure.\n\n## v1.3\n- Formalized an extension point to define custom parsers so as it should be easier add new parsers.\n- JMeter and JUnit parsers have been split in different classes.\n- Added a new Trend report.\n- Fixed an NPE when a build was failed (JENKINS-5224, JENKINS-6908)\n\n## v1.2\n- Support for Ant-FileSet pattern to search  report files.\n- Improved css.\n- Localized UI elements\n- Added Spanish translation\n\n## v1.0\n- First release, moved code from JMeter plugin  v.0.3.0 to Performance v.1.0.\n- Added ability to parse junit xml report files.\n"
  },
  {
    "path": "docs/README.md",
    "content": "# Performance Plugin for Jenkins \n\n## About\n\nPerformance 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. \n\nHere's how example trend report looks like:\n![](report_seclevel.png)\n\n## Running Tests\n\nRunning tests is done with Taurus Tool and explained in detail on dedicated **[Test Running](RunTests.md)** doc page.\n\n\n## Building Reports\n\nReport building supports many formats from popular testing tools and explained in detail on dedicated **[Reporting](Reporting.md)** doc page.\n\n\n## Links\n\n- [Test Running](RunTests.md)\n- [Reporting](Reporting.md)\n- [Changelog](Changelog.md)\n- [Usage Stats](stats.html)\n- [Jenkins Plugins Entry](https://wiki.jenkins-ci.org/display/JENKINS/Performance+Plugin)\n\n\n## Troubleshooting\n\n\n\nIf 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).\n\nhttps://groups.google.com/forum/#!topic/jenkinsci-users/o_Dr7Tn0i3U\n\n## Compiling\nTo 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.\n```bash\n$ git clone https://github.com/jenkinsci/performance-plugin.git performance\n$ cd performance\n$ mvn package\n$ cp target/performance.hpi <path_to_jenkins>/data/plugins\n```\nRemember to restart jenkins in order to use reload the plugin.\nYou could read more about plugins reading these pages :\n- http://wiki.jenkins-ci.org/display/JENKINS/Checking+out+existing+plugins\n- http://wiki.jenkins-ci.org/display/JENKINS/Plugin+tutorial\n- http://wiki.jenkins-ci.org/display/JENKINS/Hosting+Plugins"
  },
  {
    "path": "docs/Reporting.md",
    "content": "<small>[<< Back to main page](./)</small>\n# Performance Trend Reporting\n\n## Features\nPerformance 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.\n\nIt includes the feature of setting the final build status as good, unstable or failed, based on the reported error percentage.\n\nReport formats supported:\n- 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\n- [Apache JMeter](https://jmeter.apache.org/) CSV and XML format, also its Summarizer log output\n- [JUnit](https://junit.org/junit5/) format (used by SoapUI for example)\n- Twitter's [Iago](https://github.com/twitter/iago)\n- [wrk](https://github.com/wg/wrk)\n- [HPE LoadRunner](https://www.microfocus.com/en-us/products/loadrunner-load-testing/overview)\n\n## Browsing Reports\n\nAs 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.\n\nIf you just have one report file, the graph of this reports will appear on the main page.\n\nIf you have more than one report file, you have to click on \"Performance Trend\" and the graphs will appear.\n\n![](report_trend.jpg)\n\n\nThe 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.\n\nThis configuration will be saved in a cookie named performance. The default configuration is: \"Show all the builds\".\n\n![](report_filter.jpg)\n         \n         \nThe link Last report in the Performance Trend Page, give us the detailed information of each report for the last build.\n\nYou can access to the data of old builds pushing on the new menu entry of each build named Performance report.\n\n![](report_single.jpg)\n\n\nIn the performance trend page, the links to Trend report shows a report with the history data of each build.\n\n\n![](report_trend_table.jpg)\n\n\n## Jenkins GUI Configuration\n\nIf you are using GUI to configure Jenkins jobs, start with adding \"Publish Pefrormance test result report\" item into your post-build actions:\n\n![](report_step_choice.png)\n\nSpecify 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`.\n\nYou 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:\n\n![](report_constraints.png)\n\n## Using from Pipeline Scripts\n\nYou 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:\n \n### Minimal configuration \n```groovy\nperfReport 'result.csv'\n```\n\n### More advanced configuration\n```groovy\nperfReport filterRegex: '', relativeFailedThresholdNegative: 1.2, relativeFailedThresholdPositive: 1.89, relativeUnstableThresholdNegative: 1.8, relativeUnstableThresholdPositive: 1.5, sourceDataFiles: 'results.csv'\n```\n\n### Minimal command for old-style invocation is this:\n\nMinimal command for old-style invocation is this:\n\n```groovy\nperformanceReport parsers: [[$class: 'JMeterParser', glob: 'result.xml']], relativeFailedThresholdNegative: 1.2, relativeFailedThresholdPositive: 1.89, relativeUnstableThresholdNegative: 1.8, relativeUnstableThresholdPositive: 1.5\n```\n"
  },
  {
    "path": "docs/RunTests.md",
    "content": "<small>[<< Back to main page](./)</small>\n# Running Performance Tests\n\n## Features\nPerformance 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.\n\n_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._\n\nInternally, build step will run Taurus tool, doing some extra work around it:\n\n- it will search for global `bzt` available, if none found it will try to use `virtualenv` to install one locally into workspace\n- it will run `bzt` with provided configs and options\n- it will set job status based on `bzt` exit code, making it unstable or failed \n- it will automatically generate [performance trend report](Reporting.md) after `bzt` finishes\n\nBuild step tries to minimally interfere with Taurus tool to let you use its full capabilities (Taurus is pretty feature-rich thing for running tests).\n\nTest runner step works fine with Jenkins slaves, as well as with Pipeline syntax (see section below.)\n\n\n## Jenkins GUI Configuration\nIf you are using GUI-based job configs for Jenkins, choose \"Run Performance Test\" step from \"Add build step\" menu:\n\n![](run_step_choice.png)\n\nIn 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:\n\n![](run_jmeter.png)\n\nIf 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.\n\n![](run_extended_config.png)\n\nClicking on \"Advanced...\" will open several options that can alter build step behavior:\n\n- _Change working directory_ - set working directory in which test will be run, by default will be used build workspace\n- _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 \n- _Always use virtualenv_ - enable this flag if you want to install `bzt` into `virtualenv`\n- _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\n- _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\n- _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\n- _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\n\n## Using from Pipeline Scripts\n\nHere's example pipeline script to use build step with `bzt` command that maps to Taurus Tool invocation.\n\n```groovy\nnode {\n    stage(\"clean\") {\n        cleanWs()   // requires workspace cleanup plugin to be installed\n    }\n    \n    stage('get config file') {\n            sh \"wget https://raw.githubusercontent.com/Blazemeter/taurus/master/examples/jmeter/stepping.yml\"\n    }\n    \n    stage(\"run test\") {\n        bzt \"stepping.yml\"\n    }\n}\n```\n\n## Other Ways to Run Test in Jenkins (deprecated)\n\n### Using jmeter in a 'MAVEN' project\nFollow the instructions in this [article](http://www.theserverlabs.com/blog/?p=280&cpage=1)\n\n### Using jmeter in an 'ANT' project\nAlthough there are different ways to run jmeter tests, here is explained a method to run them using ant.\n\nOnce 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.\n\nFinally run your project setting the property jmeter-home to the appropriate folder in your computer: `ant \"-Djmeter-home=C:\\jmeter\" -f build.xml`\n\n```xml\n<project default=\"all\">\n  <!-- ant-jmeter.jar comes with jmeter, be sure this is the release you have -->\n  <path id=\"ant.jmeter.classpath\">\n    <pathelement\n       location=\"${jmeter-home}/extras/ant-jmeter-1.1.1.jar\" />\n  </path>\n  <taskdef\n    name=\"jmeter\"\n    classname=\"org.programmerplanet.ant.taskdefs.jmeter.JMeterTask\"\n    classpathref=\"ant.jmeter.classpath\" />\n  <target name=\"clean\">\n    <delete dir=\"results\"/>\n    <delete file=\"jmeter.log\"/>\n    <mkdir dir=\"results/jtl\"/>\n    <mkdir dir=\"results/html\"/>\n  </target>\n  <target name=\"test\" depends=\"clean\">\n    <jmeter\n       jmeterhome=\"${jmeter-home}\"\n       resultlogdir=\"results/jtl\">\n      <testplans dir=\"test/jmeter\" includes=\"*.jmx\"/>\n      <property name=\"jmeter.save.saveservice.output_format\" value=\"xml\"/>\n    </jmeter>\n  </target>\n  <!-- This is not needed for the plugin, but it produces a nice html report\n       which can be saved usin jenkins's archive artifact feature -->\n  <target name=\"report\" depends=\"test\">\n    <xslt\n       basedir=\"results/jtl\"\n       destdir=\"results/html\"\n       includes=\"*.jtl\"\n       style=\"${jmeter-home}/extras/jmeter-results-detail-report_21.xsl\"/>\n  </target>\n  <target name=\"all\" depends=\"test, report\"/>\n</project>\n```"
  },
  {
    "path": "docs/_config.yml",
    "content": "theme: jekyll-theme-cayman"
  },
  {
    "path": "docs/stats.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en-us\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Statistics</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <meta name=\"theme-color\" content=\"#157878\">\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\"\n          href=\"http://jenkinsci.github.io/performance-plugin/assets/css/style.css?v=ae639cea1586341f89b4711f8e51ffa156d402b6\">\n\n</head>\n<body>\n<section class=\"page-header\">\n    <h1 class=\"project-name\">performance-plugin</h1>\n    <h2 class=\"project-tagline\">Performance Plugin for Jenkins CI</h2>\n\n    <a href=\"https://github.com/jenkinsci/performance-plugin\" class=\"btn\">View on GitHub</a>\n\n\n</section>\n\n<section class=\"main-content\">\n    <small><a href=\"./\">&lt;&lt; Back to main page</a></small>\n    <h1 id=\"test\">Usage Statistics</h1>\n\n    <div id=\"installations\" style=\"min-width: 310px; height: 400px; margin: 0 auto\"></div>\n    <hr/>\n    <div id=\"versions\" style=\"min-width: 310px; height: 400px; margin: 0 auto\"></div>\n\n\n    <footer class=\"site-footer\">\n\n        <span class=\"site-footer-owner\"><a href=\"https://github.com/jenkinsci/performance-plugin\">performance-plugin</a> is maintained by <a\n                href=\"https://github.com/jenkinsci\">jenkinsci</a>.</span>\n\n        <span class=\"site-footer-credits\">This page was generated by <a href=\"https://pages.github.com\">GitHub Pages</a>.</span>\n    </footer>\n</section>\n\n<script src=\"https://code.jquery.com/jquery-2.2.4.min.js\"></script>\n<script src=\"https://code.highcharts.com/highcharts.js\"></script>\n<script src=\"https://code.highcharts.com/modules/exporting.js\"></script>\n<script src=\"https://code.highcharts.com/modules/data.js\"></script>\n<script>\n    function values(dict) {\n        var values = [];\n        var keys = Object.keys(dict).sort();\n        for (var k = 0; k < keys.length; k++) {\n            values.push(dict[keys[k]]);\n        }\n        return values;\n    }\n\n\n    function installations(data) {\n        var counts = [];\n        var percents = [];\n        for (var key1 in data.installations) {\n            counts.push([parseInt(key1), data.installations[key1]])\n        }\n\n        for (var key2 in data.installationsPercentage) {\n            percents.push([parseInt(key2), data.installationsPercentage[key2]])\n        }\n\n        return {\n            series: [{\n                name: 'Percentage',\n                data: percents,\n                yAxis: 1,\n                color: \"silver\",\n                dashStyle: \"LongDash\",\n                lineWidth: 1\n            },\n                {\n                    name: 'Count',\n                    data: counts,\n                    lineWidth: 3\n                }],\n            title: {\n                text: 'Installations History'\n            },\n            xAxis: {\n                type: \"datetime\"\n            },\n            yAxis: [{\n                title: {\n                    text: 'Installations count'\n                },\n                endOnTick: false,\n                plotLines: [{\n                    value: 0,\n                    width: 1,\n                    color: '#808080'\n                }]\n            }, {\n                title: {\n                    text: '% of Jenkins installations'\n                },\n                labels: {\n                    formatter: function () {\n                        return this.value + ' %';\n                    }\n                },\n                endOnTick: false,\n                plotLines: [{\n                    value: 0,\n                    width: 1,\n                    color: '#808080'\n                }],\n                opposite: true\n            }],\n            tooltip: {\n                shared: true\n            },\n            legend: {\n                layout: 'vertical',\n                align: 'left',\n                x: 120,\n                verticalAlign: 'top',\n                y: 50,\n                floating: true,\n                backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColor) || '#FFFFFF'\n            }\n        };\n    }\n\n    function versions(data) {\n        data = data.installationsPercentagePerVersion;\n\n        var series = [];\n        var sum = values(data).reduce(function (a, b) {\n            return a + b;\n        }, 0);\n\n        var keys = Object.keys(data);\n        keys.sort();\n\n        var other = 0;\n        for (var n = 0; n < keys.length; n++) {\n            var ver = keys[n];\n            var val = Math.round(1000 * data[ver] / sum) / 10;\n            if (ver.indexOf('-') < 0 && val > 1) {\n                series.push(['v ' + ver, val]);\n            } else {\n                other += val;\n            }\n        }\n\n        if (other) {\n            series.push(['Other', other]);\n        }\n\n        return {\n            plotOptions: {\n                series: {\n                    animation: false\n                }\n            },\n            chart: {\n                type: 'column'\n            },\n\n            title: {\n                text: 'Installations by Version'\n            },\n            xAxis: {\n                type: 'category'\n            },\n            yAxis: {\n                title: {\n                    text: '% of known installations'\n                },\n                labels: {\n                    formatter: function () {\n                        return this.value + ' %';\n                    }\n                },\n                endOnTick: false,\n                plotLines: [{\n                    value: 0,\n                    width: 1,\n                    color: '#808080'\n                }]\n            },\n            tooltip: {\n                valueSuffix: '%'\n            },\n            legend: {\n                enabled: false\n            },\n            series: [{\n                name: 'Percentage',\n                data: series\n            }]\n        };\n    }\n\n\n    $(document).ready(function () {\n        $.getJSON(\"http://stats.jenkins.io/plugin-installation-trend/performance.stats.json\").success(function (data) {\n            $('#installations').highcharts(installations(data));\n            $('#versions').highcharts(versions(data));\n        }).fail(function () {\n            alert(\"failed to get data\")\n        });\n    });\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n    xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.jenkins-ci.plugins</groupId>\n        <artifactId>plugin</artifactId>\n        <version>6.2153.vcf31911d10c4</version>\n        <relativePath />\n    </parent>\n\n    <artifactId>performance</artifactId>\n    <version>${changelist}</version>\n    <packaging>hpi</packaging>\n\n    <name>Performance Plugin</name>\n    <description>This plugin allows tracking performance KPIs, based on results read from popular testing tools  (JMeter, JUnit, Taurus).</description>\n    <url>https://github.com/jenkinsci/${project.artifactId}-plugin</url>\n\n    <developers>\n        <developer>\n            <id>undera</id>\n            <name>Andrey Pokhilko (CA BlazeMeter)</name>\n            <email>andrey@blazemeter.com</email>\n        </developer>\n        <developer>\n            <id>artem_fedorov</id>\n            <name>Artem Fedorov (CA BlazeMeter)</name>\n            <email>artem.fedorov@blazemeter.com</email>\n        </developer>\n        <developer>\n            <id>a_st</id>\n            <name>Alexander Straube</name>\n            <email>alexander.straube@gmail.com</email>\n        </developer>\n    </developers>\n\n    <scm child.scm.connection.inherit.append.path=\"false\"\n        child.scm.developerConnection.inherit.append.path=\"false\"\n        child.scm.url.inherit.append.path=\"false\">\n        <connection>scm:git:https://github.com/${gitHubRepo}</connection>\n        <developerConnection>scm:git:https://github.com/${gitHubRepo}</developerConnection>\n        <tag>${scmTag}</tag>\n        <url>https://github.com/${gitHubRepo}</url>\n    </scm>\n\n    <distributionManagement>\n        <repository>\n            <id>maven.jenkins-ci.org</id>\n            <url>https://repo.jenkins-ci.org/releases</url>\n        </repository>\n    </distributionManagement>\n\n    <properties>\n        <changelist>999999-SNAPSHOT</changelist>\n        <!-- https://www.jenkins.io/doc/developer/plugin-development/choosing-jenkins-baseline/ -->\n        <jenkins.baseline>2.516</jenkins.baseline>\n        <jenkins.version>${jenkins.baseline}.1</jenkins.version>\n        <gitHubRepo>jenkinsci/${project.artifactId}-plugin</gitHubRepo>\n        <hpi.bundledArtifacts>commons-csv,hsqldb,jackcess,plexus-utils,ucanaccess</hpi.bundledArtifacts>\n        <hpi.strictBundledArtifacts>true</hpi.strictBundledArtifacts>\n        <concurrency>2</concurrency>\n        <!-- disable SpotBugs temporarily since there are 62 bugs -->\n        <spotbugs.failOnError>false</spotbugs.failOnError>\n        <ban-junit4-imports.skip>false</ban-junit4-imports.skip>\n        <ban-commons-lang-2.skip>false</ban-commons-lang-2.skip>\n    </properties>\n\n    <repositories>\n        <repository>\n            <id>repo.jenkins-ci.org</id>\n            <url>https://repo.jenkins-ci.org/public/</url>\n        </repository>\n    </repositories>\n\n    <pluginRepositories>\n        <pluginRepository>\n            <id>repo.jenkins-ci.org</id>\n            <url>https://repo.jenkins-ci.org/public/</url>\n        </pluginRepository>\n    </pluginRepositories>\n\n    <dependencyManagement>\n        <dependencies>\n            <dependency>\n                <groupId>io.jenkins.tools.bom</groupId>\n                <artifactId>bom-${jenkins.baseline}.x</artifactId>\n                <version>6210.v69ea_fd8a_f010</version>\n                <type>pom</type>\n                <scope>import</scope>\n            </dependency>\n        </dependencies>\n    </dependencyManagement>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.codehaus.plexus</groupId>\n            <artifactId>plexus-utils</artifactId>\n            <version>4.0.3</version>\n        </dependency>\n        <dependency>\n            <groupId>io.jenkins.plugins</groupId>\n            <artifactId>gson-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.mockito</groupId>\n            <artifactId>mockito-core</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.mockito</groupId>\n            <artifactId>mockito-junit-jupiter</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.commons</groupId>\n            <artifactId>commons-csv</artifactId>\n            <version>1.14.1</version>\n            <exclusions>\n                <exclusion>\n                    <groupId>commons-codec</groupId>\n                    <artifactId>commons-codec</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>commons-io</groupId>\n                    <artifactId>commons-io</artifactId>\n                </exclusion>\n            </exclusions>\n        </dependency>\n        <dependency>\n            <groupId>org.jenkins-ci.plugins.workflow</groupId>\n            <artifactId>workflow-cps</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.jenkins-ci.plugins.workflow</groupId>\n            <artifactId>workflow-basic-steps</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.jenkins-ci.plugins.workflow</groupId>\n            <artifactId>workflow-job</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.jenkins-ci.plugins.workflow</groupId>\n            <artifactId>workflow-durable-task-step</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>net.sf.ucanaccess</groupId>\n            <artifactId>ucanaccess</artifactId>\n            <version>5.0.1</version>\n        </dependency>\n    </dependencies>\n</project>\n"
  },
  {
    "path": "requirements.txt",
    "content": "virtualenv\r\nbzt\r\nurwid>=3.0.2,<4.0.0\r\napiritif"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/PerformancePublisher.java",
    "content": "package hudson.plugins.performance;\n\nimport java.io.BufferedWriter;\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.OutputStreamWriter;\nimport java.io.PrintStream;\nimport java.nio.charset.StandardCharsets;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\nimport org.jenkinsci.Symbol;\nimport org.kohsuke.accmod.Restricted;\nimport org.kohsuke.accmod.restrictions.NoExternalUse;\nimport org.kohsuke.stapler.DataBoundConstructor;\nimport org.kohsuke.stapler.DataBoundSetter;\n\nimport edu.umd.cs.findbugs.annotations.NonNull;\nimport hudson.EnvVars;\nimport hudson.Extension;\nimport hudson.FilePath;\nimport hudson.Launcher;\nimport hudson.init.InitMilestone;\nimport hudson.init.Initializer;\nimport hudson.model.AbstractProject;\nimport hudson.model.Action;\nimport hudson.model.Items;\nimport hudson.model.Result;\nimport hudson.model.Run;\nimport hudson.model.TaskListener;\nimport hudson.plugins.performance.actions.ExternalBuildReportAction;\nimport hudson.plugins.performance.actions.PerformanceBuildAction;\nimport hudson.plugins.performance.actions.PerformanceProjectAction;\nimport hudson.plugins.performance.constraints.AbstractConstraint;\nimport hudson.plugins.performance.constraints.ConstraintChecker;\nimport hudson.plugins.performance.constraints.ConstraintEvaluation;\nimport hudson.plugins.performance.constraints.ConstraintFactory;\nimport hudson.plugins.performance.constraints.blocks.PreviousResultsBlock;\nimport hudson.plugins.performance.constraints.blocks.TestCaseBlock;\nimport hudson.plugins.performance.cookie.CookieHandler;\nimport hudson.plugins.performance.data.ConstraintSettings;\nimport hudson.plugins.performance.data.HttpSample;\nimport hudson.plugins.performance.data.PerformanceReportPosition;\nimport hudson.plugins.performance.data.TaurusFinalStats;\nimport hudson.plugins.performance.descriptors.ConstraintDescriptor;\nimport hudson.plugins.performance.descriptors.PerformanceReportParserDescriptor;\nimport hudson.plugins.performance.details.GraphConfigurationDetail;\nimport hudson.plugins.performance.details.TestSuiteReportDetail;\nimport hudson.plugins.performance.details.TrendReportDetail;\nimport hudson.plugins.performance.parsers.AbstractParser;\nimport hudson.plugins.performance.parsers.IagoParser;\nimport hudson.plugins.performance.parsers.JMeterCsvParser;\nimport hudson.plugins.performance.parsers.JMeterParser;\nimport hudson.plugins.performance.parsers.JUnitParser;\nimport hudson.plugins.performance.parsers.JmeterSummarizerParser;\nimport hudson.plugins.performance.parsers.ParserFactory;\nimport hudson.plugins.performance.parsers.PerformanceReportParser;\nimport hudson.plugins.performance.parsers.TaurusParser;\nimport hudson.plugins.performance.parsers.WrkSummarizerParser;\nimport hudson.plugins.performance.reports.AbstractReport;\nimport hudson.plugins.performance.reports.ConstraintReport;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.reports.ThroughputReport;\nimport hudson.plugins.performance.reports.UriReport;\nimport hudson.plugins.performance.tools.SafeMaths;\nimport hudson.tasks.BuildStepDescriptor;\nimport hudson.tasks.BuildStepMonitor;\nimport hudson.tasks.Publisher;\nimport hudson.tasks.Recorder;\nimport hudson.util.ListBoxModel;\nimport jenkins.tasks.SimpleBuildStep;\n\npublic class PerformancePublisher extends Recorder implements SimpleBuildStep {\n\n    public static final double THRESHOLD_TOLERANCE = 0.0000000000000000000000000000000000000000000000000000000000000000000000000000001;\n    private static final double DEFAULT_THRESHOLD = -1;\n\n    private int errorFailedThreshold = -1;\n\n    private int errorUnstableThreshold = -1;\n\n    private String errorUnstableResponseTimeThreshold = \"\";\n\n    private double relativeFailedThresholdPositive = DEFAULT_THRESHOLD;\n\n    private double relativeFailedThresholdNegative = DEFAULT_THRESHOLD;\n\n    private double relativeUnstableThresholdPositive = DEFAULT_THRESHOLD;\n\n    private double relativeUnstableThresholdNegative = DEFAULT_THRESHOLD;\n\n    private int nthBuildNumber = 0;\n\n    private String configType = \"ART\";\n\n    private String graphType = \"ART\";\n\n    private boolean modeOfThreshold = false;\n\n    private boolean failBuildIfNoResultFile = true;\n\n    private boolean compareBuildPrevious = false;\n\n    public static final String ART = \"ART\";\n\n    public static final String MRT = \"MRT\";\n\n    public static final String PRT = \"PRT\";\n\n    public String optionType = \"ART\";\n\n    private static final String ARCHIVE_DIRECTORY = \"archive\";\n\n    private boolean modePerformancePerTestCase = false;\n\n    /**\n     * Exclude response time of errored samples\n     */\n    private boolean excludeResponseTime;\n\n    /**\n     * Show Trends mode.\n     */\n    private boolean showTrendGraphs;\n\n    /**\n     * @deprecated as of 1.3. for compatibility\n     */\n    private transient String filename; // NOSONAR On purpose keep of transient, we don't want to save it\n\n    private boolean modeThroughput;\n\n    /**\n     * Performance evaluation mode. false = standard mode; true = expert mode\n     */\n    private boolean modeEvaluation = false;\n\n    /**\n     * Configured constraints\n     */\n    private List<? extends AbstractConstraint> constraints = Collections.emptyList();\n\n    /**\n     * Constraint settings\n     */\n    private boolean ignoreFailedBuilds;\n    private boolean ignoreUnstableBuilds;\n    private boolean persistConstraintLog;\n\n    /**\n     * @deprecated as of 2.2. for compatibility\n     * Migrate into String reportFiles with autodetect parser type.\n     * Now this param use for restore previous job configs in GUI mode.\n     */\n    @Deprecated\n    private transient List<PerformanceReportParser> parsers; // NOSONAR On purpose keep of transient, we don't want to save it\n\n    private String sourceDataFiles;\n    private String filterRegex;\n\n    /**\n     * Optional filename indicating whether and where a JUnit compatible XML report should be written\n     */\n    private String junitOutput = \"\";\n\n    /**\n     * Percentiles that will be display in url tables\n     * comma-separated\n     */\n    private String percentiles = AbstractReport.DEFAULT_PERCENTILES;\n\n\n    /**\n     * Base line build for create performance Trends\n     * default '0' - is previous build\n     */\n    private int baselineBuild;\n\n    /**\n     * Legacy constructor used for internal references.\n     */\n    @Restricted(NoExternalUse.class)\n    public PerformancePublisher(String sourceDataFiles,\n                                int errorFailedThreshold,\n                                int errorUnstableThreshold,\n                                String errorUnstableResponseTimeThreshold,\n                                double relativeFailedThresholdPositive,\n                                double relativeFailedThresholdNegative,\n                                double relativeUnstableThresholdPositive,\n                                double relativeUnstableThresholdNegative,\n                                int nthBuildNumber,\n                                boolean modePerformancePerTestCase,\n                                String configType,\n                                boolean modeOfThreshold,\n                                boolean failBuildIfNoResultFile,\n                                boolean compareBuildPrevious,\n                                boolean modeThroughput,\n                                boolean showTrendGraphs,\n                                /**\n                                 * Deprecated. Now use for support previous pipeline jobs.\n                                 */\n                                List<PerformanceReportParser> parsers) {\n        this.parsers = parsers;\n        this.sourceDataFiles = sourceDataFiles;\n        migrateParsers();\n\n        this.errorFailedThreshold = errorFailedThreshold;\n        this.errorUnstableThreshold = errorUnstableThreshold;\n        this.errorUnstableResponseTimeThreshold = errorUnstableResponseTimeThreshold;\n        this.showTrendGraphs = showTrendGraphs;\n\n        this.relativeFailedThresholdPositive = relativeFailedThresholdPositive;\n        this.relativeFailedThresholdNegative = relativeFailedThresholdNegative;\n        this.relativeUnstableThresholdPositive = relativeUnstableThresholdPositive;\n        this.relativeUnstableThresholdNegative = relativeUnstableThresholdNegative;\n\n        this.nthBuildNumber = nthBuildNumber;\n        this.configType = configType;\n        this.optionType = configType;\n        this.modeOfThreshold = modeOfThreshold;\n        this.failBuildIfNoResultFile = failBuildIfNoResultFile;\n        this.compareBuildPrevious = compareBuildPrevious;\n\n        this.modePerformancePerTestCase = modePerformancePerTestCase;\n        this.modeThroughput = modeThroughput;\n    }\n\n    @DataBoundConstructor\n    public PerformancePublisher(String sourceDataFiles) {\n        this.sourceDataFiles = sourceDataFiles;\n    }\n\n    public static File getPerformanceReport(Run<?, ?> build, String parserDisplayName,\n                                            String performanceReportName) {\n        return new File(build.getRootDir(), PerformanceReportMap.getPerformanceReportFileRelativePath(parserDisplayName,\n                getPerformanceReportBuildFileName(performanceReportName)));\n    }\n\n    @Override\n    public Action getProjectAction(AbstractProject<?, ?> project) {\n        return new PerformanceProjectAction(project);\n    }\n\n    public BuildStepMonitor getRequiredMonitorService() {\n        return BuildStepMonitor.NONE;\n    }\n\n\n    /**\n     * <p>\n     * Delete the date suffix appended to the Performance result files by the\n     * Maven Performance plugin\n     * </p>\n     *\n     * @return the name of the PerformanceReport in the Build\n     */\n    public static String getPerformanceReportBuildFileName(String performanceReportWorkspaceName) {\n        String result = performanceReportWorkspaceName;\n        if (performanceReportWorkspaceName != null) {\n            Pattern p = Pattern.compile(\"-[0-9]*\\\\.xml\");\n            Matcher matcher = p.matcher(performanceReportWorkspaceName);\n            if (matcher.find()) {\n                result = matcher.replaceAll(\".xml\");\n            }\n        }\n        return result;\n    }\n\n    /**\n     * look for performance reports based in the configured parameter includes.\n     * 'includes' is - an Ant-style pattern - a list of files and folders\n     * separated by the characters ;:,\n     */\n    protected static List<FilePath> locatePerformanceReports(FilePath workspace, String includes)\n            throws IOException, InterruptedException {\n\n        // First use ant-style pattern\n        /*\n         * try { FilePath[] ret = workspace.list(includes); if (ret.length > 0) {\n         * return Arrays.asList(ret); }\n         */\n        // Agoley : Possible fix, if we specify more than one result file pattern\n        try {\n            String[] parts = includes.split(\"\\\\s*[;:,]+\\\\s*\");\n\n            List<FilePath> files = new ArrayList<>();\n            for (String path : parts) {\n                FilePath[] ret = workspace.list(path);\n                if (ret.length > 0) {\n                    files.addAll(Arrays.asList(ret));\n                }\n            }\n            if (!files.isEmpty())\n                return files;\n\n        } catch (IOException ignored) {\n            // NOOP\n        }\n\n        // Agoley: seems like this block doesn't work\n        // If it fails, do a legacy search\n        ArrayList<FilePath> files = new ArrayList<>();\n        String[] parts = includes.split(\"\\\\s*[;:,]+\\\\s*\");\n        for (String path : parts) {\n            FilePath src = workspace.child(path);\n            if (src.exists()) {\n                if (src.isDirectory()) {\n                    files.addAll(Arrays.asList(src.list(\"**/*\")));\n                } else {\n                    files.add(src);\n                }\n            }\n        }\n        if (!files.isEmpty())\n            return files;\n\n        // give up and just try direct matching on string\n        File directFile = new File(includes);\n        if (directFile.exists())\n            files.add(new FilePath(directFile));\n        return files;\n    }\n\n    protected List<PerformanceReportParser> getParsers(Run<?, ?> build, FilePath workspace, PrintStream logger, EnvVars env) throws IOException, InterruptedException {\n        final List<PerformanceReportParser> parsers = new ArrayList<>();\n        if (sourceDataFiles != null) {\n            for (String filePath : sourceDataFiles.split(\";\")) {\n                if (!filePath.isEmpty()) {\n                    try {\n                        logger.println(\"Creating parser with percentiles:'\" + percentiles + \",' filterRegex:\" + filterRegex);\n                        parsers.addAll(ParserFactory.getParser(build, workspace, logger, filePath, env, percentiles, filterRegex));\n                    } catch (IOException ex) {\n                        logger.println(\"Cannot detect file type because of error: \" + ex.getMessage());\n                    }\n                }\n            }\n        }\n        return parsers;\n    }\n\n    /**\n     * Used to migrate from user selected parser to autodetected parser\n     */\n    private void migrateParsers() {\n        if (parsers != null && !this.parsers.isEmpty()) {\n            StringBuilder builder = new StringBuilder();\n            for (PerformanceReportParser p : this.parsers) {\n                builder.append(p.glob).append(';');\n            }\n            builder.setLength(builder.length() - 1);\n            if (this.sourceDataFiles == null || this.sourceDataFiles.equals(\"\")) {\n                this.sourceDataFiles = builder.toString();\n            } else {\n                this.sourceDataFiles = this.sourceDataFiles + \";\" + builder.toString();\n            }\n            this.parsers = null;\n        }\n    }\n\n    /**\n     * This method, invoked after object is resurrected from persistence\n     */\n    public Object readResolve() {\n        // data format migration\n        if (parsers == null)\n            parsers = new ArrayList<>();\n        if (filename != null) {\n            parsers.add(new JMeterParser(filename, percentiles, filterRegex));\n            filename = null;\n        }\n        // Migrate parsers to simple field sourceDataFiles.\n        migrateParsers();\n        return this;\n    }\n\n\n    @Override\n    public void perform(@NonNull Run<?, ?> run, @NonNull FilePath workspace, @NonNull Launcher launcher, @NonNull TaskListener listener)\n            throws InterruptedException, IOException {\n        run.setResult(Result.SUCCESS);\n\n        final List<PerformanceReportParser> parsers = getParsers(run, workspace, listener.getLogger(), run.getEnvironment(listener));\n        if (!parsers.isEmpty()) {\n            prepareParsers(parsers);\n\n            Collection<PerformanceReport> parsedReports = prepareEvaluation(run, workspace, listener, parsers);\n            if (parsedReports == null) {\n                return;\n            }\n\n            if (!modeEvaluation) {\n                evaluateInStandardMode(run, workspace, parsedReports, listener, parsers);\n                writeStandardResultsToXML(run, parsedReports);\n            } else {\n                evaluateInExpertMode(run, workspace, listener);\n            }\n        } else {\n            if (failBuildIfNoResultFile) {\n                run.setResult(Result.FAILURE);\n            }\n        }\n    }\n\n    /**\n     * preparing evaluation - this is necessary regardless of the mode of\n     * evaluation\n     */\n    public Collection<PerformanceReport> prepareEvaluation(Run<?, ?> run, FilePath workspace, TaskListener listener, List<PerformanceReportParser> parsers)\n            throws IOException, InterruptedException {\n\n        // add the report to the build object.\n        PerformanceBuildAction a = new PerformanceBuildAction(run, listener.getLogger(), parsers);\n        run.addAction(a);\n\n        Collection<PerformanceReport> parsedReports = locatePerformanceReports(run, workspace, listener, parsers);\n        if (parsedReports == null) {\n            return Collections.emptyList();\n        }\n\n        addExternalReportActionsToBuild(run, parsers);\n\n        for (PerformanceReport r : parsedReports) {\n            r.setBuildAction(a);\n        }\n\n        return parsedReports;\n    }\n\n    private void addExternalReportActionsToBuild(Run<?, ?> run, List<PerformanceReportParser> parsers) {\n        for (PerformanceReportParser parser : parsers) {\n            if (parser.reportURL != null && !parser.reportURL.isEmpty()) {\n                run.addAction(new ExternalBuildReportAction(parser.reportURL));\n            }\n        }\n    }\n\n    private Collection<PerformanceReport> locatePerformanceReports(Run<?, ?> run, FilePath workspace, TaskListener listener, List<PerformanceReportParser> parsers) throws IOException, InterruptedException {\n        Collection<PerformanceReport> performanceReports = new ArrayList<>();\n        PrintStream logger = listener.getLogger();\n        EnvVars env = run.getEnvironment(listener);\n        String glob;\n        for (PerformanceReportParser parser : parsers) {\n            glob = parser.glob;\n            // Replace any runtime environment variables such as ${sample_var}\n            glob = env.expand(glob);\n            logger.println(\"Performance: Recording \" + parser.getReportName() + \" reports '\" + glob + \"'\");\n\n            List<FilePath> files = locatePerformanceReports(workspace, glob);\n            if (files.isEmpty()) {\n                Result result = run.getResult();\n                if (result != null) {\n                    if (result.isWorseThan(Result.UNSTABLE)) {\n                        return Collections.emptyList();\n                    }\n                } else {\n                    // Handle the situation when result is null\n                    logger.println(\"Result is null\");\n                }\n\n                if (failBuildIfNoResultFile) {\n                    run.setResult(Result.FAILURE);\n                }\n                logger.println(\"Performance: no \" + parser.getReportName() + \" files matching '\" + glob\n                        + \"' have been found. Has the report generated?. Setting Build to \" + run.getResult());\n                return Collections.emptyList();\n            }\n\n            logger.println(\"Performance: \" + parser.getReportName() + \" copying reports to master, files '\" + files + \"'\");\n            List<File> localReports = copyReportsToMaster(run, logger, files, parser.getDescriptor().getDisplayName());\n            logger.println(\"Performance: \" + parser.getReportName() + \" parsing local reports '\" + localReports\n                    + \"'\");\n            performanceReports.addAll(parser.parse(run, localReports, listener));\n        }\n        return performanceReports;\n    }\n\n    /**\n     *\n     */\n    private void prepareParsers(Collection<PerformanceReportParser> performanceReportParsers) {\n        for (PerformanceReportParser parser : performanceReportParsers) {\n            parser.setExcludeResponseTime(excludeResponseTime);\n            parser.setShowTrendGraphs(showTrendGraphs);\n            parser.setBaselineBuild(baselineBuild);\n        }\n    }\n\n    protected List<UriReport> getBuildUriReports(Run<?, ?> build, FilePath workspace, TaskListener listener,\n                                                 List<PerformanceReportParser> parsers, boolean locatePerformanceReports)\n            throws IOException, InterruptedException {\n\n        List<UriReport> uriReports = new ArrayList<>();\n\n        if (locatePerformanceReports) {\n            Collection<PerformanceReport> performanceReports = locatePerformanceReports(build, workspace, listener, parsers);\n            if (performanceReports == null) {\n                return Collections.emptyList();\n            }\n\n            for (PerformanceReport r : performanceReports) {\n                // URI list is the list of labels in the current JMeter results\n                // file\n                uriReports.addAll(r.getUriListOrdered());\n            }\n        } else {\n            Set<PerformanceReport> parsedReports = new HashSet<>();\n\n            for (PerformanceReportParser parser : parsers) {\n                // add the report to the build object.\n                List<File> localReports = getExistingReports(build, listener.getLogger(), parser.getDescriptor().getDisplayName());\n\n                // For more than one parser of the same type, existing reports will be found multiple times, \n                // so we collect them in a Set to avoid duplicates (based on comparison by report filename).\n                parsedReports.addAll(parser.parse(build, localReports, listener));\n            }\n\n            for (PerformanceReport r : parsedReports) {\n                // uri list is the list of labels in the previous jmeter results\n                // file\n                uriReports.addAll(r.getUriListOrdered());\n            }\n\n        }\n        return uriReports;\n    }\n\n    // for mode \"standard evaluation\"\n    public void evaluateInStandardMode(Run<?, ?> run, FilePath workspace, Collection<PerformanceReport> parsedReports,\n                                       TaskListener listener, List<PerformanceReportParser> parsers)\n            throws IOException, InterruptedException {\n\n        if (!modeOfThreshold) {\n            compareWithAbsoluteThreshold(run, listener, parsedReports);\n        } else {\n            compareWithRelativeThreshold(run, workspace, listener, parsers);\n        }\n    }\n\n\n    // For absolute error/unstable threshold..\n    public void compareWithAbsoluteThreshold(Run<?, ?> run, TaskListener listener, Collection<PerformanceReport> parsedReports) {\n        PrintStream logger = listener.getLogger();\n        try {\n            printInfoAboutErrorThreshold(logger);\n            HashMap<String, String> responseTimeThresholdMap = getResponseTimeThresholdMap(logger);\n            // add the report to the build object.\n            // mark the build as unstable or failure depending on the outcome.\n            for (PerformanceReport performanceReport : parsedReports) {\n                analyzeErrorThreshold(run, performanceReport, responseTimeThresholdMap, logger);\n                writeErrorThresholdReportInXML(run, performanceReport);\n            }\n        } catch (Exception e) {\n            logger.println(\"ERROR: Exception while determining absolute error/unstable threshold evaluation\");\n            e.printStackTrace(logger);\n        }\n    }\n\n    // analyze Unstable and Failed thresholds values and set build result to UNSTABLE or FAILURE if needed\n    private void analyzeErrorThreshold(Run<?, ?> run, PerformanceReport performanceReport, HashMap<String, String> responseTimeThresholdMap, PrintStream logger) {\n        Result result = Result.SUCCESS;\n        double errorPercent = performanceReport.errorPercent();\n\n        // check average response time values\n        Result res = checkAverageResponseTime(performanceReport, responseTimeThresholdMap, logger);\n        if (res != null) {\n            result = res;\n        }\n\n        // check failed and unstable values\n        if (errorFailedThreshold >= 0 && errorPercent - errorFailedThreshold > THRESHOLD_TOLERANCE) {\n            result = Result.FAILURE;\n        } else if (errorUnstableThreshold >= 0 && errorPercent - errorUnstableThreshold > THRESHOLD_TOLERANCE) {\n            result = Result.UNSTABLE;\n        }\n\n        // set result. It'll be set only when result is worse\n        run.setResult(result);\n\n        logger.println(\"Performance: File \" + performanceReport.getReportFileName() + \" reported \" + errorPercent\n                + \"% of errors [\" + result + \"]. Build status is: \" + run.getResult());\n    }\n\n    // check average response time values\n    private Result checkAverageResponseTime(PerformanceReport performanceReport, HashMap<String, String> responseTimeThresholdMap, PrintStream logger) {\n        long average = performanceReport.getAverage();\n        try {\n            if ((responseTimeThresholdMap != null && responseTimeThresholdMap.get(performanceReport.getReportFileName()) != null) &&\n                    (Long.parseLong(responseTimeThresholdMap.get(performanceReport.getReportFileName())) <= average)) {\n                logger.println(\"UNSTABLE: \" + performanceReport.getReportFileName() + \" has exceeded the threshold of [\"\n                        + Long.parseLong(responseTimeThresholdMap.get(performanceReport.getReportFileName())) + \"] with the time of [\"\n                        + Long.toString(average) + \"]\");\n                return Result.UNSTABLE;\n            }\n        } catch (NumberFormatException nfe) {\n            logger.println(\"ERROR: Threshold set to a non-number [\"\n                    + responseTimeThresholdMap.get(performanceReport.getReportFileName()) + \"]\");\n            return Result.FAILURE;\n        }\n        return null;\n    }\n\n    // write 'standard mode' report in xml containing each of the populated columns otherwise found in the jelly output.\n    // producing an on disk, machine parseable format allows for archiving and automation.\n    private void writeStandardResultsToXML(Run<?, ?> run, Collection<PerformanceReport> parsedReports) throws IOException {\n        File xmlDirectory = createArchiveDirectoryIfMissing(run);\n        File xmlfile = new File(xmlDirectory, \"standardResults.xml\");\n        try (OutputStreamWriter fw = new OutputStreamWriter(new FileOutputStream(xmlfile), StandardCharsets.UTF_8);\n                BufferedWriter bw = new BufferedWriter(fw)){\n            \n            String xml = new StringBuilder(\"<?xml version=\\\"1.0\\\"?>\\n\")\n                    .append(\"<results>\\n\")\n                    .append(appendStandardResultsStatsToXml(parsedReports))\n                    .append(\"</results>\\n\").toString();\n\n            bw.write(xml);\n        }\n    }\n\n    private String appendStandardResultsStatsToXml(Collection<PerformanceReport> reports) {\n        StringBuilder xmlSB = new StringBuilder();\n        for (PerformanceReport perfReport : reports) {\n            for (UriReport report : perfReport.getUriListOrdered()) {\n                xmlSB.append(\"<api>\\n\\t\");\n                xmlSB.append(\"<uri>\").append(report.getUri()).append(\"</uri>\\n\\t\");\n                xmlSB.append(\"<samples>\").append(report.samplesCount()).append(\"</samples>\\n\\t\");\n                xmlSB.append(\"<average>\").append(report.getAverage()).append(\"</average>\\n\\t\");\n                xmlSB.append(\"<min>\").append(report.getMin()).append(\"</min>\\n\\t\");\n                xmlSB.append(\"<median>\").append(report.getMedian()).append(\"</median>\\n\\t\");\n                xmlSB.append(\"<ninetieth>\").append(report.get90Line()).append(\"</ninetieth>\\n\\t\");\n                xmlSB.append(\"<ninetyFifth>\").append(report.get95Line()).append(\"</ninetyFifth>\\n\\t\");\n                xmlSB.append(\"<max>\").append(report.getMax()).append(\"</max>\\n\\t\");\n                xmlSB.append(\"<httpCode>\").append(report.getHttpCode()).append(\"</httpCode>\\n\\t\");\n                xmlSB.append(\"<errors>\").append(report.errorPercent()).append(\"</errors>\\n\");\n                xmlSB.append(\"</api>\\n\");\n            }\n        }\n        return xmlSB.toString();\n    }\n\n    // write report in xml, when checked Error Threshold comparison\n    private void writeErrorThresholdReportInXML(Run<?, ?> run, PerformanceReport performanceReport) throws IOException {\n        File xmlDirectory = createArchiveDirectoryIfMissing(run);\n\n        String glob = performanceReport.getReportFileName();\n        String[] arr = glob.split(\"/\");\n\n        File xmlfile = new File(xmlDirectory, \"/dashBoard_\" + arr[arr.length - 1].split(\"\\\\.\")[0] + \".xml\");\n        try (OutputStreamWriter fw = new OutputStreamWriter(new FileOutputStream(xmlfile), StandardCharsets.UTF_8);\n             BufferedWriter bw = new BufferedWriter(fw)) {\n            String xml = \"<?xml version=\\\"1.0\\\"?>\\n\";\n            xml += \"<results>\\n\";\n            xml += \"<absoluteDefinition>\\n\";\n            xml += \"\\t<unstable>\" + errorUnstableThreshold + \"</unstable>\\n\";\n            xml += \"\\t<failed>\" + errorFailedThreshold + \"</failed>\\n\";\n            xml += \"\\t<calculated>\" + performanceReport.errorPercent() + \"</calculated>\\n\";\n            xml += \"</absoluteDefinition>\\n\";\n\n            xml += appendStatsToXml(performanceReport.getUriListOrdered());\n\n            xml += \"</results>\";\n\n            bw.write(xml);\n        }\n    }\n\n    private String appendStatsToXml(List<UriReport> reports) {\n        final StringBuilder averageBuffer = new StringBuilder(\"<average>\\n\");\n        final StringBuilder medianBuffer = new StringBuilder(\"<median>\\n\");\n        final StringBuilder percentileBuffer = new StringBuilder(\"<percentile>\\n\");\n\n        for (UriReport uriReport : reports) {\n            averageBuffer.append(\"\\t<\").append(uriReport.getStaplerUri()).append(\">\\n\");\n            averageBuffer.append(\"\\t\\t<currentBuildAvg>\").append(uriReport.getAverage()).append(\"</currentBuildAvg>\\n\");\n            averageBuffer.append(\"\\t</\").append(uriReport.getStaplerUri()).append(\">\\n\");\n\n            medianBuffer.append(\"\\t<\").append(uriReport.getStaplerUri()).append(\">\\n\");\n            medianBuffer.append(\"\\t\\t<currentBuildMed>\").append(uriReport.getMedian()).append(\"</currentBuildMed>\\n\");\n            medianBuffer.append(\"\\t</\").append(uriReport.getStaplerUri()).append(\">\\n\");\n\n            percentileBuffer.append(\"\\t<\").append(uriReport.getStaplerUri()).append(\">\\n\");\n            percentileBuffer.append(\"\\t\\t<currentBuild90Line>\").append(uriReport.get90Line()).append(\"</currentBuild90Line>\\n\");\n            percentileBuffer.append(\"\\t</\").append(uriReport.getStaplerUri()).append(\">\\n\");\n\n            percentileBuffer.append(\"\\t<\").append(uriReport.getStaplerUri()).append(\">\\n\");\n            percentileBuffer.append(\"\\t\\t<currentBuild95Line>\").append(uriReport.get95Line()).append(\"</currentBuild95Line>\\n\");\n            percentileBuffer.append(\"\\t</\").append(uriReport.getStaplerUri()).append(\">\\n\");\n\n        }\n\n        averageBuffer.append(\"</average>\\n\");\n        medianBuffer.append(\"</median>\\n\");\n        percentileBuffer.append(\"</percentile>\\n\");\n\n        StringBuilder result = new StringBuilder();\n        result.append(averageBuffer);\n        result.append(medianBuffer);\n        result.append(percentileBuffer);\n        return result.toString();\n    }\n\n\n    private HashMap<String, String> getResponseTimeThresholdMap(PrintStream logger) {\n        HashMap<String, String> responseTimeThresholdMap = null;\n        if (!\"\".equals(this.errorUnstableResponseTimeThreshold) && this.errorUnstableResponseTimeThreshold != null) {\n\n            responseTimeThresholdMap = new HashMap<>();\n            String[] lines = this.errorUnstableResponseTimeThreshold.split(\"\\n\");\n\n            for (String line : lines) {\n                String[] components = line.split(\":\");\n                if (components.length == 2) {\n                    logger.println(\"Setting threshold: \" + components[0] + \":\" + components[1]);\n                    responseTimeThresholdMap.put(components[0], components[1]);\n                }\n            }\n        }\n        return responseTimeThresholdMap;\n    }\n\n\n    // For relative comparisons between builds...\n    public void compareWithRelativeThreshold(Run<?, ?> run, FilePath workspace, TaskListener listener, List<PerformanceReportParser> parsers)\n            throws IOException, InterruptedException {\n        PrintStream logger = listener.getLogger();\n        try {\n            printInfoAboutRelativeThreshold(logger);\n\n            List<UriReport> currentUriReports = getBuildUriReports(run, workspace, listener, parsers, true);\n            if (currentUriReports == null) {\n                return;\n            }\n\n            StringBuilder averageBuffer = null;\n            StringBuilder medianBuffer = null;\n            StringBuilder percentileBuffer = null;\n\n            // getting previous build/nth previous build..\n            Run<?, ?> buildForComparison = compareBuildPrevious ? run.getPreviousSuccessfulBuild() : getnthBuild(run);\n\n            if (buildForComparison != null) {\n                logger.print(\"\\nComparison build no. - \" + buildForComparison.number + \" and \" + run.number + \" using \");\n\n                int maxUriColumnWidth = 0;\n                for (UriReport report : currentUriReports) {\n                    maxUriColumnWidth = Math.max(report.getStaplerUri().length(), maxUriColumnWidth);\n                }\n\n                printInfoAboutCompareBasedOn(logger, \"%-\" + maxUriColumnWidth + \"s%20s%20s%20s%20s\");\n\n                compareUriReports(run,\n                        currentUriReports,\n                        // getting files related to the previous build selected\n                        getBuildUriReports(buildForComparison, workspace, listener, parsers, false),\n                        logger,\n                        // open xml tags\n                        (averageBuffer = new StringBuilder(\"<average>\\n\")),\n                        (medianBuffer = new StringBuilder(\"<median>\\n\")),\n                        (percentileBuffer = new StringBuilder(\"<percentile>\\n\")),\n                        \"%1$-\" + maxUriColumnWidth + \"s%2$20d%3$20d%4$20.0f%5$19.2f%%\"\n                );\n\n                // close xml tags\n                averageBuffer.append(\"</average>\\n\");\n                medianBuffer.append(\"</median>\\n\");\n                percentileBuffer.append(\"</percentile>\");\n            }\n\n            writeRelativeThresholdReportInXML(run, averageBuffer, medianBuffer, percentileBuffer);\n\n\n        } catch (Exception e) {\n            logger.println(\"ERROR: Exception while determining relative comparison between builds\");\n            e.printStackTrace(logger);\n        }\n\n    }\n\n\n    // Comparing both builds based on either average, median or 90\n    // percentile response time...\n    private void compareUriReports(Run<?, ?> run, List<UriReport> currentUriReports, List<UriReport> reportsForComparison, PrintStream logger,\n                                   StringBuilder averageBuffer, StringBuilder medianBuffer, StringBuilder percentileBuffer, String logFormat) {\n\n        // comparing the labels and calculating the differences...\n        for (UriReport reportForComparison : reportsForComparison) {\n            for (UriReport currentUriReport : currentUriReports) {\n                if (reportForComparison.getStaplerUri().equalsIgnoreCase(currentUriReport.getStaplerUri())) {\n\n                    appendRelativeInfoAboutAverage(currentUriReport, reportForComparison, averageBuffer);\n                    appendRelativeInfoAboutMedian(currentUriReport, reportForComparison, medianBuffer);\n                    appendRelativeInfoAbout90Line(currentUriReport, reportForComparison, percentileBuffer);\n\n                    calculateBuildStatus(run, logger, reportForComparison.getStaplerUri(),\n                            calculateRelativeDiffInPercent(currentUriReport, reportForComparison, logger, logFormat));\n                }\n            }\n        }\n    }\n\n    // setting the build status based on the differences\n    // calculated...\n    private void calculateBuildStatus(Run<?, ?> run, PrintStream logger, String staplerUri, double relativeDiffPercent) {\n        Result result = null;\n        if (relativeDiffPercent < 0) {\n            if (calculateRelativeFailedThresholdNegative(relativeDiffPercent)) {\n                result = Result.FAILURE;\n            } else if (calculateRelativeUnstableThresholdNegative(relativeDiffPercent)) {\n                result = Result.UNSTABLE;\n            }\n        } else if (relativeDiffPercent >= 0) {\n            if (calculateRelativeFailedThresholdPositive(relativeDiffPercent)) {\n                result = Result.FAILURE;\n            } else if (calculateRelativeUnstableThresholdPositive(relativeDiffPercent)) {\n                result = Result.UNSTABLE;\n            }\n        }\n\n        if (result != null) {\n            // set result. It'll be set only when result is worse\n            run.setResult(result);\n            logger.print(\n                    (result == Result.FAILURE) ?\n                            \"\\nThe label \\\"\" + staplerUri + \"\\\"\" + \" caused the build to fail\\n\" :\n                            \"\\nThe label \\\"\" + staplerUri + \"\\\"\" + \" made the build unstable\\n\"\n            );\n        }\n    }\n\n    private double calculateDiffInPercents(double value1, double value2) {\n        return Math.round(SafeMaths.safeDivide(value1 * 100, value2) * 100) / 100d;\n    }\n\n    private boolean calculateRelativeFailedThresholdNegative(double relativeDiffPercent) {\n        return (relativeFailedThresholdNegative >= 0\n                && Math.abs(relativeDiffPercent) - relativeFailedThresholdNegative > THRESHOLD_TOLERANCE);\n    }\n\n    private boolean calculateRelativeUnstableThresholdNegative(double relativeDiffPercent) {\n        return (relativeUnstableThresholdNegative >= 0\n                && Math.abs(relativeDiffPercent) - relativeUnstableThresholdNegative > THRESHOLD_TOLERANCE);\n    }\n\n    private boolean calculateRelativeFailedThresholdPositive(double relativeDiffPercent) {\n        return (relativeFailedThresholdPositive >= 0\n                && Math.abs(relativeDiffPercent) - relativeFailedThresholdPositive > THRESHOLD_TOLERANCE);\n    }\n\n    private boolean calculateRelativeUnstableThresholdPositive(double relativeDiffPercent) {\n        return (relativeUnstableThresholdPositive >= 0\n                && Math.abs(relativeDiffPercent) - relativeUnstableThresholdPositive > THRESHOLD_TOLERANCE);\n    }\n\n    private double calculateRelativeDiffInPercent(UriReport currentReport, UriReport reportForComparison, PrintStream logger, String logFormat) {\n        double relativeDiff;\n        double relativeDiffPercent = 0;\n\n        if (configType.equalsIgnoreCase(\"ART\")) {\n            relativeDiff = (double) currentReport.getAverage() - reportForComparison.getAverage();\n            relativeDiffPercent = calculateDiffInPercents(relativeDiff, reportForComparison.getAverage());\n\n            logger.println(String.format(logFormat, reportForComparison.getStaplerUri(),\n                    reportForComparison.getAverage(), currentReport.getAverage(),\n                    relativeDiff, relativeDiffPercent));\n\n        } else if (configType.equalsIgnoreCase(\"MRT\")) {\n            relativeDiff = (double) currentReport.getMedian() - reportForComparison.getMedian();\n            relativeDiffPercent = calculateDiffInPercents(relativeDiff, reportForComparison.getMedian());\n\n            logger.println(String.format(logFormat, reportForComparison.getStaplerUri(),\n                    reportForComparison.getMedian(), currentReport.getMedian(),\n                    relativeDiff, relativeDiffPercent));\n\n        } else if (configType.equalsIgnoreCase(\"PRT\")) {\n            relativeDiff = (double) currentReport.get90Line() - reportForComparison.get90Line();\n            relativeDiffPercent = calculateDiffInPercents(relativeDiff, reportForComparison.get90Line());\n\n            logger.println(String.format(logFormat, reportForComparison.getStaplerUri(),\n                    reportForComparison.get90Line(), currentReport.get90Line(),\n                    relativeDiff, relativeDiffPercent));\n        }\n        return relativeDiffPercent;\n    }\n\n    private void writeRelativeThresholdReportInXML(Run<?, ?> run, StringBuilder averageBuffer,\n                                                   StringBuilder medianBuffer, StringBuilder percentileBuffer) throws IOException {\n        File xmlDirectory = createArchiveDirectoryIfMissing(run);\n\n        File xmlfile = new File(xmlDirectory, \"dashBoard_results.xml\");\n        try (OutputStreamWriter fw = new OutputStreamWriter(new FileOutputStream(xmlfile), StandardCharsets.UTF_8);\n             BufferedWriter bw = new BufferedWriter(fw)) {\n\n            String buildNo = \"\\t<buildNum>\" + (compareBuildPrevious ? \"previous\" : nthBuildNumber) + \"</buildNum>\\n\";\n\n            String unstable = \"\\t<unstable>\\n\";\n            unstable += \"\\t\\t<negative>\" + relativeUnstableThresholdNegative + \"</negative>\\n\";\n            unstable += \"\\t\\t<positive>\" + relativeUnstableThresholdPositive + \"</positive>\\n\";\n            unstable += \"\\t</unstable>\\n\";\n\n            String failed = \"\\t<failed>\\n\";\n            failed += \"\\t\\t<negative>\" + relativeFailedThresholdNegative + \"</negative>\\n\";\n            failed += \"\\t\\t<positive>\" + relativeFailedThresholdPositive + \"</positive>\\n\";\n            failed += \"\\t</failed>\\n\";\n\n            String relative = \"<relativeDefinition>\\n\";\n            relative += buildNo + unstable + failed;\n            relative += \"</relativeDefinition>\";\n\n            bw.write(\"<?xml version=\\\"1.0\\\"?>\\n\");\n            bw.write(\"<results>\\n\");\n            bw.write(relative + \"\\n\");\n\n            if (averageBuffer != null) {\n                bw.write(averageBuffer.toString());\n            }\n\n            if (medianBuffer != null) {\n                bw.write(medianBuffer.toString());\n            }\n\n            if (percentileBuffer != null) {\n                bw.write(percentileBuffer.toString());\n            }\n\n            bw.write(\"</results>\");\n        }\n    }\n\n    private File createArchiveDirectoryIfMissing(Run<?, ?> run) {\n        File xmlDirectory = new File(run.getRootDir(), ARCHIVE_DIRECTORY);\n        if (!xmlDirectory.exists() && !xmlDirectory.mkdirs()) {\n            throw new IllegalStateException(\"Could not create archive directory \" + xmlDirectory.getAbsolutePath());\n        }\n        return xmlDirectory;\n    }\n\n\n    private void appendRelativeInfoAboutAverage(UriReport currentReport, UriReport reportForComparison, StringBuilder averageBuffer) {\n        double relativeDiff = (double) currentReport.getAverage() - reportForComparison.getAverage();\n        double relativeDiffPercent = calculateDiffInPercents(relativeDiff, reportForComparison.getAverage());\n\n        averageBuffer.append(\"\\t<\").append(currentReport.getStaplerUri()).append(\">\\n\");\n        averageBuffer.append(\"\\t\\t<previousBuildAvg>\").append(reportForComparison.getAverage()).append(\"</previousBuildAvg>\\n\");\n        averageBuffer.append(\"\\t\\t<currentBuildAvg>\").append(currentReport.getAverage()).append(\"</currentBuildAvg>\\n\");\n        averageBuffer.append(\"\\t\\t<relativeDiff>\").append(relativeDiff).append(\"</relativeDiff>\\n\");\n        averageBuffer.append(\"\\t\\t<relativeDiffPercent>\").append(relativeDiffPercent).append(\"</relativeDiffPercent>\\n\");\n        averageBuffer.append(\"\\t</\").append(currentReport.getStaplerUri()).append(\">\\n\");\n    }\n\n    private void appendRelativeInfoAboutMedian(UriReport currentReport, UriReport reportForComparison, StringBuilder medianBuffer) {\n        double relativeDiff = (double) currentReport.getMedian() - reportForComparison.getMedian();\n        double relativeDiffPercent = calculateDiffInPercents(relativeDiff, reportForComparison.getMedian());\n\n        medianBuffer.append(\"\\t<\").append(currentReport.getStaplerUri()).append(\">\\n\");\n        medianBuffer.append(\"\\t\\t<previousBuildMed>\").append(reportForComparison.getMedian()).append(\"</previousBuildMed>\\n\");\n        medianBuffer.append(\"\\t\\t<currentBuildMed>\").append(currentReport.getMedian()).append(\"</currentBuildMed>\\n\");\n        medianBuffer.append(\"\\t\\t<relativeDiff>\").append(relativeDiff).append(\"</relativeDiff>\\n\");\n        medianBuffer.append(\"\\t\\t<relativeDiffPercent>\").append(relativeDiffPercent).append(\"</relativeDiffPercent>\\n\");\n        medianBuffer.append(\"\\t</\").append(currentReport.getStaplerUri()).append(\">\\n\");\n    }\n\n    private void appendRelativeInfoAbout90Line(UriReport currentReport, UriReport reportForComparison, StringBuilder percentileBuffer) {\n        double relativeDiff = (double) currentReport.get90Line() - reportForComparison.get90Line();\n        double relativeDiffPercent = calculateDiffInPercents(relativeDiff, reportForComparison.get90Line());\n\n        percentileBuffer.append(\"\\t<\").append(currentReport.getStaplerUri()).append(\">\\n\");\n        percentileBuffer.append(\"\\t\\t<previousBuild90Line>\").append(reportForComparison.get90Line()).append(\"</previousBuild90Line>\\n\");\n        percentileBuffer.append(\"\\t\\t<currentBuild90Line>\").append(currentReport.get90Line()).append(\"</currentBuild90Line>\\n\");\n        percentileBuffer.append(\"\\t\\t<relativeDiff>\").append(relativeDiff).append(\"</relativeDiff>\\n\");\n        percentileBuffer.append(\"\\t\\t<relativeDiffPercent>\").append(relativeDiffPercent).append(\"</relativeDiffPercent>\\n\");\n        percentileBuffer.append(\"\\t</\").append(currentReport.getStaplerUri()).append(\">\\n\");\n    }\n\n    // Print information about Unstable & Failed Threshold\n    private void printInfoAboutErrorThreshold(PrintStream logger) {\n        logger.println(\n                (errorUnstableThreshold >= 0 && errorUnstableThreshold <= 100) ?\n                        \"Performance: Percentage of errors greater or equal than \" + errorUnstableThreshold\n                                + \"% sets the build as \" + Result.UNSTABLE.toString().toLowerCase() :\n                        \"Performance: No threshold configured for making the test \" + Result.UNSTABLE.toString().toLowerCase()\n        );\n\n        logger.println(\n                (errorFailedThreshold >= 0 && errorFailedThreshold <= 100) ?\n                        \"Performance: Percentage of errors greater or equal than \" + errorFailedThreshold\n                                + \"% sets the build as \" + Result.FAILURE.toString().toLowerCase() :\n                        \"Performance: No threshold configured for making the test \" + Result.FAILURE.toString().toLowerCase()\n        );\n    }\n\n    // Print information about Relative Threshold\n    private void printInfoAboutRelativeThreshold(PrintStream logger) {\n        if (relativeFailedThresholdNegative >= 0) {\n            logger.printf(\"Performance: Percentage of relative difference less than -%s %% sets the build as [%s]%n\",\n                    relativeFailedThresholdNegative, Result.FAILURE.toString());\n        }\n\n        if (relativeFailedThresholdPositive >= 0) {\n            logger.printf(\"Performance: Percentage of relative difference more than %s %% sets the build as [%s]%n\",\n                    relativeFailedThresholdPositive, Result.FAILURE.toString());\n        }\n\n        if (relativeUnstableThresholdNegative >= 0) {\n            logger.printf(\"Performance: Percentage of relative difference less than -%s %% sets the build as [%s]%n\",\n                    relativeUnstableThresholdNegative, Result.UNSTABLE.toString());\n        }\n\n        if (relativeUnstableThresholdPositive >= 0) {\n            logger.printf(\"Performance: Percentage of relative difference more than %s %% sets the build as [%s]%n\",\n                    relativeUnstableThresholdPositive, Result.UNSTABLE.toString());\n        }\n    }\n\n\n    private void printInfoAboutCompareBasedOn(PrintStream logger, String logFormat) {\n        if (configType.equalsIgnoreCase(\"ART\")) {\n            logger.println(\"Average response time\\n\\n\");\n            logger.println(String.format(logFormat,\n                    \"URI\", \"PrevBuildURIAvg\", \"CurrentBuildURIAvg\", \"RelativeDiff\", \"RelativeDiff(%)\"));\n        } else if (configType.equalsIgnoreCase(\"MRT\")) {\n            logger.println(\"Median response time\\n\\n\");\n            logger.println(String.format(logFormat,\n                    \"URI\", \"PrevBuildURIMed\", \"CurrentBuildURIMed\", \"RelativeDiff\", \"RelativeDiff(%)\"));\n        } else if (configType.equalsIgnoreCase(\"PRT\")) {\n            logger.println(\"90 Percentile response time\\n\\n\");\n            logger.println(String.format(logFormat,\n                    \"URI\", \"PrevBuildURI90%\", \"CurrentBuildURI90%\", \"RelativeDiff\", \"RelativeDiff(%)\"));\n        }\n    }\n\n    /*\n     * For mode \"expert evaluation\"\n     */\n    public void evaluateInExpertMode(Run<?, ?> run, FilePath workspace, TaskListener listener) throws IOException, InterruptedException {\n        PrintStream logger = listener.getLogger();\n        ConstraintFactory factory = new ConstraintFactory();\n        ConstraintSettings settings = new ConstraintSettings(listener, ignoreFailedBuilds, ignoreUnstableBuilds,\n                persistConstraintLog, getBaselineBuild());\n        ConstraintChecker checker = new ConstraintChecker(settings, run.getParent().getBuilds());\n        ArrayList<ConstraintEvaluation> ceList = new ArrayList<>();\n        try {\n            ceList = checker.checkAllConstraints(factory.createConstraintClones(run, constraints));\n        } catch (Exception e) {\n            e.printStackTrace(logger);\n        }\n      /*\n       * Create Report of evaluated constraints\n       */\n        ConstraintReport cr = new ConstraintReport(ceList, run.getParent().getBuilds().iterator().next(), persistConstraintLog);\n        logger.print(cr.getLoggerMsg());\n        /*\n         * Determine build result\n         */\n        run.setResult(cr.getBuildResult());\n\n        /*\n         * Write JUnit report back to workspace, for other post-build actions to pick up\n         */\n        if (junitOutput != null && !junitOutput.isEmpty()) {\n            listener.getLogger().println(\"Performance: Generating JUnit output: \" + junitOutput);\n            FilePath output = new FilePath(workspace, junitOutput);\n            FilePath parent = output.getParent();\n            if (parent != null) {\n                parent.mkdirs();\n            } else {\n                // Handle the situation when parent is null\n                listener.getLogger().println(\"Failed to create parent dirs because the path is null.\");\n            }\n            try {\n                String junitReport = cr.getJunitReport();\n                if (junitReport != null) {\n                    output.write(junitReport, null);\n                } else {\n                    listener.getLogger().println(\"Failed to write JUnit file because junitreport is null.\");\n                }\n            }\n            catch (IOException ex) {\n                listener.getLogger().println(\"Failed to write JUnit file: \"+ex.getMessage());\n            }\n        }\n    }\n\n    private List<File> copyReportsToMaster(Run<?, ?> build, PrintStream logger, List<FilePath> files,\n                                           String parserDisplayName) throws IOException, InterruptedException {\n        List<File> localReports = new ArrayList<>();\n        for (FilePath src : files) {\n            final File localReport = getPerformanceReport(build, parserDisplayName, src.getName());\n            if (src.isDirectory()) {\n                logger.println(\"Performance: File '\" + src.getName() + \"' is a directory, not a Performance Report\");\n                continue;\n            }\n            src.copyTo(new FilePath(localReport));\n            localReports.add(localReport);\n        }\n        return localReports;\n    }\n\n\n    public int getErrorFailedThreshold() {\n        return errorFailedThreshold;\n    }\n\n    @DataBoundSetter\n    public void setErrorFailedThreshold(int errorFailedThreshold) {\n        this.errorFailedThreshold = (errorFailedThreshold == -1) ? (-1) : Math.max(0, Math.min(errorFailedThreshold, 100));\n    }\n\n    public int getErrorUnstableThreshold() {\n        return errorUnstableThreshold;\n    }\n\n    @DataBoundSetter\n    public void setErrorUnstableThreshold(int errorUnstableThreshold) {\n        this.errorUnstableThreshold = (errorUnstableThreshold == -1) ? (-1) : Math.max(0, Math.min(errorUnstableThreshold, 100));\n    }\n\n    public String getErrorUnstableResponseTimeThreshold() {\n        return this.errorUnstableResponseTimeThreshold;\n    }\n\n    @DataBoundSetter\n    public void setErrorUnstableResponseTimeThreshold(String errorUnstableResponseTimeThreshold) {\n        this.errorUnstableResponseTimeThreshold = errorUnstableResponseTimeThreshold;\n    }\n\n    public boolean isModePerformancePerTestCase() {\n        return modePerformancePerTestCase;\n    }\n\n    @DataBoundSetter\n    public void setModePerformancePerTestCase(boolean modePerformancePerTestCase) {\n        this.modePerformancePerTestCase = modePerformancePerTestCase;\n    }\n\n    public String getFilename() {\n        return filename;\n    }\n\n    public void setFilename(String filename) {\n        this.filename = filename;\n    }\n\n    public boolean isFailBuildIfNoResultFile() {\n        return failBuildIfNoResultFile;\n    }\n\n    @DataBoundSetter\n    public void setFailBuildIfNoResultFile(boolean failBuildIfNoResultFile) {\n        this.failBuildIfNoResultFile = failBuildIfNoResultFile;\n    }\n\n    public boolean isART() {\n        return configType.compareToIgnoreCase(PerformancePublisher.ART) == 0;\n    }\n\n    public boolean isMRT() {\n        return configType.compareToIgnoreCase(PerformancePublisher.MRT) == 0;\n    }\n\n    public boolean isPRT() {\n        return configType.compareToIgnoreCase(PerformancePublisher.PRT) == 0;\n    }\n\n    public static File[] getPerformanceReportDirectory(Run<?, ?> build, String parserDisplayName,\n                                                       PrintStream logger) {\n        File folder = new File(build.getRootDir(), PerformanceReportMap.getPerformanceReportFileRelativePath(parserDisplayName, \"\"));\n        return folder.listFiles();\n    }\n\n    /**\n     * Gets the Build object entered in the text box \"Compare with nth Build\"\n     *\n     * @param build, listener\n     * @return build object\n     */\n\n    // @psingh5 -\n    public Run<?, ?> getnthBuild(Run<?, ?> build) {\n        Run<?, ?> nthBuild = build;\n\n        int nextBuildNumber = build.number - nthBuildNumber;\n\n        for (int i = 1; i <= nextBuildNumber; i++) {\n            nthBuild = nthBuild.getPreviousBuild();\n            if (nthBuild == null)\n                return null;\n        }\n        return (nthBuildNumber == 0) ? null : nthBuild;\n    }\n\n    private List<File> getExistingReports(Run<?, ?> build, PrintStream logger, String parserDisplayName) {\n        List<File> localReports = new ArrayList<>();\n        final File[] localReport = getPerformanceReportDirectory(build, parserDisplayName, logger);\n\n        for (int i = 0; i < localReport.length; i++) {\n\n            String name = localReport[i].getName();\n            String[] arr = name.split(\"\\\\.\");\n\n            // skip the serialized jmeter report file\n            if (arr[arr.length - 1].equalsIgnoreCase(\"serialized\"))\n                continue;\n\n            localReports.add(localReport[i]);\n        }\n        return localReports;\n    }\n\n    public double getRelativeFailedThresholdPositive() {\n        return relativeFailedThresholdPositive;\n    }\n\n    public double getRelativeFailedThresholdNegative() {\n        return relativeFailedThresholdNegative;\n    }\n\n    @DataBoundSetter\n    public void setRelativeFailedThresholdPositive(double relativeFailedThresholdPositive) {\n        this.relativeFailedThresholdPositive = relativeFailedThresholdPositive;\n    }\n\n    @DataBoundSetter\n    public void setRelativeFailedThresholdNegative(double relativeFailedThresholdNegative) {\n        this.relativeFailedThresholdNegative = relativeFailedThresholdNegative;\n    }\n\n    public double getRelativeUnstableThresholdPositive() {\n        return relativeUnstableThresholdPositive;\n    }\n\n    public double getRelativeUnstableThresholdNegative() {\n        return relativeUnstableThresholdNegative;\n    }\n\n    @DataBoundSetter\n    public void setRelativeUnstableThresholdPositive(double relativeUnstableThresholdPositive) {\n        this.relativeUnstableThresholdPositive = relativeUnstableThresholdPositive;\n    }\n\n    @DataBoundSetter\n    public void setRelativeUnstableThresholdNegative(double relativeUnstableThresholdNegative) {\n        this.relativeUnstableThresholdNegative = relativeUnstableThresholdNegative;\n    }\n\n    public int getNthBuildNumber() {\n        return nthBuildNumber;\n    }\n\n    @DataBoundSetter\n    public void setNthBuildNumber(int nthBuildNumber) {\n        this.nthBuildNumber = Math.max(0, Math.min(nthBuildNumber, Integer.MAX_VALUE));\n    }\n\n    public String getConfigType() {\n        return configType;\n    }\n\n    @DataBoundSetter\n    public void setConfigType(String configType) {\n        this.configType = configType;\n    }\n\n    public String getGraphType() {\n        return graphType;\n    }\n\n    @DataBoundSetter\n    public void setGraphType(String graphType) {\n        this.graphType = graphType;\n    }\n\n    public boolean getModeOfThreshold() {\n        return modeOfThreshold;\n    }\n\n    @DataBoundSetter\n    public void setModeOfThreshold(boolean modeOfThreshold) {\n        this.modeOfThreshold = modeOfThreshold;\n    }\n\n    public boolean getCompareBuildPrevious() {\n        return compareBuildPrevious;\n    }\n\n    @DataBoundSetter\n    public void setCompareBuildPrevious(boolean compareBuildPrevious) {\n        this.compareBuildPrevious = compareBuildPrevious;\n    }\n\n    public boolean isModeThroughput() {\n        return modeThroughput;\n    }\n\n    @DataBoundSetter\n    public void setModeThroughput(boolean modeThroughput) {\n        this.modeThroughput = modeThroughput;\n    }\n\n    public List<? extends AbstractConstraint> getConstraints() {\n        return constraints;\n    }\n\n    @DataBoundSetter\n    public void setConstraints(List<? extends AbstractConstraint> constraints) {\n        this.constraints = constraints;\n    }\n\n    @DataBoundSetter\n    public void setIgnoreFailedBuilds(boolean ignoreFailedBuilds) {\n        this.ignoreFailedBuilds = ignoreFailedBuilds;\n    }\n\n    public boolean isIgnoreFailedBuilds() {\n        return ignoreFailedBuilds;\n    }\n\n    @DataBoundSetter\n    public void setIgnoreUnstableBuilds(boolean ignoreUnstableBuilds) {\n        this.ignoreUnstableBuilds = ignoreUnstableBuilds;\n    }\n\n    public boolean isIgnoreUnstableBuilds() {\n        return ignoreUnstableBuilds;\n    }\n\n    public boolean isPersistConstraintLog() {\n        return persistConstraintLog;\n    }\n\n    @DataBoundSetter\n    public void setPersistConstraintLog(boolean persistConstraintLog) {\n        this.persistConstraintLog = persistConstraintLog;\n    }\n\n    public boolean isModeEvaluation() {\n        return modeEvaluation;\n    }\n\n    @DataBoundSetter\n    public void setModeEvaluation(boolean modeEvaluation) {\n        this.modeEvaluation = modeEvaluation;\n    }\n\n    @DataBoundSetter\n    public void setShowTrendGraphs(boolean showTrendGraphs) {\n        this.showTrendGraphs = showTrendGraphs;\n    }\n\n    public boolean isShowTrendGraphs() {\n        return showTrendGraphs;\n    }\n\n    public boolean getShowTrendGraphs() {\n        return showTrendGraphs;\n    }\n\n    public String getSourceDataFiles() {\n        return sourceDataFiles;\n    }\n\n    public void setSourceDataFiles(String sourceDataFiles) {\n        this.sourceDataFiles = sourceDataFiles;\n    }\n\n    public List<PerformanceReportParser> getParsers() {\n        return parsers;\n    }\n\n    @DataBoundSetter\n    public void setParsers(List<PerformanceReportParser> parsers) {\n        this.parsers = parsers;\n        migrateParsers();\n    }\n\n    public boolean isExcludeResponseTime() {\n        return excludeResponseTime;\n    }\n\n    @DataBoundSetter\n    public void setExcludeResponseTime(boolean excludeResponseTime) {\n        this.excludeResponseTime = excludeResponseTime;\n    }\n\n    public String getJunitOutput() {\n        return junitOutput;\n    }\n\n    @DataBoundSetter\n    public void setJunitOutput(String junitOutput) {\n        this.junitOutput = junitOutput;\n    }\n\n    public String getPercentiles() {\n        return percentiles;\n    }\n\n    @DataBoundSetter\n    public void setPercentiles(String percentiles) {\n        this.percentiles = percentiles;\n    }\n\n\n    public int getBaselineBuild() {\n        return baselineBuild;\n    }\n\n    @DataBoundSetter\n    public void setBaselineBuild(int baselineBuild) {\n        this.baselineBuild = baselineBuild;\n    }\n\n    /**\n     * Mapping classes after refactoring for backward compatibility.\n     */\n    @Initializer(before = InitMilestone.PLUGINS_STARTED)\n    public static void addAliases() {\n        // Items.XSTREAM2 is used for serializing project configuration,\n        // and Run.XSTREAM2 is used for serializing build and its associated Actions.\n\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.PerformanceBuildAction\", PerformanceBuildAction.class);\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.PerformanceProjectAction\", PerformanceProjectAction.class);\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.ExternalBuildReport\", ExternalBuildReportAction.class);\n\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.constraints.PreviousResultsBlock\", PreviousResultsBlock.class);\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.constraints.TestCaseBlock\", TestCaseBlock.class);\n\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.CookieHandler\", CookieHandler.class);\n\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.constraints.ConstraintSettings\", ConstraintSettings.class);\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.HttpSample\", HttpSample.class);\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.PerformanceReportPosition\", PerformanceReportPosition.class);\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.TaurusStatusReport\", TaurusFinalStats.class);\n\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.constraints.ConstraintDescriptor\", ConstraintDescriptor.class);\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.PerformanceReportParserDescriptor\", PerformanceReportParserDescriptor.class);\n\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.GraphConfigurationDetail\", GraphConfigurationDetail.class);\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.TestSuiteReportDetail\", TestSuiteReportDetail.class);\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.TrendReportDetail\", TrendReportDetail.class);\n\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.AbstractParser\", AbstractParser.class);\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.IagoParser\", IagoParser.class);\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.JMeterCsvParser\", JMeterCsvParser.class);\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.JMeterParser\", JMeterParser.class);\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.JmeterSummarizerParser\", JmeterSummarizerParser.class);\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.JUnitParser\", JUnitParser.class);\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.PerformanceReportParser\", PerformanceReportParser.class);\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.TaurusParser\", TaurusParser.class);\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.WrkSummarizerParser\", WrkSummarizerParser.class);\n\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.reports.throughput.ThroughputReport\", ThroughputReport.class);\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.reports.ThroughputReport\", ThroughputReport.class);\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.AbstractReport\", AbstractReport.class);\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.constraints.ConstraintReport\", ConstraintReport.class);\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.PerformanceReport\", PerformanceReport.class);\n        Items.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.UriReport\", UriReport.class);\n\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.PerformanceBuildAction\", PerformanceBuildAction.class);\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.PerformanceProjectAction\", PerformanceProjectAction.class);\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.ExternalBuildReport\", ExternalBuildReportAction.class);\n\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.constraints.PreviousResultsBlock\", PreviousResultsBlock.class);\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.constraints.TestCaseBlock\", TestCaseBlock.class);\n\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.CookieHandler\", CookieHandler.class);\n\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.constraints.ConstraintSettings\", ConstraintSettings.class);\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.HttpSample\", HttpSample.class);\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.PerformanceReportPosition\", PerformanceReportPosition.class);\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.TaurusStatusReport\", TaurusFinalStats.class);\n\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.constraints.ConstraintDescriptor\", ConstraintDescriptor.class);\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.PerformanceReportParserDescriptor\", PerformanceReportParserDescriptor.class);\n\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.GraphConfigurationDetail\", GraphConfigurationDetail.class);\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.TestSuiteReportDetail\", TestSuiteReportDetail.class);\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.TrendReportDetail\", TrendReportDetail.class);\n\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.AbstractParser\", AbstractParser.class);\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.IagoParser\", IagoParser.class);\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.JMeterCsvParser\", JMeterCsvParser.class);\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.JMeterParser\", JMeterParser.class);\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.JmeterSummarizerParser\", JmeterSummarizerParser.class);\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.JUnitParser\", JUnitParser.class);\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.PerformanceReportParser\", PerformanceReportParser.class);\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.TaurusParser\", TaurusParser.class);\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.WrkSummarizerParser\", WrkSummarizerParser.class);\n\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.reports.throughput.ThroughputReport\", ThroughputReport.class);\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.reports.ThroughputReport\", ThroughputReport.class);\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.AbstractReport\", AbstractReport.class);\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.constraints.ConstraintReport\", ConstraintReport.class);\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.PerformanceReport\", PerformanceReport.class);\n        Run.XSTREAM2.addCompatibilityAlias(\"hudson.plugins.performance.UriReport\", UriReport.class);\n    }\n\n    @Symbol({\"perfReport\", \"performanceReport\"})\n    @Extension\n    public static class DescriptorImpl extends BuildStepDescriptor<Publisher> {\n        @Override\n        public String getDisplayName() {\n            return Messages.Publisher_DisplayName();\n        }\n\n        @Override\n        public String getHelpFile() {\n            return \"/plugin/performance/help.html\";\n        }\n\n        public List<PerformanceReportParserDescriptor> getParserDescriptors() {\n            return PerformanceReportParserDescriptor.all();\n        }\n\n        public List<ConstraintDescriptor> getConstraintDescriptors() {\n            return ConstraintDescriptor.all();\n        }\n\n        @Override\n        public boolean isApplicable(Class<? extends AbstractProject> jobType) {\n            return true;\n        }\n\n        /**\n         * Populate the comparison type dynamically based on the user selection from\n         * the previous time\n         *\n         * @return the name of the option selected in the previous run\n         */\n        public ListBoxModel doFillConfigTypeItems() {\n            return getResponseTimeOptions();\n        }\n\n        public ListBoxModel doFillGraphTypeItems() {\n            return getResponseTimeOptions();\n        }\n\n        private ListBoxModel getResponseTimeOptions() {\n            ListBoxModel items = new ListBoxModel();\n            items.add(\"Average Response Time\", \"ART\");\n            items.add(\"Median Response Time\", \"MRT\");\n            items.add(\"Percentile Response Time\", \"PRT\");\n            return items;\n        }\n    }\n\n    /**\n     * @return the filterRegex\n     */\n    public String getFilterRegex() {\n        return filterRegex;\n    }\n\n    /**\n     * @param filterRegex the filterRegex to set\n     */\n    @DataBoundSetter\n    public void setFilterRegex(String filterRegex) {\n        this.filterRegex = filterRegex;\n    }\n}\n\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/PerformanceReportMap.java",
    "content": "package hudson.plugins.performance;\n\nimport hudson.model.AbstractProject;\nimport hudson.model.Describable;\nimport hudson.model.Job;\nimport hudson.model.ModelObject;\nimport hudson.model.Run;\nimport hudson.model.TaskListener;\nimport hudson.plugins.performance.actions.PerformanceBuildAction;\nimport hudson.plugins.performance.actions.PerformanceProjectAction;\nimport hudson.plugins.performance.data.ReportValueSelector;\nimport hudson.plugins.performance.details.GraphConfigurationDetail;\nimport hudson.plugins.performance.parsers.JMeterParser;\nimport hudson.plugins.performance.parsers.PerformanceReportParser;\nimport hudson.plugins.performance.reports.AbstractReport;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.data.PerformanceReportPosition;\nimport hudson.plugins.performance.reports.ThroughputReport;\nimport hudson.plugins.performance.reports.UriReport;\nimport hudson.util.ChartUtil;\nimport hudson.util.ChartUtil.NumberOnlyBuildLabel;\nimport hudson.util.DataSetBuilder;\nimport hudson.util.Graph;\n\nimport org.jfree.chart.JFreeChart;\nimport org.jfree.data.category.CategoryDataset;\nimport org.kohsuke.stapler.StaplerRequest;\nimport org.kohsuke.stapler.StaplerResponse;\n\nimport java.io.File;\nimport java.io.FileFilter;\nimport java.io.FilenameFilter;\nimport java.io.IOException;\nimport java.io.UnsupportedEncodingException;\nimport java.net.URLDecoder;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.StringTokenizer;\n\n/**\n * Root object of a performance report.\n */\npublic class PerformanceReportMap implements ModelObject {\n\n    /**\n     * The {@link PerformanceBuildAction} that this report belongs to.\n     */\n    private transient PerformanceBuildAction buildAction;\n    /**\n     * {@link PerformanceReport}s are keyed by\n     * {@link PerformanceReport#reportFileName}\n     * <p>\n     * Test names are arbitrary human-readable and URL-safe string that identifies\n     * an individual report.\n     */\n    private Map<String, PerformanceReport> performanceReportMap = new LinkedHashMap<>();\n    private static final String PERFORMANCE_REPORTS_DIRECTORY = \"performance-reports\";\n    private static final String PLUGIN_NAME = \"performance\";\n    private static final String TRENDREPORT_LINK = \"trendReport\";\n\n    public PerformanceReportMap(final PerformanceBuildAction buildAction,\n                                TaskListener listener) throws IOException {\n        this(buildAction, listener, true);\n    }\n\n    /**\n     * Parses the reports and build a {@link PerformanceReportMap}.\n     *\n     * @throws IOException If a report fails to parse.\n     */\n    public PerformanceReportMap(final PerformanceBuildAction buildAction,\n                         TaskListener listener, boolean isTopLevel) throws IOException {\n        this.buildAction = buildAction;\n        parseReports(getBuild(), listener, new PerformanceReportCollector() {\n\n            public void addAll(Collection<PerformanceReport> reports) {\n                for (PerformanceReport r : reports) {\n                    r.setBuildAction(buildAction);\n                    performanceReportMap.put(r.getReportFileName(), r);\n                }\n            }\n        }, null);\n\n        if (isTopLevel) {\n            addPreviousBuildReports();\n        }\n    }\n\n\n\n    private void addAll(Collection<PerformanceReport> reports) {\n        for (PerformanceReport r : reports) {\n            r.setBuildAction(buildAction);\n            performanceReportMap.put(r.getReportFileName(), r);\n        }\n    }\n\n    public Run<?, ?> getBuild() {\n        return buildAction.getBuild();\n    }\n\n    PerformanceBuildAction getBuildAction() {\n        return buildAction;\n    }\n\n    public String getDisplayName() {\n        return Messages.Report_DisplayName();\n    }\n\n    public List<PerformanceReport> getPerformanceListOrdered() {\n        List<PerformanceReport> listPerformance = new ArrayList<PerformanceReport>(\n                getPerformanceReportMap().values());\n        Collections.sort(listPerformance);\n        return listPerformance;\n    }\n\n    protected PerformancePublisher getPublisher() {\n        if (buildAction != null) {\n            Run<?, ?> build = buildAction.getBuild();\n            if (build != null) {\n                Job<?, ?> job = build.getParent();\n                if (job instanceof AbstractProject) {\n                    AbstractProject<?, ?> project = (AbstractProject<?, ?>) job;\n                    Describable<?> describable = project.getPublishersList().get(PerformancePublisher.class);\n                    return (describable != null) ? (PerformancePublisher) describable : null;\n                }\n            }\n        }\n        return null;\n    }\n\n    public boolean ifModeThroughputUsed() {\n        PerformancePublisher publisher = getPublisher();\n        return publisher == null || publisher.isModeThroughput();\n    }\n\n    public boolean ifShowTrendGraphsUsed() {\n        PerformancePublisher publisher = getPublisher();\n        return publisher == null || publisher.isShowTrendGraphs();\n    }\n\n    public boolean ifModePerformancePerTestCaseUsed() {\n        PerformancePublisher publisher = getPublisher();\n        return publisher == null || publisher.isModePerformancePerTestCase();\n    }\n\n    public Map<String, PerformanceReport> getPerformanceReportMap() {\n        return performanceReportMap;\n    }\n\n    /**\n     * <p>\n     * Give the Performance report with the parameter for name in Bean\n     * </p>\n     *\n     * @param performanceReportName\n     * @return\n     */\n    public PerformanceReport getPerformanceReport(String performanceReportName) {\n        return performanceReportMap.get(performanceReportName);\n    }\n\n    /**\n     * Get a URI report within a Performance report file\n     *\n     * @param uriReport \"Performance report file name\";\"URI name\"\n     * @return\n     */\n    public UriReport getUriReport(String uriReport) {\n        if (uriReport != null) {\n            String uriReportDecoded;\n            try {\n                uriReportDecoded = URLDecoder\n                        .decode(uriReport.replace(UriReport.END_PERFORMANCE_PARAMETER, \"\"),\n                                \"UTF-8\");\n            } catch (UnsupportedEncodingException e) {\n                e.printStackTrace();\n                return null;\n            }\n            StringTokenizer st = new StringTokenizer(uriReportDecoded,\n                    GraphConfigurationDetail.SEPARATOR);\n            return getPerformanceReportMap().get(st.nextToken()).getUriReportMap()\n                    .get(st.nextToken());\n        } else {\n            return null;\n        }\n    }\n\n    public String getUrlName() {\n        return PLUGIN_NAME;\n    }\n\n    public void setBuildAction(PerformanceBuildAction buildAction) {\n        this.buildAction = buildAction;\n    }\n\n    public void setPerformanceReportMap(\n            Map<String, PerformanceReport> performanceReportMap) {\n        this.performanceReportMap = performanceReportMap;\n    }\n\n    public static String getPerformanceReportFileRelativePath(\n            String parserDisplayName, String reportFileName) {\n        return getRelativePath(parserDisplayName, reportFileName);\n    }\n\n    public static String getPerformanceReportDirRelativePath() {\n        return getRelativePath();\n    }\n\n    private static String getRelativePath(String... suffixes) {\n        StringBuilder sb = new StringBuilder(100);\n        sb.append(PERFORMANCE_REPORTS_DIRECTORY);\n        for (String suffix : suffixes) {\n            sb.append(File.separator).append(suffix);\n        }\n        return sb.toString();\n    }\n\n    /**\n     * <p>\n     * Verify if the PerformanceReport exist the performanceReportName must to be\n     * like it is in the build\n     * </p>\n     *\n     * @param performanceReportName\n     * @return boolean\n     */\n    public boolean isFailed(String performanceReportName) {\n        return getPerformanceReport(performanceReportName) == null;\n    }\n\n    public void doRespondingTimeGraph(StaplerRequest request,\n                                      StaplerResponse response) throws IOException {\n        String parameter = request.getParameter(\"performanceReportPosition\");\n        Run<?, ?> previousBuild = getBuild();\n        final Map<Run<?, ?>, Map<String, PerformanceReport>> buildReports = getBuildReports(parameter, previousBuild);\n        // Now we should have the data necessary to generate the graphs!\n        DataSetBuilder<String, NumberOnlyBuildLabel> dataSetBuilder = new DataSetBuilder<String, NumberOnlyBuildLabel>();\n        ReportValueSelector valueSelector = ReportValueSelector.get(getBuild().getParent());\n        String keyLabel = getKeyLabel(valueSelector.getGraphType());\n        for (Map.Entry<Run<?, ?>, Map<String, PerformanceReport>> entry : buildReports.entrySet()) {\n            NumberOnlyBuildLabel label = new NumberOnlyBuildLabel(entry.getKey());\n            PerformanceReport report = entry.getValue().get(parameter);\n            dataSetBuilder.add(valueSelector.getValue(report),\n                    keyLabel, label);\n        }\n        String legendLimit = request.getParameter(\"legendLimit\");\n        int limit = (legendLimit != null && !legendLimit.isEmpty()) ? Integer.parseInt(legendLimit) : Integer.MAX_VALUE;\n        new Graph(-1, 400, 200) {\n            @Override\n            protected JFreeChart createGraph() {\n                return createRespondingTimeChart(dataSetBuilder.build(), limit);\n            }\n        }.doPng(request, response);\n    }\n\n    public void doThroughputGraph(StaplerRequest request, StaplerResponse response) throws IOException {\n        String parameter = request.getParameter(\"performanceReportPosition\");\n        if (parameter == null) {\n            return;\n        }\n\n        if (ChartUtil.awtProblemCause != null) {\n            // not available. send out error message\n            response.sendRedirect2(request.getContextPath() + \"/images/headless.png\");\n            return;\n        }\n\n        final DataSetBuilder<String, NumberOnlyBuildLabel> dataSetBuilder = new DataSetBuilder<>();\n        List<? extends Run<?, ?>> builds = buildAction.getBuild().getParent().getBuilds();\n\n        for (final Run<?, ?> build : builds) {\n                final PerformanceBuildAction performanceBuildAction = build.getAction(PerformanceBuildAction.class);\n                if (performanceBuildAction == null) {\n                    continue;\n                }\n\n                final PerformanceReport performanceReport = performanceBuildAction\n                        .getPerformanceReportMap().getPerformanceReport(parameter);\n                if (performanceReport == null) {\n                    continue;\n                }\n\n                final ThroughputReport throughputReport = new ThroughputReport(performanceReport);\n                final NumberOnlyBuildLabel label = new NumberOnlyBuildLabel(build);\n                dataSetBuilder.add(throughputReport.get(), Messages.ProjectAction_RequestsPerSeconds(), label);\n        }\n\n        new Graph(-1, 400, 200) {\n            @Override\n            protected JFreeChart createGraph() {\n                return createThroughputChart((dataSetBuilder.build()));\n            }\n        }.doPng(request, response);\n    }\n\n    protected JFreeChart createThroughputChart(CategoryDataset dataset) {\n        return PerformanceProjectAction.createThroughputChart(dataset);\n    }\n\n\n    public void doRespondingTimeGraphPerTestCaseMode(\n            StaplerRequest request, StaplerResponse response) throws IOException {\n        final String performanceReportNameFile = request.getParameter(\"performanceReportPosition\");\n        if (performanceReportNameFile == null) {\n            return;\n        }\n\n        if (ChartUtil.awtProblemCause != null) {\n            // not available. send out error message\n            response.sendRedirect2(request.getContextPath() + \"/images/headless.png\");\n            return;\n        }\n\n        final DataSetBuilder<String, NumberOnlyBuildLabel> dataSetBuilder = new DataSetBuilder<>();\n        List<? extends Run<?, ?>> builds = buildAction.getBuild().getParent().getBuilds();\n\n        ReportValueSelector valueSelector = ReportValueSelector.get(getPublisher());\n\n\n        for (Run<?, ?> build : builds) {\n                NumberOnlyBuildLabel label = new NumberOnlyBuildLabel(build);\n\n            final PerformanceBuildAction performanceBuildAction = build.getAction(PerformanceBuildAction.class);\n            if (performanceBuildAction == null) {\n                continue;\n            }\n\n            final PerformanceReport performanceReport = performanceBuildAction\n                    .getPerformanceReportMap().getPerformanceReport(performanceReportNameFile);\n            if (performanceReport == null) {\n                continue;\n            }\n\n            List<UriReport> uriListOrdered = performanceReport.getUriListOrdered();\n            for (UriReport uriReport : uriListOrdered) {\n                dataSetBuilder.add(valueSelector.getValue(uriReport), uriReport.getUri(), label);\n            }\n        }\n\n        String legendLimit = request.getParameter(\"legendLimit\");\n        int limit = (legendLimit != null && !legendLimit.isEmpty()) ? Integer.parseInt(legendLimit) : Integer.MAX_VALUE;\n        new Graph(-1, 600, 200) {\n            @Override\n            protected JFreeChart createGraph() {\n                return createRespondingTimeChart(dataSetBuilder.build(), limit);\n            }\n        }.doPng(request, response);\n    }\n\n    public void doErrorsGraph(StaplerRequest request, StaplerResponse response)\n            throws IOException {\n        final String performanceReportNameFile = request.getParameter(\"performanceReportPosition\");\n        if (performanceReportNameFile == null) {\n            return;\n        }\n\n        if (ChartUtil.awtProblemCause != null) {\n            // not available. send out error message\n            response.sendRedirect2(request.getContextPath() + \"/images/headless.png\");\n            return;\n        }\n        DataSetBuilder<String, NumberOnlyBuildLabel> dataSetBuilderErrors = new DataSetBuilder<String, NumberOnlyBuildLabel>();\n        List<? extends Run<?, ?>> builds = buildAction.getBuild().getParent().getBuilds();\n\n        for (Run<?, ?> currentBuild : builds) {\n                NumberOnlyBuildLabel label = new NumberOnlyBuildLabel(currentBuild);\n                PerformanceBuildAction performanceBuildAction = currentBuild\n                        .getAction(PerformanceBuildAction.class);\n\n                if (performanceBuildAction == null) {\n                    continue;\n                }\n                PerformanceReport performanceReport = performanceBuildAction\n                        .getPerformanceReportMap().getPerformanceReport(\n                                performanceReportNameFile);\n                if (performanceReport == null) {\n                    continue;\n                }\n\n                dataSetBuilderErrors.add(performanceReport.errorPercent(),\n                        Messages.ProjectAction_Errors(), label);\n        }\n        new Graph(-1, 400, 200) {\n            @Override\n            protected JFreeChart createGraph() {\n                return createErrorsChart(dataSetBuilderErrors.build());\n            }\n        }.doPng(request, response);\n    }\n\n    protected JFreeChart createErrorsChart(CategoryDataset dataset) {\n        return PerformanceProjectAction.createErrorsChart(dataset);\n    }\n\n\n    protected JFreeChart createRespondingTimeChart(CategoryDataset dataset, int legendLimit) {\n        return PerformanceProjectAction.doCreateRespondingTimeChart(dataset, legendLimit);\n    }\n\n    private String getKeyLabel(String configType) {\n        if (configType.equals(PerformancePublisher.MRT))\n            return Messages.ProjectAction_Median();\n        if (configType.equals(PerformancePublisher.PRT))\n            return Messages.ProjectAction_Line90();\n        return Messages.ProjectAction_Average();\n    }\n\n    private Map<Run<?, ?>, Map<String, PerformanceReport>> getBuildReports(String parameter, Run<?, ?> previousBuild) throws IOException {\n        final Map<Run<?, ?>, Map<String, PerformanceReport>> buildReports = new LinkedHashMap<Run<?, ?>, Map<String, PerformanceReport>>();\n        while (previousBuild != null) {\n            final Run<?, ?> currentBuild = previousBuild;\n            parseReports(currentBuild, TaskListener.NULL,\n                    new PerformanceReportCollector() {\n\n                        public void addAll(Collection<PerformanceReport> parse) {\n                            for (PerformanceReport performanceReport : parse) {\n                                if (buildReports.get(currentBuild) == null) {\n                                    Map<String, PerformanceReport> map = new LinkedHashMap<String, PerformanceReport>();\n                                    buildReports.put(currentBuild, map);\n                                }\n                                buildReports.get(currentBuild).put(\n                                        performanceReport.getReportFileName(), performanceReport);\n                            }\n                        }\n                    }, parameter);\n            previousBuild = previousBuild.getPreviousCompletedBuild();\n        }\n\n        return buildReports;\n    }\n\n    public void doSummarizerGraph(StaplerRequest request, StaplerResponse response)\n            throws IOException {\n        String parameter = request.getParameter(\"performanceReportPosition\");\n        Run<?, ?> previousBuild = getBuild();\n        Map<Run<?, ?>, Map<String, PerformanceReport>> buildReports = getBuildReports(parameter, previousBuild);\n        DataSetBuilder<NumberOnlyBuildLabel, String> dataSetBuilderSummarizer = new DataSetBuilder<NumberOnlyBuildLabel, String>();\n        ReportValueSelector valueSelector = ReportValueSelector.get(getBuild().getParent());\n        for (Map.Entry<Run<?, ?>, Map<String, PerformanceReport>> entry : buildReports.entrySet()) {\n            NumberOnlyBuildLabel label = new NumberOnlyBuildLabel(entry.getKey());\n            PerformanceReport report = entry.getValue().get(parameter);\n\n            // Now we should have the data necessary to generate the graphs!\n            for (Map.Entry<String, UriReport> secondEntry : report.getUriReportMap().entrySet()) {\n                long methodValue = valueSelector.getValue(secondEntry.getValue());\n                dataSetBuilderSummarizer.add(methodValue, label, secondEntry.getKey());\n            }\n        }\n\n        new Graph(-1, 400, 200) {\n            @Override\n            protected JFreeChart createGraph() {\n                return createSummarizerChart(dataSetBuilderSummarizer.build());\n            }\n        }.doPng(request, response);\n    }\n\n    protected JFreeChart createSummarizerChart(CategoryDataset dataset) {\n        return PerformanceProjectAction.doCreateSummarizerChart(dataset, \"ms\", Messages.ProjectAction_RespondingTime());\n    }\n\n    protected void parseReports(Run<?, ?> build, TaskListener listener,\n                              PerformanceReportCollector collector, final String filename)\n            throws IOException {\n        File repo = new File(build.getRootDir(),\n                PerformanceReportMap.getPerformanceReportDirRelativePath());\n\n        // files directly under the directory are for JMeter, for compatibility\n        // reasons.\n        File[] files = repo.listFiles(new FileFilter() {\n\n            public boolean accept(File f) {\n                return !f.isDirectory() && !f.getName().endsWith(\".serialized\");\n            }\n        });\n        // this may fail, if the build itself failed, we need to recover gracefully\n        if (files != null) {\n            addAll(new JMeterParser(\"\", AbstractReport.DEFAULT_PERCENTILES).parse(build, Arrays.asList(files), listener));\n        }\n\n        // otherwise subdirectory name designates the parser ID.\n        File[] dirs = repo.listFiles(new FileFilter() {\n\n            public boolean accept(File f) {\n                return f.isDirectory();\n            }\n        });\n        // this may fail, if the build itself failed, we need to recover gracefully\n        if (dirs != null) {\n            for (File dir : dirs) {\n                PerformanceReportParser p = buildAction.getParserByDisplayName(dir\n                        .getName());\n                if (p != null) {\n                    File[] listFiles = dir.listFiles(new FilenameFilter() {\n\n                        public boolean accept(File dir, String name) {\n                            if (filename == null && !name.endsWith(\".serialized\")) {\n                                return true;\n                            }\n                            if (name.equals(filename)) {\n                                return true;\n                            }\n                            return false;\n                        }\n                    });\n                    if (listener != null && listener.getLogger() != null) {\n                        try {\n                            collector.addAll(p.parse(build, Arrays.asList(listFiles), listener));\n                        } catch (IOException ex) {\n                            listener.getLogger().println(\"Unable to process directory '\" + dir + \"'.\");\n                            ex.printStackTrace(listener.getLogger());\n                        }\n                    } else {\n                        // Handle the situation when listener or its logger is null\n                    }\n                }\n            }\n        }\n\n        //addPreviousBuildReports();\n    }\n\n    private void addPreviousBuildReports() {\n        for (Map.Entry<String, PerformanceReport> item : getPerformanceReportMap().entrySet()) {\n            PerformanceReport curReport = item.getValue();\n            int baselineBuild = curReport.getBaselineBuild();\n            PerformanceReport reportForCompare = (baselineBuild == 0) ?\n                    getPerformanceReportForBuild(getBuild().getPreviousCompletedBuild(), item.getKey()) :\n                    getPerformanceReportForBuild(getBuild(baselineBuild), item.getKey());\n            if (reportForCompare != null) {\n                curReport.setLastBuildReport(reportForCompare);\n            }\n        }\n    }\n\n    protected PerformanceReportMap getReportMap(Run<?, ?> build) {\n        if (build == null) {\n            return null;\n        }\n\n        PerformanceBuildAction action = build.getAction(PerformanceBuildAction.class);\n        if (action == null) {\n            return null;\n        }\n\n        return action.getPerformanceReportMap(false);\n    }\n\n    protected PerformanceReport getPerformanceReportForBuild(Run<?, ?> build, String key) {\n        PerformanceReportMap reportMap = getReportMap(build);\n        if (reportMap == null) {\n            return null;\n        }\n\n        return reportMap.getPerformanceReportMap().get(key);\n    }\n\n    protected Run<?, ?> getBuild(int buildNumber) {\n        Run<?, ?> r = getBuild();\n        while (r != null && buildNumber != r.getNumber()) {\n            r = r.getPreviousBuild();\n        }\n        return r;\n    }\n\n    protected interface PerformanceReportCollector {\n\n        void addAll(Collection<PerformanceReport> parse);\n    }\n\n    public Object getDynamic(final String link, final StaplerRequest request,\n                             final StaplerRequest response) {\n        if (TRENDREPORT_LINK.equals(link)) {\n            return createTrendReportGraphs(request);\n        } else {\n            return null;\n        }\n    }\n\n    public Object createTrendReportGraphs(final StaplerRequest request) {\n        String filename = getTrendReportFilename(request);\n        PerformanceReport report = performanceReportMap.get(filename);\n        Run<?, ?> build = getBuild();\n        if (build == null) {\n            // Handle the situation when build is null\n            return null;\n        }\n\n        TrendReportGraphs trendReport = new TrendReportGraphs(build.getParent(),\n                build, request, filename, report);\n\n        return trendReport;\n    }\n\n    private String getTrendReportFilename(final StaplerRequest request) {\n        PerformanceReportPosition performanceReportPosition = new PerformanceReportPosition();\n        request.bindParameters(performanceReportPosition);\n        return performanceReportPosition.getPerformanceReportPosition();\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/TrendReportGraphs.java",
    "content": "package hudson.plugins.performance;\n\nimport hudson.model.Job;\nimport hudson.model.ModelObject;\nimport hudson.model.Run;\nimport hudson.plugins.performance.actions.PerformanceBuildAction;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.data.PerformanceReportPosition;\nimport hudson.plugins.performance.reports.UriReport;\nimport org.kohsuke.stapler.StaplerRequest;\nimport org.kohsuke.stapler.StaplerResponse;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\n\npublic class TrendReportGraphs implements ModelObject {\n\n    private Run<?, ?> build;\n    private String filename;\n    private PerformanceReport performanceReport;\n    private Job<?, ?> project;\n\n    public TrendReportGraphs(final Job<?, ?> project,\n                             final Run<?, ?> build, final StaplerRequest request,\n                             String filename, PerformanceReport performanceReport) {\n        this.build = build;\n        this.filename = filename;\n        this.performanceReport = performanceReport;\n        this.project = project;\n    }\n\n    private UriReport getUriReportForRequest(StaplerRequest request) {\n\n        PerformanceReportPosition performanceReportPosition = new PerformanceReportPosition();\n        request.bindParameters(performanceReportPosition);\n\n        PerformanceBuildAction performanceBuildAction = build\n                .getAction(PerformanceBuildAction.class);\n\n        if (performanceBuildAction != null && performanceReport != null) {\n            String uri = performanceReportPosition.getSummarizerTrendUri();\n            if (uri != null) {\n                return performanceReport.getUriReportMap().get(uri);\n            }\n        }\n        return null;\n    }\n\n    public void doRespondingTimeGraph(StaplerRequest request,\n                                      StaplerResponse response) throws IOException {\n        UriReport uriReport = getUriReportForRequest(request);\n        if (uriReport != null) {\n            uriReport.doSummarizerTrendGraph(request, response);\n        }\n    }\n\n    public void doPercentileGraph(StaplerRequest request,\n                                  StaplerResponse response) throws IOException {\n        UriReport uriReport = getUriReportForRequest(request);\n        if (uriReport != null) {\n            uriReport.doPercentileGraph(request, response);\n        }\n    }\n\n    public void doThroughputGraph(StaplerRequest request,\n                                  StaplerResponse response) throws IOException {\n        UriReport uriReport = getUriReportForRequest(request);\n        if (uriReport != null) {\n            uriReport.doThroughputGraph(request, response);\n        }\n    }\n\n    public void doErrorGraph(StaplerRequest request,\n                                  StaplerResponse response) throws IOException {\n        UriReport uriReport = getUriReportForRequest(request);\n        if (uriReport != null) {\n            uriReport.doErrorGraph(request, response);\n        }\n    }\n\n    public ArrayList<String> getUris() {\n        ArrayList<String> uriList = new ArrayList<>();\n        PerformanceReport report = getPerformanceReport();\n\n        if (report != null) {\n            uriList.addAll(report.getUriReportMap().keySet());\n        }\n        return uriList;\n    }\n\n    public UriReport getUriReport(String uri) {\n        if (performanceReport != null) {\n            return performanceReport.getUriReportMap().get(uri);\n        } else {\n            return build.getAction(PerformanceBuildAction.class)\n                    .getPerformanceReportMap().getUriReport(uri);\n        }\n    }\n\n    public String getDisplayName() {\n        return Messages.TrendReportDetail_DisplayName();\n    }\n\n    public String getFilename() {\n        return filename;\n    }\n\n    public Job<?, ?> getProject() {\n        return project;\n    }\n\n    public Run<?, ?> getBuild() {\n        return build;\n    }\n\n    public boolean hasSamples(String uri) {\n        UriReport report = getUriReport(uri);\n        return report != null && report.hasSamples();\n    }\n\n    public PerformanceReport getPerformanceReport() {\n        return performanceReport;\n    }\n\n}"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/actions/ExternalBuildReportAction.java",
    "content": "package hudson.plugins.performance.actions;\n\n\nimport hudson.model.Action;\nimport org.kohsuke.stapler.StaplerProxy;\n\npublic class ExternalBuildReportAction implements Action, StaplerProxy {\n    private final String reportURL;\n\n    public ExternalBuildReportAction(String reportURL) {\n        this.reportURL = reportURL;\n    }\n\n    @Override\n    public String getIconFileName() {\n        return \"graph.gif\";\n    }\n\n    @Override\n    public String getDisplayName() {\n        return \"View External Report\";\n    }\n\n    @Override\n    public String getUrlName() {\n        return reportURL;\n    }\n\n    @Override\n    public Object getTarget() {\n        return null;\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/actions/PerformanceBuildAction.java",
    "content": "package hudson.plugins.performance.actions;\n\nimport hudson.model.Action;\nimport hudson.model.Run;\nimport hudson.plugins.performance.Messages;\nimport hudson.plugins.performance.PerformanceReportMap;\nimport hudson.plugins.performance.parsers.PerformanceReportParser;\nimport hudson.util.StreamTaskListener;\nimport org.kohsuke.stapler.StaplerProxy;\n\nimport java.io.IOException;\nimport java.io.PrintStream;\nimport java.lang.ref.WeakReference;\nimport java.util.List;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\npublic class PerformanceBuildAction implements Action, StaplerProxy {\n    private final Run<?, ?> build;\n\n    /**\n     * Configured parsers used to parse reports in this build.\n     * For compatibility reasons, this can be null.\n     */\n    private final List<PerformanceReportParser> parsers;\n\n    private transient final PrintStream hudsonConsoleWriter;\n\n    private transient WeakReference<PerformanceReportMap> performanceReportMap;\n\n    private static final Logger logger = Logger.getLogger(PerformanceBuildAction.class.getName());\n\n\n    public PerformanceBuildAction(Run<?, ?> pBuild, PrintStream logger,\n                                  List<PerformanceReportParser> parsers) {\n        build = pBuild;\n        hudsonConsoleWriter = logger;\n        this.parsers = parsers;\n    }\n\n    public PerformanceReportParser getParserByDisplayName(String displayName) {\n        if (parsers != null)\n            for (PerformanceReportParser parser : parsers)\n                if (parser.getDescriptor().getDisplayName().equals(displayName))\n                    return parser;\n        return null;\n    }\n\n    public String getDisplayName() {\n        return Messages.BuildAction_DisplayName();\n    }\n\n    public String getIconFileName() {\n        return \"graph.gif\";\n    }\n\n    public String getUrlName() {\n        return \"performance\";\n    }\n\n    public PerformanceReportMap getTarget() {\n        return getPerformanceReportMap(true);\n    }\n\n    public Run<?, ?> getBuild() {\n        return build;\n    }\n\n    public PrintStream getHudsonConsoleWriter() {\n        return hudsonConsoleWriter;\n    }\n\n    public synchronized PerformanceReportMap getPerformanceReportMap() {\n        return getPerformanceReportMap(true);\n    }\n\n    public synchronized PerformanceReportMap getPerformanceReportMap(boolean isInitNextLevel) {\n        PerformanceReportMap reportMap = null;\n        synchronized(this) {\n            WeakReference<PerformanceReportMap> wr = this.performanceReportMap;\n            if (wr != null) {\n                reportMap = wr.get();\n                if (reportMap != null) {\n                    return reportMap;\n                }\n            }\n        }\n        try {\n            reportMap = new PerformanceReportMap(this, StreamTaskListener.fromStderr(), isInitNextLevel);\n        } catch (IOException e) {\n            logger.log(Level.SEVERE, \"Error creating new PerformanceReportMap()\", e);\n        }\n        this.performanceReportMap = new WeakReference<>(reportMap);\n        return reportMap;\n    }\n\n    public synchronized void setPerformanceReportMap(WeakReference<PerformanceReportMap> performanceReportMap) {\n        synchronized(this) {\n            this.performanceReportMap = performanceReportMap;\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/actions/PerformanceProjectAction.java",
    "content": "package hudson.plugins.performance.actions;\n\nimport java.awt.BasicStroke;\nimport java.awt.Color;\nimport java.io.File;\nimport java.io.IOException;\nimport java.text.ParseException;\nimport java.text.SimpleDateFormat;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.GregorianCalendar;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\nimport org.jfree.chart.ChartFactory;\nimport org.jfree.chart.JFreeChart;\nimport org.jfree.chart.axis.CategoryAxis;\nimport org.jfree.chart.axis.CategoryLabelPositions;\nimport org.jfree.chart.axis.DateAxis;\nimport org.jfree.chart.axis.NumberAxis;\nimport org.jfree.chart.plot.CategoryPlot;\nimport org.jfree.chart.plot.PlotOrientation;\nimport org.jfree.chart.plot.XYPlot;\nimport org.jfree.chart.renderer.category.BarRenderer;\nimport org.jfree.chart.renderer.category.LineAndShapeRenderer;\nimport org.jfree.chart.renderer.xy.XYBarRenderer;\nimport org.jfree.chart.renderer.xy.XYDotRenderer;\nimport org.jfree.chart.renderer.xy.XYItemRenderer;\nimport org.jfree.chart.title.LegendTitle;\nimport org.jfree.data.category.CategoryDataset;\nimport org.jfree.data.xy.IntervalXYDataset;\nimport org.jfree.data.xy.XYDataset;\nimport org.jfree.ui.RectangleEdge;\nimport org.jfree.ui.RectangleInsets;\nimport org.kohsuke.stapler.StaplerRequest;\nimport org.kohsuke.stapler.StaplerResponse;\n\nimport edu.umd.cs.findbugs.annotations.NonNull;\nimport hudson.FilePath;\nimport hudson.model.AbstractBuild;\nimport hudson.model.AbstractProject;\nimport hudson.model.Action;\nimport hudson.model.Job;\nimport hudson.model.Run;\nimport hudson.plugins.performance.Messages;\nimport hudson.plugins.performance.PerformancePublisher;\nimport hudson.plugins.performance.PerformanceReportMap;\nimport hudson.plugins.performance.data.PerformanceReportPosition;\nimport hudson.plugins.performance.data.ReportValueSelector;\nimport hudson.plugins.performance.details.GraphConfigurationDetail;\nimport hudson.plugins.performance.details.TestSuiteReportDetail;\nimport hudson.plugins.performance.details.TrendReportDetail;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.reports.ThroughputReport;\nimport hudson.plugins.performance.reports.UriReport;\nimport hudson.util.ChartUtil;\nimport hudson.util.ChartUtil.NumberOnlyBuildLabel;\nimport hudson.util.ColorPalette;\nimport hudson.util.DataSetBuilder;\nimport hudson.util.Graph;\nimport hudson.util.ShiftedCategoryAxis;\n\npublic class PerformanceProjectAction implements Action {\n\n    private static final String CONFIGURE_LINK = \"configure\";\n    private static final String TRENDREPORT_LINK = \"trendReport\";\n    private static final String TESTSUITE_LINK = \"testsuiteReport\";\n\n    private static final String PLUGIN_NAME = \"performance\";\n\n    @SuppressWarnings(\"unused\")\n    private static final long serialVersionUID = 1L;\n\n    /**\n     * Logger.\n     */\n    private static final Logger LOGGER = Logger\n            .getLogger(PerformanceProjectAction.class.getName());\n\n    public final Job<?, ?> job;\n\n    private List<String> performanceReportList;\n\n    public String getDisplayName() {\n        return Messages.ProjectAction_DisplayName();\n    }\n\n    public String getIconFileName() {\n        return \"graph.gif\";\n    }\n\n    public String getUrlName() {\n        return PLUGIN_NAME;\n    }\n\n    public PerformanceProjectAction(Job<?, ?> job) {\n        this.job = job;\n    }\n\n    public static JFreeChart createErrorsChart(CategoryDataset dataset) {\n\n        final JFreeChart chart = ChartFactory.createLineChart(\n                Messages.ProjectAction_PercentageOfErrors(), // chart title\n                null, // unused\n                \"%\", // range axis label\n                dataset, // data\n                PlotOrientation.VERTICAL, // orientation\n                true, // include legend\n                true, // tooltips\n                false // urls\n        );\n\n        // NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART...\n\n        final LegendTitle legend = chart.getLegend();\n        legend.setPosition(RectangleEdge.BOTTOM);\n\n        chart.setBackgroundPaint(Color.WHITE);\n\n        final CategoryPlot plot = chart.getCategoryPlot();\n\n        // plot.setAxisOffset(new Spacer(Spacer.ABSOLUTE, 5.0, 5.0, 5.0, 5.0));\n        plot.setBackgroundPaint(Color.WHITE);\n        plot.setOutlinePaint(null);\n        plot.setRangeGridlinesVisible(true);\n        plot.setRangeGridlinePaint(Color.BLACK);\n\n        CategoryAxis domainAxis = new ShiftedCategoryAxis(null);\n        plot.setDomainAxis(domainAxis);\n        domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_90);\n        domainAxis.setLowerMargin(0.0);\n        domainAxis.setUpperMargin(0.0);\n        domainAxis.setCategoryMargin(0.0);\n\n        final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();\n        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());\n        rangeAxis.setUpperBound(100);\n        rangeAxis.setLowerBound(0);\n\n        final LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot\n                .getRenderer();\n        renderer.setBaseStroke(new BasicStroke(4.0f));\n        ColorPalette.apply(renderer);\n\n        // crop extra space around the graph\n        plot.setInsets(new RectangleInsets(5.0, 0, 0, 5.0));\n\n        return chart;\n    }\n\n    public static JFreeChart doCreateRespondingTimeChart(CategoryDataset dataset, int legendLimit) {\n\n        final JFreeChart chart = ChartFactory.createLineChart(\n                Messages.ProjectAction_RespondingTime(), // charttitle\n                null, // unused\n                \"ms\", // range axis label\n                dataset, // data\n                PlotOrientation.VERTICAL, // orientation\n                true, // include legend\n                true, // tooltips\n                false // urls\n        );\n        final LegendTitle legend = chart.getLegend();\n        legend.setPosition(RectangleEdge.BOTTOM);\n        if (dataset.getRowCount() > legendLimit) {\n            chart.removeLegend();\n        }\n\n        chart.setBackgroundPaint(Color.WHITE);\n\n        final CategoryPlot plot = chart.getCategoryPlot();\n\n        // plot.setAxisOffset(new Spacer(Spacer.ABSOLUTE, 5.0, 5.0, 5.0, 5.0));\n        plot.setBackgroundPaint(Color.WHITE);\n        plot.setOutlinePaint(null);\n        plot.setRangeGridlinesVisible(true);\n        plot.setRangeGridlinePaint(Color.BLACK);\n\n        CategoryAxis domainAxis = new ShiftedCategoryAxis(null);\n        plot.setDomainAxis(domainAxis);\n        domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_90);\n        domainAxis.setLowerMargin(0.0);\n        domainAxis.setUpperMargin(0.0);\n        domainAxis.setCategoryMargin(0.0);\n\n        final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();\n        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());\n\n        final LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot\n                .getRenderer();\n        renderer.setBaseStroke(new BasicStroke(4.0f));\n        ColorPalette.apply(renderer);\n\n        // crop extra space around the graph\n        plot.setInsets(new RectangleInsets(5.0, 0, 0, 5.0));\n\n        return chart;\n    }\n\n    public static JFreeChart createThroughputChart(final CategoryDataset dataset) {\n\n        final JFreeChart chart = ChartFactory.createLineChart(\n                Messages.ProjectAction_Throughput(), // chart title\n                null, // unused\n                Messages.ProjectAction_RequestsPerSeconds(), // range axis label\n                dataset, // data\n                PlotOrientation.VERTICAL, // orientation\n                true, // include legend\n                true, // tooltips\n                false // urls\n        );\n\n        final LegendTitle legend = chart.getLegend();\n        legend.setPosition(RectangleEdge.BOTTOM);\n\n        chart.setBackgroundPaint(Color.WHITE);\n\n        final CategoryPlot plot = chart.getCategoryPlot();\n\n        plot.setBackgroundPaint(Color.WHITE);\n        plot.setOutlinePaint(null);\n        plot.setRangeGridlinesVisible(true);\n        plot.setRangeGridlinePaint(Color.BLACK);\n\n        CategoryAxis domainAxis = new ShiftedCategoryAxis(null);\n        plot.setDomainAxis(domainAxis);\n        domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_90);\n        domainAxis.setLowerMargin(0.0);\n        domainAxis.setUpperMargin(0.0);\n        domainAxis.setCategoryMargin(0.0);\n\n        final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();\n        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());\n\n        final LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot.getRenderer();\n        renderer.setBaseStroke(new BasicStroke(4.0f));\n        ColorPalette.apply(renderer);\n\n        // crop extra space around the graph\n        plot.setInsets(new RectangleInsets(5.0, 0, 0, 5.0));\n\n        return chart;\n    }\n\n    public static JFreeChart doCreateSummarizerChart(CategoryDataset dataset,\n                                                     String yAxis, String chartTitle) {\n\n        final JFreeChart chart = ChartFactory.createBarChart(chartTitle, // chart\n                // title\n                null, // unused\n                yAxis, // range axis label\n                dataset, // data\n                PlotOrientation.VERTICAL, // orientation\n                true, // include legend\n                true, // tooltips\n                true // urls\n        );\n\n        chart.setBackgroundPaint(Color.WHITE);\n\n        final CategoryPlot plot = chart.getCategoryPlot();\n\n        plot.setBackgroundPaint(Color.WHITE);\n        plot.setRangeGridlinesVisible(true);\n        plot.setRangeGridlinePaint(Color.BLACK);\n\n        CategoryAxis domainAxis = plot.getDomainAxis();\n        domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);\n\n        final BarRenderer renderer = (BarRenderer) plot.getRenderer();\n        renderer.setDrawBarOutline(false);\n        renderer.setBaseStroke(new BasicStroke(4.0f));\n        renderer.setItemMargin(0);\n        renderer.setMaximumBarWidth(0.05);\n\n        return chart;\n    }\n\n    public static JFreeChart createSummarizerTrend(\n            ArrayList<XYDataset> dataset, String uri) {\n\n        final JFreeChart chart = ChartFactory.createTimeSeriesChart(uri, Messages.TrendReportDetail_Time(),\n                Messages.TrendReportDetail_ResponseTime(), dataset.get(0), true, true, false);\n        chart.setBackgroundPaint(Color.WHITE);\n\n        final XYPlot plot = chart.getXYPlot();\n        plot.setBackgroundPaint(Color.WHITE);\n        plot.setDomainGridlinePaint(Color.BLACK);\n        plot.setRangeGridlinePaint(Color.BLACK);\n\n        plot.setDomainCrosshairVisible(true);\n        plot.setRangeCrosshairVisible(true);\n\n        /*\n         * final NumberAxis axis2 = new NumberAxis(\"Errors\"); axis2.isAutoRange();\n         * axis2.setLowerBound(0); plot.setRangeAxis(1, axis2); plot.setDataset(1,\n         * dataset.get(1)); plot.mapDatasetToRangeAxis(1, 1);\n         *\n         * final StandardXYItemRenderer renderer2 = new StandardXYItemRenderer();\n         * renderer2.setSeriesPaint(0, Color.black); plot.setRenderer(1, renderer2);\n         */\n        final DateAxis axis = (DateAxis) plot.getDomainAxis();\n        axis.setDateFormatOverride(new SimpleDateFormat(\"HH:mm:ss\"));\n\n        final XYDotRenderer renderer = new XYDotRenderer(); // scatter plot\n        plot.setRenderer(renderer);\n        renderer.setDotWidth(2);\n        renderer.setDotHeight(2);\n        renderer.setSeriesPaint(0, ColorPalette.RED);\n\n        return chart;\n    }\n\n    public static JFreeChart createUriPercentileChart(XYDataset dataset, String uri) {\n        final JFreeChart chart = ChartFactory.createXYLineChart(uri, Messages.TrendReportDetail_Percent(),\n                Messages.TrendReportDetail_ResponseTime(), dataset,\n                PlotOrientation.VERTICAL, true, true, false);\n        chart.setBackgroundPaint(Color.WHITE);\n\n        final XYPlot plot = chart.getXYPlot();\n        plot.setBackgroundPaint(Color.WHITE);\n        plot.setDomainGridlinePaint(Color.BLACK);\n        plot.setRangeGridlinePaint(Color.BLACK);\n\n        // Exclude zeroes to make sure y-axis aligns with response time auto range:\n        final NumberAxis yaxis = (NumberAxis) plot.getRangeAxis();\n        yaxis.setAutoRange(true);\n        yaxis.setAutoRangeIncludesZero(false);\n\n        final NumberAxis xaxis = (NumberAxis) plot.getDomainAxis();\n        xaxis.setRange(0, 100); // avoid auto margin\n\n        final XYItemRenderer renderer = plot.getRenderer();\n        renderer.setSeriesPaint(0, ColorPalette.RED);\n\n        return chart;\n    }\n\n    public static JFreeChart createUriThroughputChart(IntervalXYDataset dataset, String uri) {\n        final JFreeChart chart = ChartFactory.createXYBarChart(uri, Messages.TrendReportDetail_Time(), true,\n                Messages.TrendReportDetail_RequestsPerMinute(), dataset,\n                PlotOrientation.VERTICAL, true, true, false);\n        chart.setBackgroundPaint(Color.WHITE);\n\n        final XYPlot plot = chart.getXYPlot();\n        plot.setBackgroundPaint(Color.WHITE);\n        plot.setDomainGridlinePaint(Color.BLACK);\n        plot.setRangeGridlinePaint(Color.BLACK);\n\n        final DateAxis axis = (DateAxis) plot.getDomainAxis();\n        axis.setDateFormatOverride(new SimpleDateFormat(\"HH:mm:ss\"));\n\n        final XYBarRenderer renderer = (XYBarRenderer) plot.getRenderer();\n        // As of Jenkins v2.198 jfreechart v1.0.19 paints bars with a gradient by\n        // default\n        // which can't be turned off in v1.0.9 the plugin is compiled against\n        // so instead use a red outline and fill with white:\n        renderer.setSeriesPaint(0, Color.WHITE);\n        renderer.setDrawBarOutline(true);\n        renderer.setSeriesOutlinePaint(0, ColorPalette.RED);\n\n        return chart;\n    }\n\n    private String getPerformanceReportNameFile(StaplerRequest request) {\n        PerformanceReportPosition performanceReportPosition = new PerformanceReportPosition();\n        request.bindParameters(performanceReportPosition);\n        return getPerformanceReportNameFile(performanceReportPosition);\n    }\n\n    private String getPerformanceReportNameFile(final PerformanceReportPosition performanceReportPosition) {\n        String performanceReportNameFile = performanceReportPosition.getPerformanceReportPosition();\n        if (performanceReportNameFile == null && getPerformanceReportList().size() == 1) {\n            performanceReportNameFile = getPerformanceReportList().get(0);\n        }\n        return performanceReportNameFile;\n    }\n\n    public void doErrorsGraph(StaplerRequest request, StaplerResponse response)\n            throws IOException {\n        final String performanceReportNameFile = getPerformanceReportNameFile(request);\n        if (performanceReportNameFile == null) {\n            return;\n        }\n\n        if (ChartUtil.awtProblemCause != null) {\n            // not available. send out error message\n            response.sendRedirect2(request.getContextPath() + \"/images/headless.png\");\n            return;\n        }\n        DataSetBuilder<String, NumberOnlyBuildLabel> dataSetBuilderErrors = new DataSetBuilder<>();\n        List<? extends Run<?, ?>> builds = getJob().getBuilds();\n        Range buildsLimits = getFirstAndLastBuild(request, builds);\n\n        int nbBuildsToAnalyze = builds.size();\n        for (Run<?, ?> currentBuild : builds) {\n            if (buildsLimits.in(nbBuildsToAnalyze)) {\n\n                if (!buildsLimits.includedByStep(currentBuild.number)) {\n                    continue;\n                }\n\n                NumberOnlyBuildLabel label = new NumberOnlyBuildLabel(currentBuild);\n                PerformanceBuildAction performanceBuildAction = currentBuild\n                        .getAction(PerformanceBuildAction.class);\n                if (performanceBuildAction == null) {\n                    continue;\n                }\n                PerformanceReport performanceReport = performanceBuildAction\n                        .getPerformanceReportMap().getPerformanceReport(\n                                performanceReportNameFile);\n                if (performanceReport == null) {\n                    nbBuildsToAnalyze--;\n                    continue;\n                }\n                dataSetBuilderErrors.add(performanceReport.errorPercent(),\n                        Messages.ProjectAction_Errors(), label);\n            }\n            nbBuildsToAnalyze--;\n        }\n\n        new Graph(-1, 400, 200) {\n            @Override\n            protected JFreeChart createGraph() {\n                return createErrorsGraph(dataSetBuilderErrors.build());\n            }\n        }.doPng(request, response);\n    }\n\n    protected JFreeChart createErrorsGraph(CategoryDataset dataset) {\n        return createErrorsChart(dataset);\n    }\n\n    public void doRespondingTimeGraphPerTestCaseMode(\n            StaplerRequest request, StaplerResponse response) throws IOException {\n        final String performanceReportNameFile = getPerformanceReportNameFile(request);\n        if (performanceReportNameFile == null) {\n            return;\n        }\n\n        if (ChartUtil.awtProblemCause != null) {\n            // not available. send out error message\n            response.sendRedirect2(request.getContextPath() + \"/images/headless.png\");\n            return;\n        }\n        DataSetBuilder<String, NumberOnlyBuildLabel> dataSetBuilder = new DataSetBuilder<>();\n        ReportValueSelector valueSelector = ReportValueSelector.get(getJob());\n        List<? extends Run<?, ?>> builds = getJob().getBuilds();\n        Range buildsLimits = getFirstAndLastBuild(request, builds);\n\n        int nbBuildsToAnalyze = builds.size();\n\n        for (Run<?, ?> build : builds) {\n            if (buildsLimits.in(nbBuildsToAnalyze)) {\n                NumberOnlyBuildLabel label = new NumberOnlyBuildLabel(build);\n\n                if (!buildsLimits.includedByStep(build.number)) {\n                    continue;\n                }\n                PerformanceReport performanceReport = getPerformanceReport(build, performanceReportNameFile);\n                if (performanceReport == null) {\n                    nbBuildsToAnalyze--;\n                    continue;\n                }\n\n                List<UriReport> uriListOrdered = performanceReport.getUriListOrdered();\n                for (UriReport uriReport : uriListOrdered) {\n                    dataSetBuilder.add(valueSelector.getValue(uriReport), uriReport.getUri(), label);\n                }\n            }\n            nbBuildsToAnalyze--;\n        }\n        String legendLimit = request.getParameter(\"legendLimit\");\n        int limit = (legendLimit != null && !legendLimit.isEmpty()) ? Integer.parseInt(legendLimit) : Integer.MAX_VALUE;\n\n        new Graph(-1, 600, 200) {\n            @Override\n            protected JFreeChart createGraph() {\n                return createRespondingTimeChart(dataSetBuilder.build(), limit);\n            }\n        }.doPng(request, response);\n    }\n\n    protected PerformanceReport getPerformanceReport(Run<?, ?> build, String reportFileName) {\n        PerformanceBuildAction performanceBuildAction = build.getAction(PerformanceBuildAction.class);\n        if (performanceBuildAction == null) {\n            return null;\n        }\n        return performanceBuildAction\n                .getPerformanceReportMap()\n                .getPerformanceReport(reportFileName);\n    }\n\n    protected JFreeChart createRespondingTimeChart(CategoryDataset dataset, int legendLimit) {\n        return doCreateRespondingTimeChart(dataset, legendLimit);\n    }\n\n    public void doRespondingTimeGraph(StaplerRequest request, StaplerResponse response) throws IOException {\n        final String performanceReportNameFile = getPerformanceReportNameFile(request);\n        if (performanceReportNameFile == null) {\n            return;\n        }\n\n        if (ChartUtil.awtProblemCause != null) {\n            // not available. send out error message\n            response.sendRedirect2(request.getContextPath() + \"/images/headless.png\");\n            return;\n        }\n        DataSetBuilder<String, NumberOnlyBuildLabel> dataSetBuilderAverage = new DataSetBuilder<>();\n        List<? extends Run<?, ?>> builds = getJob().getBuilds();\n        Range buildsLimits = getFirstAndLastBuild(request, builds);\n\n        int nbBuildsToAnalyze = builds.size();\n        for (Run<?, ?> build : builds) {\n            if (buildsLimits.in(nbBuildsToAnalyze)) {\n\n                if (!buildsLimits.includedByStep(build.number)) {\n                    continue;\n                }\n\n                NumberOnlyBuildLabel label = new NumberOnlyBuildLabel(build);\n                PerformanceBuildAction performanceBuildAction = build\n                        .getAction(PerformanceBuildAction.class);\n                if (performanceBuildAction == null) {\n                    continue;\n                }\n                PerformanceReport performanceReport = performanceBuildAction\n                        .getPerformanceReportMap().getPerformanceReport(\n                                performanceReportNameFile);\n                if (performanceReport == null) {\n                    nbBuildsToAnalyze--;\n                    continue;\n                }\n                dataSetBuilderAverage.add(performanceReport.getMedian(),\n                        Messages.ProjectAction_Median(), label);\n                dataSetBuilderAverage.add(performanceReport.getAverage(),\n                        Messages.ProjectAction_Average(), label);\n                dataSetBuilderAverage.add(performanceReport.get90Line(),\n                        Messages.ProjectAction_Line90(), label);\n                dataSetBuilderAverage.add(performanceReport.get95Line(),\n                        Messages.ProjectAction_Line95(), label);\n            }\n            nbBuildsToAnalyze--;\n        }\n\n        String legendLimit = request.getParameter(\"legendLimit\");\n        int limit = (legendLimit != null && !legendLimit.isEmpty()) ? Integer.parseInt(legendLimit) : Integer.MAX_VALUE;\n\n        new Graph(-1, 400, 200) {\n            @Override\n            protected JFreeChart createGraph() {\n                return createRespondingTimeChart(dataSetBuilderAverage.build(), limit);\n            }\n        }.doPng(request, response);\n    }\n\n    public void doThroughputGraph(final StaplerRequest request, final StaplerResponse response) throws IOException {\n        final String performanceReportNameFile = getPerformanceReportNameFile(request);\n        if (performanceReportNameFile == null) {\n            return;\n        }\n\n        if (ChartUtil.awtProblemCause != null) {\n            // not available. send out error message\n            response.sendRedirect2(request.getContextPath() + \"/images/headless.png\");\n            return;\n        }\n\n        final DataSetBuilder<String, NumberOnlyBuildLabel> dataSetBuilder = new DataSetBuilder<>();\n        final List<? extends Run<?, ?>> builds = getJob().getBuilds();\n        final Range buildsLimits = getFirstAndLastBuild(request, builds);\n\n        int nbBuildsToAnalyze = builds.size();\n        for (final Run<?, ?> build : builds) {\n            if (buildsLimits.in(nbBuildsToAnalyze)) {\n\n                if (!buildsLimits.includedByStep(build.number)) {\n                    continue;\n                }\n\n                final PerformanceBuildAction performanceBuildAction = build.getAction(PerformanceBuildAction.class);\n                if (performanceBuildAction == null) {\n                    continue;\n                }\n\n                final PerformanceReport performanceReport = performanceBuildAction\n                        .getPerformanceReportMap().getPerformanceReport(performanceReportNameFile);\n                if (performanceReport == null) {\n                    nbBuildsToAnalyze--;\n                    continue;\n                }\n\n                final ThroughputReport throughputReport = new ThroughputReport(performanceReport);\n                final NumberOnlyBuildLabel label = new NumberOnlyBuildLabel(build);\n                dataSetBuilder.add(throughputReport.get(), Messages.ProjectAction_RequestsPerSeconds(), label);\n            }\n            nbBuildsToAnalyze--;\n        }\n\n        new Graph(-1, 400, 200) {\n            @Override\n            protected JFreeChart createGraph() {\n                return createThroughputGraph(dataSetBuilder.build());\n            }\n        }.doPng(request, response);\n    }\n\n    protected JFreeChart createThroughputGraph(CategoryDataset dataset) {\n        return createThroughputChart(dataset);\n    }\n\n    public void doSummarizerGraph(StaplerRequest request, StaplerResponse response) throws IOException {\n        final PerformanceReportPosition performanceReportPosition = new PerformanceReportPosition();\n        request.bindParameters(performanceReportPosition);\n        final String performanceReportNameFile = getPerformanceReportNameFile(performanceReportPosition);\n\n        if (ChartUtil.awtProblemCause != null) {\n            // not available. send out error message\n            // response.sendRedirect2(request.getContextPath() +\n            // \"/images/headless.png\");\n            return;\n        }\n        DataSetBuilder<NumberOnlyBuildLabel, String> dataSetBuilderSummarizer = new DataSetBuilder<>();\n        DataSetBuilder<NumberOnlyBuildLabel, String> dataSetBuilderSummarizerErrors = new DataSetBuilder<>();\n        ReportValueSelector valueSelector = ReportValueSelector.get(getJob());\n\n        List<?> builds = getJob().getBuilds();\n        Range buildsLimits = getFirstAndLastBuild(request, builds);\n\n        int nbBuildsToAnalyze = builds.size();\n        for (Object build : builds) {\n            Run<?, ?> currentBuild = (Run<?, ?>) build;\n            if (buildsLimits.in(nbBuildsToAnalyze)) {\n                NumberOnlyBuildLabel label = new NumberOnlyBuildLabel(currentBuild);\n                PerformanceReport performanceReport = getPerformanceReport(currentBuild, performanceReportNameFile);\n                if (performanceReport == null) {\n                    nbBuildsToAnalyze--;\n                    continue;\n                }\n\n                for (Map.Entry<String, UriReport> entry : performanceReport.getUriReportMap().entrySet()) {\n                    long methodValue = valueSelector.getValue(entry.getValue());\n                    float methodErrors = entry.getValue().getSummarizerErrors();\n                    dataSetBuilderSummarizer.add(methodValue, label, entry.getKey());\n                    dataSetBuilderSummarizerErrors.add(methodErrors, label, entry.getKey());\n                }\n            }\n            nbBuildsToAnalyze--;\n        }\n\n        String summarizerReportType = performanceReportPosition\n                .getSummarizerReportType();\n\n        if (summarizerReportType != null) {\n            new Graph(-1, 400, 200) {\n                @Override\n                protected JFreeChart createGraph() {\n                    return createSummarizerChart(dataSetBuilderSummarizerErrors.build(), \"%\",\n                            Messages.ProjectAction_PercentageOfErrors());\n                }\n            }.doPng(request, response);\n        } else {\n            new Graph(-1, 400, 200) {\n                @Override\n                protected JFreeChart createGraph() {\n                    return createSummarizerChart(dataSetBuilderSummarizer.build(), \"ms\",\n                            Messages.ProjectAction_RespondingTime());\n                }\n            }.doPng(request, response);\n        }\n    }\n\n    protected JFreeChart createSummarizerChart(CategoryDataset dataset, String yAxis, String chartTitle) {\n        return doCreateSummarizerChart(dataset, yAxis, chartTitle);\n    }\n\n    /**\n     * <p>\n     * give a list of two Integer : the smallest build to use and the biggest.\n     * </p>\n     *\n     * @param request\n     * @param builds\n     * @return outList\n     */\n    private Range getFirstAndLastBuild(StaplerRequest request, List<?> builds) {\n        GraphConfigurationDetail graphConf = (GraphConfigurationDetail) createUserConfiguration(request);\n\n        if (graphConf.isNone()) {\n            return all(builds);\n        }\n\n        if (graphConf.isBuildCount()) {\n            if (graphConf.getBuildCount() <= 0) {\n                return all(builds);\n            } else {\n                int first = builds.size() - graphConf.getBuildCount();\n                return new Range(first > 0 ? first + 1 : 1, builds.size());\n            }\n        } else if (graphConf.isBuildNth()) {\n            if (graphConf.getBuildStep() <= 0) {\n                return all(builds);\n            } else {\n                return new Range(1, builds.size(), graphConf.getBuildStep());\n            }\n        } else if (graphConf.isDate()) {\n            if (graphConf.isDefaultDates()) {\n                return all(builds);\n            } else {\n                int firstBuild = -1;\n                int lastBuild = -1;\n                int var = builds.size();\n                GregorianCalendar firstDate = null;\n                GregorianCalendar lastDate = null;\n                try {\n                    firstDate = GraphConfigurationDetail\n                            .getGregorianCalendarFromString(graphConf.getFirstDayCount());\n                    lastDate = GraphConfigurationDetail\n                            .getGregorianCalendarFromString(graphConf.getLastDayCount());\n                    lastDate.set(GregorianCalendar.HOUR_OF_DAY, 23);\n                    lastDate.set(GregorianCalendar.MINUTE, 59);\n                    lastDate.set(GregorianCalendar.SECOND, 59);\n                    for (Object build : builds) {\n                        Run<?, ?> currentBuild = (Run<?, ?>) build;\n                        GregorianCalendar buildDate = new GregorianCalendar();\n                        buildDate.setTime(currentBuild.getTimestamp().getTime());\n                        if (firstDate.getTime().before(buildDate.getTime())) {\n                            firstBuild = var;\n                        }\n                        if (lastBuild < 0 && lastDate.getTime().after(buildDate.getTime())) {\n                            lastBuild = var;\n                        }\n                        var--;\n                    }\n                    return new Range(firstBuild, lastBuild);\n                } catch (ParseException e) {\n                    LOGGER\n                            .log(Level.SEVERE, \"Error during the manage of the Calendar\", e);\n                }\n            }\n        }\n        throw new IllegalArgumentException(\"unsupported configType + \"\n                + graphConf.getConfigType());\n    }\n\n    public Range all(List<?> builds) {\n        return new Range(1, builds.size());\n    }\n\n    public Job<?, ?> getJob() {\n        return job;\n    }\n\n    public final Run<?, ?> getSomeBuildWithWorkspace() {\n        byte cnt = 0;\n        for (Run<?, ?> run = job.getLastBuild(); cnt < 5 && run != null; run = run.getPreviousBuild()) {\n            if (!run.isBuilding()) {\n                if (run instanceof AbstractBuild) {\n                    FilePath ws = ((AbstractBuild<?, ?>) run).getWorkspace();\n                    if (ws != null) {\n                        return run;\n                    }\n                } else {\n                    return run;\n                }\n            }\n            cnt++;\n        }\n        return null;\n    }\n\n    @NonNull\n    public List<String> getPerformanceReportList() {\n        this.performanceReportList = new ArrayList<>(0);\n        if (null == this.job) {\n            return performanceReportList;\n        }\n\n        if (null == getSomeBuildWithWorkspace()) {\n            return performanceReportList;\n        }\n        File file = new File(getSomeBuildWithWorkspace().getRootDir(),\n                PerformanceReportMap.getPerformanceReportDirRelativePath());\n        if (!file.isDirectory()) {\n            return performanceReportList;\n        }\n        File[] files = file.listFiles();\n\n        if (files != null) {\n            for (File entry : files) {\n                if (entry.isDirectory()) {\n                    File[] entryFiles = entry.listFiles();\n                    if (entryFiles != null) {\n                        for (File e : Objects.requireNonNull(entryFiles)) {\n                            if (!e.getName().endsWith(\".serialized\") && !e.getName().endsWith(\".serialized-v2\")) {\n                                this.performanceReportList.add(e.getName());\n                            }\n                        }\n                    }\n\n                } else {\n                    if (!entry.getName().endsWith(\".serialized\") && !entry.getName().endsWith(\".serialized-v2\")) {\n                        this.performanceReportList.add(entry.getName());\n                    }\n                }\n\n            }\n\n        } else {\n            // Handle the situation when files is null\n            return performanceReportList;\n        }\n\n        Collections.sort(performanceReportList);\n\n        return this.performanceReportList;\n    }\n\n    public void setPerformanceReportList(List<String> performanceReportList) {\n        this.performanceReportList = performanceReportList;\n    }\n\n    public boolean isTrendVisibleOnProjectDashboard() {\n        return getPerformanceReportList().size() == 1;\n    }\n\n    /**\n     * Returns the graph configuration for this project.\n     *\n     * @param link     not used\n     * @param request  Stapler request\n     * @param response Stapler response\n     * @return the dynamic result of the analysis (detail page).\n     */\n    public Object getDynamic(final String link, final StaplerRequest request,\n                             final StaplerResponse response) {\n        if (CONFIGURE_LINK.equals(link)) {\n            return createUserConfiguration(request);\n        } else if (TRENDREPORT_LINK.equals(link)) {\n            return createTrendReport(request);\n        } else if (TESTSUITE_LINK.equals(link)) {\n            return createTestsuiteReport(request);\n        } else {\n            return null;\n        }\n    }\n\n    /**\n     * Creates a view to configure the trend graph for the current user.\n     *\n     * @param request Stapler request\n     * @return a view to configure the trend graph for the current user\n     */\n    private Object createUserConfiguration(final StaplerRequest request) {\n        return new GraphConfigurationDetail(job, PLUGIN_NAME, request);\n    }\n\n    /**\n     * Creates a view to configure the trend graph for the current user.\n     *\n     * @param request Stapler request\n     * @return a view to configure the trend graph for the current user\n     */\n    private Object createTrendReport(final StaplerRequest request) {\n        String filename = getTrendReportFilename(request);\n        CategoryDataset dataSet = getTrendReportData(request, filename).build();\n        return new TrendReportDetail(job, PLUGIN_NAME, request, filename, dataSet);\n    }\n\n    private Object createTestsuiteReport(final StaplerRequest request) {\n        String filename = getTestSuiteReportFilename(request);\n        Range buildsLimits = getFirstAndLastBuild(request, getJob().getBuilds());\n        return new TestSuiteReportDetail(job, filename, buildsLimits);\n    }\n\n    private String getTrendReportFilename(final StaplerRequest request) {\n        PerformanceReportPosition performanceReportPosition = new PerformanceReportPosition();\n        request.bindParameters(performanceReportPosition);\n        return performanceReportPosition.getPerformanceReportPosition();\n    }\n\n    private String getTestSuiteReportFilename(final StaplerRequest request) {\n        PerformanceReportPosition performanceReportPosition = new PerformanceReportPosition();\n        request.bindParameters(performanceReportPosition);\n        return performanceReportPosition.getPerformanceReportPosition();\n    }\n\n    private DataSetBuilder<String, NumberOnlyBuildLabel> getTrendReportData(final StaplerRequest request,\n                                                                            String performanceReportNameFile) {\n\n        DataSetBuilder<String, NumberOnlyBuildLabel> dataSet = new DataSetBuilder<>();\n        List<? extends Run<?, ?>> builds = getJob().getBuilds();\n        Range buildsLimits = getFirstAndLastBuild(request, builds);\n\n        int nbBuildsToAnalyze = builds.size();\n        for (Run<?, ?> currentBuild : builds) {\n            if (buildsLimits.in(nbBuildsToAnalyze)) {\n                NumberOnlyBuildLabel label = new NumberOnlyBuildLabel(currentBuild);\n                PerformanceBuildAction performanceBuildAction = currentBuild\n                        .getAction(PerformanceBuildAction.class);\n                if (performanceBuildAction == null) {\n                    continue;\n                }\n                PerformanceReport report = null;\n                report = performanceBuildAction.getPerformanceReportMap()\n                        .getPerformanceReport(performanceReportNameFile);\n                if (report == null) {\n                    nbBuildsToAnalyze--;\n                    continue;\n                }\n                dataSet.add(report.getAverage(),\n                        Messages.ProjectAction_Average(), label);\n                Map<Double, Long> percentilesValues = report.getPercentilesValues();\n\n                for (Map.Entry<Double, Long> entry : percentilesValues.entrySet()) {\n                    dataSet.add(entry.getValue(),\n                            report.getPercentileLabel(entry.getKey()), label);\n                }\n\n                dataSet.add(Math.round(report.errorPercent()),\n                        Messages.ProjectAction_PercentageOfErrors(), label);\n                dataSet.add(report.countErrors(),\n                        Messages.ProjectAction_Errors(), label);\n                dataSet.add(report.getTotalTrafficInKb(),\n                        Messages.ProjectAction_TotalTrafficKB(), label);\n                dataSet.add(report.getAverageSizeInKb(),\n                        Messages.ProjectAction_AverageKB(), label);\n            }\n            nbBuildsToAnalyze--;\n        }\n        return dataSet;\n    }\n\n    public boolean ifSummarizerParserUsed(String filename) {\n\n        return this.getJob().getBuilds().getLastBuild()\n                .getAction(PerformanceBuildAction.class).getPerformanceReportMap()\n                .getPerformanceReport(filename).ifSummarizerParserUsed(filename);\n    }\n\n    public boolean ifModePerformancePerTestCaseUsed() {\n        if (this.job instanceof AbstractProject) {\n            AbstractProject<?, ?> project = (AbstractProject<?, ?>) job;\n            PerformancePublisher publisher = (PerformancePublisher) project.getPublishersList()\n                    .get(PerformancePublisher.class);\n            return publisher != null && publisher.isModePerformancePerTestCase();\n        } else {\n            return true;\n        }\n    }\n\n    public boolean ifModeThroughputUsed() {\n        if (this.job instanceof AbstractProject) {\n            AbstractProject<?, ?> project = (AbstractProject<?, ?>) job;\n            PerformancePublisher publisher = (PerformancePublisher) project.getPublishersList()\n                    .get(PerformancePublisher.class);\n            return publisher == null || publisher.isModeThroughput();\n        } else {\n            return true;\n        }\n    }\n\n    public static class Range {\n\n        public int first;\n\n        public int last;\n\n        public int step;\n\n        public Range(int first, int last) {\n            this.first = first;\n            this.last = last;\n            this.step = 1;\n        }\n\n        public Range(int first, int last, int step) {\n            this(first, last);\n            this.step = step;\n        }\n\n        public boolean in(int nbBuildsToAnalyze) {\n            return nbBuildsToAnalyze <= last && first <= nbBuildsToAnalyze;\n        }\n\n        public boolean includedByStep(int buildNumber) {\n            return (buildNumber % step == 0);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/build/PerformanceTestBuild.java",
    "content": "package hudson.plugins.performance.build;\n\nimport hudson.EnvVars;\nimport hudson.Extension;\nimport hudson.FilePath;\nimport hudson.Functions;\nimport hudson.Launcher;\nimport hudson.model.AbstractProject;\nimport hudson.model.Action;\nimport hudson.model.Result;\nimport hudson.model.Run;\nimport hudson.model.TaskListener;\nimport hudson.plugins.performance.Messages;\nimport hudson.plugins.performance.PerformancePublisher;\nimport hudson.plugins.performance.actions.PerformanceProjectAction;\nimport hudson.tasks.BuildStepDescriptor;\nimport hudson.tasks.Builder;\nimport jenkins.tasks.SimpleBuildStep;\nimport org.apache.commons.io.output.NullOutputStream;\nimport org.codehaus.plexus.util.cli.CommandLineUtils;\nimport org.jenkinsci.Symbol;\nimport org.kohsuke.stapler.DataBoundConstructor;\nimport org.kohsuke.stapler.DataBoundSetter;\n\nimport edu.umd.cs.findbugs.annotations.NonNull;\n\nimport java.io.*;\nimport java.lang.reflect.Method;\nimport java.net.MalformedURLException;\nimport java.net.URL;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.InvalidPathException;\nimport java.util.*;\nimport java.util.logging.Logger;\n\n/**\n * \"Build step\" for running performance test\n */\npublic class PerformanceTestBuild extends Builder implements SimpleBuildStep {\n    public static final Logger LOGGER = Logger.getLogger(PerformanceTestBuild.class.getName());\n\n    protected final static String PERFORMANCE_TEST_COMMAND = \"bzt\";\n    protected final static String VIRTUALENV_COMMAND = \"virtualenv\";\n    protected final static String HELP_OPTION = \"--help\";\n    protected final static String VIRTUALENV_PATH_UNIX = \"/taurus-venv/bin/\";\n    protected final static String VIRTUALENV_PATH_WINDOWS = \"\\\\taurus-venv\\\\Scripts\\\\\";\n\n    final static String[] CHECK_BZT_COMMAND = new String[]{PERFORMANCE_TEST_COMMAND, HELP_OPTION};\n    final static String[] CHECK_VIRTUALENV_COMMAND = new String[]{VIRTUALENV_COMMAND, HELP_OPTION};\n\n    final static String[] CREATE_LOCAL_PYTHON_COMMAND_WITH_SYSTEM_PACKAGES_OPTION =\n            new String[]{VIRTUALENV_COMMAND, \"--clear\", \"--system-site-packages\", \"taurus-venv\"};\n    final static String[] CREATE_LOCAL_PYTHON_COMMAND = new String[]{VIRTUALENV_COMMAND, \"--clear\", \"taurus-venv\"};\n\n    protected final static String DEFAULT_CONFIG_FILE = \"jenkins-report.yml\";\n\n\n    @Symbol({\"bzt\",\"performanceTest\"})\n    @Extension\n    public static class Descriptor extends BuildStepDescriptor<Builder> {\n\n        @Override\n        public boolean isApplicable(Class<? extends AbstractProject> jobType) {\n            return true;\n        }\n\n        @Override\n        public String getDisplayName() {\n            return Messages.PerformanceTest_Name();\n        }\n    }\n\n\n    private String params;\n    private boolean printDebugOutput = false;\n    private boolean alwaysUseVirtualenv = false;\n    private boolean useSystemSitePackages = true;\n    private boolean generatePerformanceTrend = true;\n    private boolean useBztExitCode = true;\n    private String bztVersion = \"\";\n    private String workingDirectory = \"\";\n    private String virtualEnvCommand = \"\";\n    /**\n     * Use 'workingDirectory' for set bzt working directory\n     */\n    @Deprecated\n    private transient String workspace = \"\";\n\n    @DataBoundConstructor\n    public PerformanceTestBuild(String params) {\n        this.params = params;\n    }\n\n    /**\n     * This method, invoked after object is resurrected from persistence\n     */\n    public Object readResolve() {\n        if (workspace != null && !workspace.isEmpty()) {\n            workingDirectory = workspace;\n            workspace = \"\";\n        }\n        return this;\n    }\n\n\n    @Override\n    public Action getProjectAction(AbstractProject<?, ?> project) {\n        return generatePerformanceTrend  ? new PerformanceProjectAction(project) : null;\n    }\n\n\n    @Override\n    public void perform(@NonNull Run<?, ?> run, @NonNull FilePath workspace, @NonNull Launcher launcher, @NonNull TaskListener listener) throws InterruptedException, IOException {\n        PrintStream logger = listener.getLogger();\n        EnvVars envVars = run.getEnvironment(listener);\n        addPipelineEnvVars(run, envVars);\n\n        FilePath virtualenvWorkspace;\n        try {\n            virtualenvWorkspace = getVirtualenvWorkspace(run, workspace, logger);\n        } catch (Exception ex) {\n            logger.println(\"[ERROR] Performance test: \" + ex.getMessage());\n            run.setResult(Result.FAILURE);\n            return;\n        }\n\n        boolean isVirtualenvInstallation = false;\n        if ((!alwaysUseVirtualenv && isGlobalBztInstalled(workspace, logger, launcher, envVars)) ||\n                (isVirtualenvInstallation = installBztAndCheck(virtualenvWorkspace, logger, launcher, envVars))) {\n\n\n            FilePath bztWorkingDirectory = getBztWorkingDirectory(workspace);\n            try {\n                bztWorkingDirectory.mkdirs();\n            } catch (IOException ex) {\n                logger.println(\"Performance test: Cannot create working directory because of error: \" + ex.getMessage());\n                run.setResult(Result.FAILURE);\n                return;\n            }\n\n            int testExitCode = runPerformanceTest(bztWorkingDirectory, virtualenvWorkspace, logger, launcher, envVars, isVirtualenvInstallation);\n\n            run.setResult(useBztExitCode ?\n                    getBztJobResult(testExitCode) :\n                    getJobResult(testExitCode)\n            );\n            Result result = run.getResult();\n            if (generatePerformanceTrend && result != null && Result.FAILURE.isWorseThan(result)) {\n                generatePerformanceTrend(bztWorkingDirectory.getRemote(), run, workspace, launcher, listener);\n            }\n\n            return;\n        }\n\n        run.setResult(Result.FAILURE);\n    }\n\n    private void addPipelineEnvVars(Run<?, ?> run, EnvVars envVars) {\n        if (run.getClass().getCanonicalName().startsWith(\"org.jenkinsci.plugins.workflow\")) {\n            List<? extends Action> allActions = run.getAllActions();\n            if (!allActions.isEmpty()) {\n                for (Action action : allActions) {\n                    if (\"org.jenkinsci.plugins.workflow.cps.EnvActionImpl\".equals(action.getClass().getCanonicalName())) {\n                        addEnvVars(action, envVars);\n                    }\n                }\n            }\n        }\n    }\n\n    private void addEnvVars(Action action, EnvVars envVars) {\n        try {\n            Class<? extends Action> actionClass = action.getClass();\n            Method method = actionClass.getMethod(\"getOverriddenEnvironment\");\n            Map<String, String> map = (Map<String, String>) method.invoke(action);\n            envVars.overrideAll(map);\n        } catch (Throwable ex) {\n            LOGGER.warning(\"Failed to add envVars from action: \" + action.getClass());\n        }\n    }\n\n    private FilePath getVirtualenvWorkspace(Run<?, ?> run, FilePath workspace, PrintStream logger) throws Exception {\n        return workspace.getRemote().contains(\" \") ?\n                createTemporaryWorkspace(run, workspace, logger) :\n                workspace;\n    }\n\n    private FilePath createTemporaryWorkspace(Run<?, ?> run, FilePath workspace, PrintStream logger) throws Exception {\n        logger.println(\"[WARNING] Performance test: Job workspace contains spaces in path. Virtualenv does not support such path. Creating temporary workspace for virtualenv.\");\n        File baseTmpDir = new File(System.getProperty(\"java.io.tmpdir\"));\n        if (baseTmpDir.getAbsolutePath().contains(\" \")) {\n            logger.println(\"[WARNING] Performance test: Temporary folder contains spaces in path.\");\n            throw new InvalidPathException(baseTmpDir.getAbsolutePath(), \"Virtualenv cannot be installed in workspace that contains spaces in path.\");\n        }\n        File tempDir = new File(baseTmpDir.getAbsolutePath(), \"perf-test-virtualenv-workspace-\" + configJobName(run.getParent().getName()));\n        FilePath tempWorkspace = new FilePath(workspace.getChannel(), tempDir.getAbsolutePath());\n        tempWorkspace.mkdirs();\n        return tempWorkspace;\n    }\n\n    private String configJobName(String displayName) {\n        return displayName.replaceAll(\" \", \"-\");\n    }\n\n    protected FilePath getBztWorkingDirectory(FilePath jobWorkspace) {\n        return (workingDirectory != null && !workingDirectory.isEmpty()) ?\n                (isAbsoluteFilePath() ?\n                        // absolute workspace\n                        new FilePath(jobWorkspace.getChannel(), workingDirectory) :\n                        //relative workspace\n                        new FilePath(jobWorkspace, workingDirectory)\n                ) :\n                jobWorkspace;\n    }\n\n    private boolean isAbsoluteFilePath() {\n        return new File(workingDirectory).isAbsolute();\n    }\n\n    protected void generatePerformanceTrend(String path, Run<?, ?> run, FilePath workspace, Launcher launcher, TaskListener listener) throws IOException, InterruptedException {\n        new PerformancePublisher(path + \"/aggregate-results.xml\", -1, -1, \"\", 0, 0, 0, 0, 0, false, \"\", false, false, false, false,true, null).\n                perform(run, workspace, launcher, listener);\n    }\n\n    private boolean installBztAndCheck(FilePath workspace, PrintStream logger, Launcher launcher, EnvVars envVars) throws InterruptedException, IOException {\n        return installBzt(workspace, logger, launcher, envVars) &&\n                isVirtualenvBztInstalled(workspace, logger, launcher, envVars);\n    }\n\n    private boolean installBzt(FilePath workspace, PrintStream logger, Launcher launcher, EnvVars envVars) throws InterruptedException, IOException {\n        return isVirtualenvInstalled(workspace, logger, launcher, envVars) &&\n                createVirtualenvAndInstallBzt(workspace, logger, launcher, envVars);\n    }\n\n    private boolean createVirtualenvAndInstallBzt(FilePath workspace, PrintStream logger, Launcher launcher, EnvVars envVars) throws InterruptedException, IOException {\n        return createIsolatedPython(workspace, logger, launcher, envVars) &&\n                installBztInVirtualenv(workspace, logger, launcher, envVars);\n    }\n\n    // Step 1.1: Check bzt using \"bzt --help\".\n    private boolean isGlobalBztInstalled(FilePath workspace, PrintStream logger, Launcher launcher, EnvVars envVars) throws InterruptedException, IOException {\n        logger.println(\"Performance test: Checking global bzt installation...\");\n        boolean result = isSuccessCode(runCmd(CHECK_BZT_COMMAND, workspace, NullOutputStream.NULL_OUTPUT_STREAM, launcher, envVars));\n        logger.println(result ?\n                \"Performance test: Found global bzt installation.\" :\n                \"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.\"\n        );\n        return result;\n    }\n\n    // Step 1.2: If bzt not installed check virtualenv using \"virtualenv --help\".\n    private boolean isVirtualenvInstalled(FilePath workspace, PrintStream logger, Launcher launcher, EnvVars envVars) throws InterruptedException, IOException {\n        logger.println(\"Performance test: Checking virtualenv tool availability...\");\n        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();\n        boolean result = isSuccessCode(runCmd(CHECK_VIRTUALENV_COMMAND, workspace, outputStream, launcher, envVars));\n        logger.println(result ?\n                \"Performance test: Found virtualenv tool.\" :\n                \"Performance test: No virtualenv found on this Jenkins host. Install it with 'sudo pip install virtualenv'.\"\n        );\n        if (!result || printDebugOutput) {\n            logger.write(outputStream.toByteArray());\n        }\n        return result;\n    }\n\n    // Step 1.3: Create local python using \"virtualenv --clear taurus-venv\".\n    private boolean createIsolatedPython(FilePath workspace, PrintStream logger, Launcher launcher, EnvVars envVars) throws InterruptedException, IOException {\n        logger.println(\"Performance test: Creating virtualev at 'taurus-venv'...\");\n        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();\n        boolean result = isSuccessCode(runCmd(useSystemSitePackages ?\n                        CREATE_LOCAL_PYTHON_COMMAND_WITH_SYSTEM_PACKAGES_OPTION :\n                        CREATE_LOCAL_PYTHON_COMMAND,\n                workspace, outputStream, launcher, envVars));\n        logger.println(result ?\n                \"Performance test: Done creating virtualenv.\" :\n                \"Performance test: Failed to create virtualenv at 'taurus-venv'\"\n        );\n        if (!result || printDebugOutput) {\n            logger.write(outputStream.toByteArray());\n        }\n        return result;\n    }\n\n    // Step 1.4: Install bzt in virtualenv using \"taurus-venv/bin/pip install bzt\".\n    private boolean installBztInVirtualenv(FilePath workspace, PrintStream logger, Launcher launcher, EnvVars envVars) throws InterruptedException, IOException {\n        logger.println(\"Performance test: Installing bzt into 'taurus-venv'\");\n        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();\n        boolean result = isSuccessCode(runCmd(getBztInstallCommand(workspace), workspace, outputStream, launcher, envVars));\n        logger.println(result ?\n                \"Performance test: bzt installed successfully.\" :\n                \"Performance test: Failed to install bzt into 'taurus-venv'\"\n        );\n        if (!result || printDebugOutput) {\n            logger.write(outputStream.toByteArray());\n        }\n        return result;\n    }\n\n    // Step 1.5: Check bzt using \"taurus-venv/bin/bzt --help\"\n    private boolean isVirtualenvBztInstalled(FilePath workspace, PrintStream logger, Launcher launcher, EnvVars envVars) throws InterruptedException, IOException {\n        logger.println(\"Performance test: Checking installed bzt...\");\n        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();\n        boolean result = isSuccessCode(runCmd(getBztCheckCommand(workspace), workspace, outputStream, launcher, envVars));\n        logger.println(result ?\n                \"Performance test: bzt is operational.\" :\n                \"Performance test: Failed to run bzt inside virtualenv.\"\n        );\n        if (!result || printDebugOutput) {\n            logger.write(outputStream.toByteArray());\n        }\n        return result;\n    }\n\n    // Step 2: Run performance test.\n    private int runPerformanceTest(FilePath bztWorkingDirectory, FilePath workspace, PrintStream logger, Launcher launcher, EnvVars envVars, boolean isVirtualenvInstallation) throws InterruptedException, IOException {\n        final List<String> testCommand = new ArrayList<>();\n\n        testCommand.add((isVirtualenvInstallation ? getVirtualenvPath(workspace) : \"\") + PERFORMANCE_TEST_COMMAND);\n        String[] parsedParams;\n        try {\n            parsedParams = CommandLineUtils.translateCommandline(envVars.expand(this.params));\n        } catch (Exception e) {\n            logger.println(\"Failed parse Taurus parameters\");\n            e.printStackTrace(logger);\n            return 1;\n        }\n\n        for (String param : parsedParams) {\n            if (!param.isEmpty()) {\n                testCommand.add(param);\n            }\n        }\n\n        if (generatePerformanceTrend) {\n            testCommand.add(extractDefaultReportToWorkingDirectory(bztWorkingDirectory));\n        }\n\n        logger.println(\"Performance test: run \" + Arrays.toString(testCommand.toArray()));\n        return runCmd(testCommand.toArray(new String[testCommand.size()]), bztWorkingDirectory, logger, launcher, envVars);\n    }\n\n    public boolean isSuccessCode(int code) {\n        return code == 0;\n    }\n\n    public Result getJobResult(int code) {\n        if (code == 0) {\n            return Result.SUCCESS;\n        } else {\n            return Result.FAILURE;\n        }\n    }\n\n\n    public Result getBztJobResult(int code) {\n        if (code == 0) {\n            return Result.SUCCESS;\n        } else if (code == 1) {\n            return Result.FAILURE;\n        } else {\n            return Result.UNSTABLE;\n        }\n    }\n\n    private String getVirtualenvPath(FilePath workspace) {\n        return workspace.getRemote() + (Functions.isWindows() ?\n                VIRTUALENV_PATH_WINDOWS :\n                VIRTUALENV_PATH_UNIX);\n    }\n\n    // return bzt install command\n    private String[] getBztInstallCommand(FilePath workspace) throws IOException, InterruptedException {\n        return new String[]{\n                getVirtualenvPath(workspace) + \"pip\", \"install\", getInstallCommand(workspace)};\n    }\n\n    private String getInstallCommand(FilePath workspace) throws IOException, InterruptedException {\n        if (bztVersion != null && !bztVersion.isEmpty()) {\n            return (isPathToFile(workspace) || isURLToFile()) ?\n                    bztVersion :\n                    (PERFORMANCE_TEST_COMMAND + \"==\" + bztVersion);\n        } else {\n            return PERFORMANCE_TEST_COMMAND;\n        }\n    }\n\n    private boolean isURLToFile() {\n        try {\n            if (bztVersion.startsWith(\"git+\")) {\n                new URL(bztVersion.substring(4));\n            } else {\n                new URL(bztVersion);\n            }\n            return true;\n        } catch (MalformedURLException e) {\n            return false;\n        }\n    }\n\n    private boolean isPathToFile(FilePath workspace) throws IOException, InterruptedException {\n        return new FilePath(workspace.getChannel(), bztVersion).exists();\n    }\n\n    // return bzt check command\n    private String[] getBztCheckCommand(FilePath workspace) {\n        return new String[]{getVirtualenvPath(workspace) + \"bzt\", HELP_OPTION};\n    }\n\n    private String getVirtualEnvCommand(EnvVars envVars) {\n        return virtualEnvCommand == null || virtualEnvCommand.trim().isEmpty() ? VIRTUALENV_COMMAND : envVars.expand(virtualEnvCommand);\n    }\n\n    public int runCmd(String[] commands, FilePath workspace, OutputStream logger, Launcher launcher, EnvVars envVars) throws InterruptedException, IOException {\n        if (commands[0].equals(VIRTUALENV_COMMAND)) {\n            commands[0] = getVirtualEnvCommand(envVars);\n        }\n        try {\n            return launcher.launch().cmds(commands).envs(envVars).stdout(logger).stderr(logger).pwd(workspace).start().join();\n        } catch (IOException ex) {\n            logger.write(ex.getMessage().getBytes(StandardCharsets.UTF_8));\n            if (printDebugOutput) {\n                logger.write(Functions.printThrowable(ex).getBytes(StandardCharsets.UTF_8));\n            }\n            return 1;\n        }\n    }\n\n    protected String extractDefaultReportToWorkingDirectory(FilePath workingDirectory) throws IOException, InterruptedException {\n        FilePath defaultConfig = workingDirectory.child(DEFAULT_CONFIG_FILE);\n        try (InputStream is = getClass().getResourceAsStream(DEFAULT_CONFIG_FILE)) {\n            assert is != null;\n            defaultConfig.copyFrom(is);\n        }\n        return defaultConfig.getRemote();\n    }\n\n    public String getParams() {\n        return params;\n    }\n\n    public void setParams(String params) {\n        this.params = params;\n    }\n\n    public boolean isPrintDebugOutput() {\n        return printDebugOutput;\n    }\n\n    public boolean isAlwaysUseVirtualenv() {\n        return alwaysUseVirtualenv;\n    }\n\n    @DataBoundSetter\n    public void setAlwaysUseVirtualenv(boolean alwaysUseVirtualenv) {\n        this.alwaysUseVirtualenv = alwaysUseVirtualenv;\n    }\n\n    @DataBoundSetter\n    public void setPrintDebugOutput(boolean printDebugOutput) {\n        this.printDebugOutput = printDebugOutput;\n    }\n\n    public boolean isUseSystemSitePackages() {\n        return useSystemSitePackages;\n    }\n\n    @DataBoundSetter\n    public void setUseSystemSitePackages(boolean useSystemSitePackages) {\n        this.useSystemSitePackages = useSystemSitePackages;\n    }\n\n    public boolean isGeneratePerformanceTrend() {\n        return generatePerformanceTrend;\n    }\n\n    @DataBoundSetter\n    public void setGeneratePerformanceTrend(boolean generatePerformanceTrend) {\n        this.generatePerformanceTrend = generatePerformanceTrend;\n    }\n\n    public boolean isUseBztExitCode() {\n        return useBztExitCode;\n    }\n\n    @DataBoundSetter\n    public void setUseBztExitCode(boolean useBztExitCode) {\n        this.useBztExitCode = useBztExitCode;\n    }\n\n    public String getWorkspace() {\n        return workspace;\n    }\n\n    @DataBoundSetter\n    public void setWorkspace(String workspace) {\n        this.workspace = workspace;\n        readResolve();\n    }\n\n    public String getBztVersion() {\n        return bztVersion;\n    }\n\n    @DataBoundSetter\n    public void setBztVersion(String bztVersion) {\n        this.bztVersion = bztVersion;\n    }\n\n    public String getWorkingDirectory() {\n        return workingDirectory;\n    }\n\n    @DataBoundSetter\n    public void setWorkingDirectory(String workingDirectory) {\n        this.workingDirectory = workingDirectory;\n    }\n\n    public String getVirtualEnvCommand() {\n        return virtualEnvCommand;\n    }\n\n    @DataBoundSetter\n    public void setVirtualEnvCommand(String virtualEnvCommand) {\n        this.virtualEnvCommand = virtualEnvCommand;\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/constraints/AbsoluteConstraint.java",
    "content": "package hudson.plugins.performance.constraints;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.List;\n\nimport hudson.AbortException;\nimport hudson.Extension;\nimport hudson.model.Run;\nimport hudson.plugins.performance.actions.PerformanceBuildAction;\nimport hudson.plugins.performance.constraints.blocks.TestCaseBlock;\nimport hudson.plugins.performance.descriptors.ConstraintDescriptor;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.reports.UriReport;\nimport hudson.util.FormValidation;\n\nimport edu.umd.cs.findbugs.annotations.SuppressFBWarnings;\nimport org.jenkinsci.Symbol;\nimport org.kohsuke.stapler.DataBoundConstructor;\nimport org.kohsuke.stapler.QueryParameter;\n\n/**\n * Absolute Constraints compare the result of a new load test against some user defined values.\n *\n * @author Rene Kugel\n */\npublic class AbsoluteConstraint extends AbstractConstraint {\n\n    /**\n     * User defined absolute value which must not be exceeded\n     */\n    private long value = 0;\n\n    @Symbol(\"absolute\")\n    @Extension\n    public static class DescriptorImpl extends ConstraintDescriptor {\n\n        @Override\n        public String getDisplayName() {\n            return \"Absolute Constraint\";\n        }\n\n        public FormValidation doCheckRelatedPerfReport(@QueryParameter String relatedPerfReport) {\n            if (relatedPerfReport == null || relatedPerfReport.isEmpty()) {\n                return FormValidation.error(\"This field must not be empty\");\n            }\n            return FormValidation.ok();\n        }\n\n        public FormValidation doCheckTestCase(@QueryParameter String testCase) {\n            if (testCase == null || testCase.isEmpty()) {\n                return FormValidation.error(\"This field must not be empty\");\n            }\n            return FormValidation.ok();\n        }\n    }\n\n\n    @DataBoundConstructor\n    public AbsoluteConstraint(Metric meteredValue, Operator operator, String relatedPerfReport, Escalation escalationLevel, boolean success, TestCaseBlock testCaseBlock, long value) {\n        super(meteredValue, operator, relatedPerfReport, escalationLevel, success, testCaseBlock);\n        this.value = value;\n\n    }\n\n    /**\n     * Cloning of a AbsoluteConstraint Note that this is not from the Interface Clonable\n     *\n     * @return clone of this object\n     */\n    @SuppressFBWarnings(\"CN_IMPLEMENTS_CLONE_BUT_NOT_CLONEABLE\")\n    public AbsoluteConstraint clone() {\n        return new AbsoluteConstraint(this.getMeteredValue(), this.getOperator(), \n                this.getRelatedPerfReport(), this.getEscalationLevel(), \n                this.getSuccess(), \n                new TestCaseBlock(this.getTestCaseBlock().getTestCase()), \n                this.getValue());\n    }\n\n    @Override\n    public ConstraintEvaluation evaluate(List<? extends Run<?, ?>> builds) throws InvocationTargetException, AbortException {\n        if (builds.isEmpty()) {\n            throw new AbortException(\"Performance: No builds found to evaluate!\");\n        }\n        checkForDefectiveParams(builds);\n        PerformanceReport pr = builds.get(0).getAction(PerformanceBuildAction.class).getPerformanceReportMap().getPerformanceReport(getRelatedPerfReport());\n        // calculate the\n        double newValue = 0;\n        if (!isSpecifiedTestCase()) {\n            newValue = checkMetredValueforPerfReport(getMeteredValue(), pr);\n        } else {\n            List<UriReport> uriList = pr.getUriListOrdered();\n            for (UriReport ur : uriList) {\n                if (getTestCaseBlock().getTestCase().equals(ur.getUri())) {\n                    newValue = checkMetredValueforUriReport(getMeteredValue(), ur);\n                    break;\n                }\n            }\n        }\n        return check(newValue);\n    }\n\n    /**\n     * Compares the values and sets the success and a result message of a constraint.\n     *\n     * @param newValue measured value of a specified metric of the newly created test\n     * @return evaluated constraint\n     */\n    private ConstraintEvaluation check(double newValue) {\n        switch (getOperator()) {\n            case NOT_LESS:\n                setSuccess(newValue >= getValue());\n                break;\n            case NOT_GREATER:\n                setSuccess(newValue <= getValue());\n                break;\n            case NOT_EQUAL:\n                setSuccess(newValue != getValue());\n                break;\n            default:\n                break;\n        }\n\n        ConstraintEvaluation evaluation = new ConstraintEvaluation(this, getValue(), newValue);\n\n        String measuredLevel = isSpecifiedTestCase() ? getTestCaseBlock().getTestCase() : \"all test cases\";\n        if (getSuccess()) {\n            setResultMessage(\"Absolute constraint successful! - Report: \" + getRelatedPerfReport() + \" \\n\" + \"The constraint says: \" + getMeteredValue() + \" of \" + measuredLevel + \" must \"\n                    + getOperator().text + \" \" + getValue() + \"\\n\" + \"Measured value for \" + getMeteredValue() + \": \" + newValue + \"\\n\" + \"Escalation Level: \" + getEscalationLevel());\n        } else {\n            setResultMessage(\"Absolute constraint failed! - Report: \" + getRelatedPerfReport() + \" \\n\" + \"The constraint says: \" + getMeteredValue() + \" of \" + measuredLevel + \" must \"\n                    + getOperator().text + \" \" + getValue() + \"\\n\" + \"Measured value for \" + getMeteredValue() + \": \" + newValue + \"\\n\" + \"Escalation Level: \" + getEscalationLevel());\n        }\n\n        String unit = getMeteredValue()==Metric.ERRORPRC ? \"percent\" : \"milliseconds\";\n        setJunitResult(String.format(\"<testcase classname=\\\"%s\\\" name=\\\"%s of %s must %s %d %s\\\">%n\", \n            getRelatedPerfReport(), getMeteredValue(), measuredLevel, getOperator().text, getValue(), unit)\n            + (getSuccess() ? \"\" :\n                String.format(\"    <failure type=\\\"%s\\\">Measured value for %s: %.0f %s</failure>%n\",\n                getEscalationLevel(), getMeteredValue(), newValue, unit))\n            + \"</testcase>\\n\");\n\n        return evaluation;\n    }\n\n    public long getValue() {\n        return value;\n    }\n\n    public void setValue(long value) {\n        this.value = value;\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/constraints/AbstractConstraint.java",
    "content": "package hudson.plugins.performance.constraints;\n\nimport hudson.AbortException;\nimport hudson.ExtensionList;\nimport hudson.ExtensionPoint;\nimport hudson.model.Describable;\nimport hudson.model.Run;\nimport hudson.plugins.performance.actions.PerformanceBuildAction;\nimport hudson.plugins.performance.constraints.blocks.TestCaseBlock;\nimport hudson.plugins.performance.data.ConstraintSettings;\nimport hudson.plugins.performance.descriptors.ConstraintDescriptor;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.reports.UriReport;\nimport jenkins.model.Jenkins;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.text.ParseException;\nimport java.text.SimpleDateFormat;\nimport java.util.List;\n\n/**\n * Parent class for AbsoluteConstraint and RelativeConstraint\n *\n * @author Rene Kugel\n */\npublic abstract class AbstractConstraint implements Describable<AbstractConstraint>, ExtensionPoint {\n    public static final String ANY = \"*\";\n    protected static final String NOW = \"now\";\n    /**\n     * Holds the information whether constraint is fulfilled(true) or violated(false)\n     */\n    private boolean success = false;\n    /**\n     * True if constraint refers to a test case False if constraint refers to a whole report\n     */\n    private boolean isSpecifiedTestCase = false;\n    /**\n     * Metric which should be evaluated\n     */\n    private Metric meteredValue;\n    /**\n     * Operator which is used to compare values\n     */\n    private Operator operator;\n    /**\n     * Determines the build result if constraint is violated\n     */\n    private Escalation escalationLevel;\n    /**\n     * Holds relevant information about the evaluation\n     */\n    private String resultMessage = \"\";\n    /**\n     * Holds relevant information about the evaluation in Junit format\n     */\n    private String junitResult = \"\";\n    /**\n     * The report file the constraint refers to\n     */\n    private String relatedPerfReport;\n    /**\n     * null if isSpecifiedTestCase == false Holds the test case if isSpecifiedTestCase == true\n     */\n    private TestCaseBlock testCaseBlock;\n    /**\n     * Reference for global constraint settings\n     */\n    private ConstraintSettings settings;\n\n    public ConstraintDescriptor getDescriptor() {\n        return (ConstraintDescriptor) Jenkins.get().getDescriptorOrDie(getClass());\n    }\n\n    public static ExtensionList<AbstractConstraint> all() {\n        return Jenkins.get().getExtensionList(AbstractConstraint.class);\n    }\n\n    protected AbstractConstraint(Metric meteredValue, Operator operator, String relatedPerfReport, Escalation escalationLevel, boolean success, TestCaseBlock testCaseBlock) {\n        this.relatedPerfReport = relatedPerfReport;\n        this.success = success;\n        this.meteredValue = meteredValue;\n        this.operator = operator;\n        this.escalationLevel = escalationLevel;\n        if (testCaseBlock != null) {\n            this.setSpecifiedTestCase(true);\n            this.testCaseBlock = testCaseBlock;\n        } else {\n            this.setSpecifiedTestCase(false);\n        }\n    }\n\n    /**\n     * Cloning of a constraint Note that this is not from the Interface Clonable {@inheritDoc}\n     */\n    public abstract AbstractConstraint clone();\n\n    /**\n     * Evaluates whether the constraint is fulfilled or violated\n     *\n     * @param builds all builds that are saved in Jenkins\n     * @return\n     * @throws IllegalArgumentException\n     * @throws IllegalAccessException\n     * @throws InvocationTargetException\n     * @throws AbortException\n     * @throws ParseException\n     */\n    public abstract ConstraintEvaluation evaluate(List<? extends Run<?, ?>> builds) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, AbortException,\n            ParseException;\n\n    /**\n     * Grabs a specified Metric in a specified UriReport\n     *\n     * @param meteredValue the metric that should be evaluated\n     * @param ur           the UriReport where the metric should be measured\n     * @return the value of the specified metric in the specified UriReport\n     */\n    protected double checkMetredValueforUriReport(Metric meteredValue, UriReport ur) {\n        switch (meteredValue) {\n            case ERRORPRC:\n                return ur.errorPercent();\n            case AVERAGE:\n                return (double) ur.getAverage();\n            case LINE90:\n                return (double) ur.get90Line();\n            case LINE95:\n                return (double) ur.get95Line();\n            case MEDIAN:\n                return (double) ur.getMedian();\n            case MINIMUM:\n                return (double) ur.getMin();\n            case MAXIMUM:\n                return (double) ur.getMax();\n            default:\n                return (double) ur.getAverage();\n        }\n    }\n\n    /**\n     * Grabs a specified Metric in a specified PerformanceReport\n     *\n     * @param meteredValue the metric that should be evaluated\n     * @param pr           the PerformanceReport where the metric should be measured\n     * @return the value of the specified metric in the specified PerformanceReport\n     */\n    protected double checkMetredValueforPerfReport(Metric meteredValue, PerformanceReport pr) {\n        switch (meteredValue) {\n            case ERRORPRC:\n                return pr.errorPercent();\n            case AVERAGE:\n                return (double) pr.getAverage();\n            case LINE90:\n                return (double) pr.get90Line();\n            case LINE95:\n                return (double) pr.get95Line();\n            case MEDIAN:\n                return (double) pr.getMedian();\n            case MINIMUM:\n                return (double) pr.getMin();\n            case MAXIMUM:\n                return (double) pr.getMax();\n            default:\n                return (double) pr.getAverage();\n        }\n    }\n\n    /**\n     * Checks whether all parameters given in the UI are processable.\n     *\n     * @param builds all stored jenkins builds\n     * @throws AbortException if a parameter in the UI is not processable\n     */\n    protected void checkForDefectiveParams(List<? extends Run<?, ?>> builds) throws AbortException {\n        boolean found = false;\n\n        if (builds.get(0).getAction(PerformanceBuildAction.class).getPerformanceReportMap().getPerformanceReport(getRelatedPerfReport()) == null) {\n            throw new AbortException(\"Performance Plugin: Could't find a report specified in the performance constraints! Report: \\\"\" + getRelatedPerfReport() + \"\\\"\");\n        } else {\n            PerformanceReport pr = builds.get(0).getAction(PerformanceBuildAction.class).getPerformanceReportMap().getPerformanceReport(getRelatedPerfReport());\n            if (isSpecifiedTestCase()) {\n                for (UriReport ur : pr.getUriListOrdered()) {\n                    if (ur.getUri().equals(getTestCaseBlock().getTestCase())) {\n                        found = true;\n                    }\n                }\n                if (!found) {\n                    throw new AbortException(\"Performance Plugin: Could't find a test case specified in the performance constraints! TestCase: \\\"\" + getTestCaseBlock().getTestCase() + \"\\\" Report: \\\"\"\n                            + getRelatedPerfReport() + \"\\\"\");\n                }\n            }\n        }\n        if (this instanceof AbsoluteConstraint) {\n            AbsoluteConstraint ac = (AbsoluteConstraint) this;\n            if (ac.getValue() < 0) {\n                throw new AbortException(\"Performance Plugin: The value of a Absolute Constraint can't be negative!\");\n            }\n        }\n        if (this instanceof RelativeConstraint) {\n            RelativeConstraint rc = (RelativeConstraint) this;\n            if (rc.getTolerance() < 0) {\n                throw new AbortException(\"Performance Plugin: The tolerance of a Relative Constraint can't be negative!\");\n            }\n            if (rc.getTimeframeStart().after(rc.getTimeframeEnd())) {\n                throw new AbortException(\"Performance Plugin: The start date of a Relative Constraint can't be after the end date\");\n            }\n            if (rc.getPreviousResultsBlock().isChoiceTimeframe()) {\n                final SimpleDateFormat dfLong = new SimpleDateFormat(\"yyyy-MM-dd HH:mm\");\n                try {\n                    rc.setTimeframeStart(dfLong.parse(rc.getTimeframeStartString()));\n                    if (!NOW.equals(rc.getTimeframeEndString())) {\n                        rc.setTimeframeEnd(dfLong.parse(rc.getTimeframeEndString()));\n                    }\n                } catch (ParseException e) {\n                    throw new AbortException(\"Performance Plugin: Couldn't parse date in Relative Constraint! Please check the configuration of your constraints\");\n                }\n            }\n        }\n    }\n\n    public enum Metric {\n        AVERAGE(\"Average\", false), MEDIAN(\"Median\", false), LINE90(\"90% Line\", false), LINE95(\"95% Line\", false), MAXIMUM(\"Maximum\", false), MINIMUM(\"Minimum\", false), ERRORPRC(\"Error %\", false);\n\n        private final String text;\n        private final boolean isSelected;\n\n        private Metric(final String text, boolean isSelected) {\n            this.text = text;\n            this.isSelected = isSelected;\n        }\n\n        @Override\n        public String toString() {\n            return text;\n        }\n\n        public boolean isSelected() {\n            return isSelected;\n        }\n\n    }\n\n    public enum Escalation {\n        INFORMATION(\"Information\", false), WARNING(\"Warning\", false), ERROR(\"Error\", false);\n\n        private final String text;\n        private final boolean isSelected;\n\n        private Escalation(final String text, boolean isSelected) {\n            this.text = text;\n            this.isSelected = isSelected;\n        }\n\n        @Override\n        public String toString() {\n            return text;\n        }\n\n        public boolean isSelected() {\n            return isSelected;\n        }\n\n    }\n\n    public enum Operator {\n        NOT_GREATER(\"not be greater than\", false), NOT_LESS(\"not be less than\", false), NOT_EQUAL(\"not be equal to\", false);\n\n        public final String text;\n        private final boolean isSelected;\n\n        private Operator(final String text, boolean isSelected) {\n            this.text = text;\n            this.isSelected = isSelected;\n        }\n\n        @Override\n        public String toString() {\n            return text;\n        }\n\n        public boolean isSelected() {\n            return isSelected;\n        }\n\n    }\n\n    public void setSuccess(boolean success) {\n        this.success = success;\n    }\n\n    public boolean getSuccess() {\n        return this.success;\n    }\n\n    public String getResultMessage() {\n        return resultMessage;\n    }\n\n    public void setResultMessage(String resultMessage) {\n        this.resultMessage = resultMessage;\n    }\n\n    public String getJunitResult() {\n        return junitResult;\n    }\n\n    public void setJunitResult(String junitResult) {\n        this.junitResult = junitResult;\n    }\n\n    public String getRelatedPerfReport() {\n        return relatedPerfReport;\n    }\n\n    public void setRelatedPerfReport(String relatedPerfReport) {\n        this.relatedPerfReport = relatedPerfReport;\n    }\n\n    public Metric getMeteredValue() {\n        return meteredValue;\n    }\n\n    public void setMeteredValue(Metric meteredValue) {\n        this.meteredValue = meteredValue;\n    }\n\n    public Operator getOperator() {\n        return operator;\n    }\n\n    public void setOperator(Operator operator) {\n        this.operator = operator;\n    }\n\n    public Escalation getEscalationLevel() {\n        return escalationLevel;\n    }\n\n    public void setEscalationLevel(Escalation escalationLevel) {\n        this.escalationLevel = escalationLevel;\n    }\n\n    public TestCaseBlock getTestCaseBlock() {\n        return testCaseBlock;\n    }\n\n    public void setTestCaseBlock(TestCaseBlock testCaseBlock) {\n        this.testCaseBlock = testCaseBlock;\n    }\n\n    public boolean isSpecifiedTestCase() {\n        return isSpecifiedTestCase;\n    }\n\n    public void setSpecifiedTestCase(boolean isSpecifiedTestCase) {\n        this.isSpecifiedTestCase = isSpecifiedTestCase;\n    }\n\n    public ConstraintSettings getSettings() {\n        return settings;\n    }\n\n    public void setSettings(ConstraintSettings settings) {\n        this.settings = settings;\n    }\n\n    public String getTestCase() {\n        if (getTestCaseBlock() != null) {\n            return getTestCaseBlock().getTestCase();\n        } else {\n            return null;\n        }\n    }\n\n    public void setTestCase(String testCase) {\n        this.getTestCaseBlock().setTestCase(testCase);\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/constraints/ConstraintChecker.java",
    "content": "package hudson.plugins.performance.constraints;\n\nimport hudson.AbortException;\nimport hudson.model.Run;\nimport hudson.plugins.performance.data.ConstraintSettings;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.text.ParseException;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Checks whether a list of constraints is fulfilled or violated\n *\n * @author Rene Kugel\n */\npublic class ConstraintChecker {\n\n    /**\n     * All builds that are saved in Jenkins\n     */\n    private List<? extends Run<?, ?>> builds;\n    /**\n     * Global constraint settings\n     */\n    private ConstraintSettings settings;\n\n    public ConstraintChecker(ConstraintSettings settings, List<? extends Run<?, ?>> builds) {\n        this.settings = settings;\n        this.builds = builds;\n    }\n\n    /**\n     * Evaluates a list of constraints defined by the user in the UI\n     *\n     * @param constraints constraints defined by the user\n     * @return ArrayList of evaluated constraints\n     * @throws AbortException\n     * @throws SecurityException\n     * @throws NoSuchMethodException\n     * @throws IllegalArgumentException\n     * @throws IllegalAccessException\n     * @throws InvocationTargetException\n     * @throws ParseException\n     */\n    public ArrayList<ConstraintEvaluation> checkAllConstraints(List<? extends AbstractConstraint> constraints) throws AbortException, SecurityException, NoSuchMethodException,\n            IllegalArgumentException, IllegalAccessException, InvocationTargetException, ParseException {\n        ArrayList<ConstraintEvaluation> result = new ArrayList<ConstraintEvaluation>();\n        for (AbstractConstraint c : constraints) {\n            c.setSettings(settings);\n            try {\n                result.add(c.evaluate(builds));\n            } catch (Exception e) {\n                settings.getListener().getLogger().println(e.getMessage());\n            }\n\n        }\n        return result;\n    }\n\n    public ConstraintSettings getSettings() {\n        return settings;\n    }\n\n    public void setSettings(ConstraintSettings settings) {\n        this.settings = settings;\n    }\n\n    public List<? extends Run<?, ?>> getBuilds() {\n        return builds;\n    }\n\n    public void setBuilds(List<? extends Run<?, ?>> builds) {\n        this.builds = builds;\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/constraints/ConstraintEvaluation.java",
    "content": "package hudson.plugins.performance.constraints;\n\n/**\n * Holds the values of a evaluated constraint.\n *\n * @author Rene Kugel\n */\npublic class ConstraintEvaluation {\n\n    private AbstractConstraint abstractConstraint;\n    private double constraintValue;\n    private double measuredValue;\n\n    public ConstraintEvaluation(AbstractConstraint constraint, double result, double calculatedValue) {\n        this.abstractConstraint = constraint;\n        this.constraintValue = result;\n        this.measuredValue = calculatedValue;\n    }\n\n    public ConstraintEvaluation() {\n    }\n\n    public double getConstraintValue() {\n        return constraintValue;\n    }\n\n    public void setConstraintValue(double constraintValue) {\n        this.constraintValue = constraintValue;\n    }\n\n    public double getMeasuredValue() {\n        return measuredValue;\n    }\n\n    public void setMeasuredValue(double measuredValue) {\n        this.measuredValue = measuredValue;\n    }\n\n    public AbstractConstraint getAbstractConstraint() {\n        return abstractConstraint;\n    }\n\n    public void setAbstractConstraint(AbstractConstraint abstractConstraint) {\n        this.abstractConstraint = abstractConstraint;\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/constraints/ConstraintFactory.java",
    "content": "package hudson.plugins.performance.constraints;\n\nimport hudson.model.Run;\nimport hudson.plugins.performance.actions.PerformanceBuildAction;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.reports.UriReport;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\n/**\n * Evaluates the entries in the testCase field if test cases are specified and create clones of the\n * constraint for every given test case There are two possibilities: 1. In the testCase field a\n * comma seperated list of test cases is given 2. A '*' is given\n *\n * @author Rene Kugel\n */\npublic class ConstraintFactory {\n\n    /**\n     * Creates clones of a constraint if there is more than one test case specified in the UI\n     *\n     * @param build       all builds that are saved in Jenkins\n     * @param constraints all constraints defined in the UI\n     * @return list of all constraint clones that will get evaluated\n     */\n    public List<? extends AbstractConstraint> createConstraintClones(Run<?, ?> build, List<? extends AbstractConstraint> constraints) {\n        /*\n\t\t * Checking the test case field and handle comma separated lists and wildcard\n\t\t */\n        List<AbstractConstraint> createdConstraints = new ArrayList<>();\n        for (AbstractConstraint c : constraints) {\n            List<String> testCases = new ArrayList<>();\n            if (c.isSpecifiedTestCase()) {\n                String testCase = c.getTestCaseBlock().getTestCase();\n                if (AbstractConstraint.ANY.equals(testCase)) {\n                    PerformanceReport pr = build.getAction(PerformanceBuildAction.class).getPerformanceReportMap().getPerformanceReport(c.getRelatedPerfReport());\n                    for (UriReport ur : pr.getUriListOrdered()) {\n                        testCases.add(ur.getUri());\n                    }\n                } else {\n                    String[] tmpTestCases = testCase.split(\",\");\n                    String[] trimmedTestCases = new String[tmpTestCases.length];\n                    for (int i = 0; i < tmpTestCases.length; i++) {\n                        trimmedTestCases[i] = tmpTestCases[i].trim();\n                    }\n                    testCases = Arrays.asList(trimmedTestCases);\n                }\n\t\t\t\t/*\n\t\t\t\t * Creating clones based on the test cases\n\t\t\t\t */\n                for (String s : testCases) {\n                    AbstractConstraint constraint = c.clone();\n                    constraint.getTestCaseBlock().setTestCase(s);\n                    createdConstraints.add(constraint);\n                }\n            } else {\n                createdConstraints.add(c);\n            }\n        }\n        return createdConstraints;\n    }\n}"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/constraints/RelativeConstraint.java",
    "content": "package hudson.plugins.performance.constraints;\n\nimport java.io.PrintStream;\nimport java.text.ParseException;\nimport java.text.SimpleDateFormat;\nimport java.util.*;\n\nimport edu.umd.cs.findbugs.annotations.SuppressFBWarnings;\nimport org.jenkinsci.Symbol;\nimport org.kohsuke.stapler.AncestorInPath;\nimport org.kohsuke.stapler.DataBoundConstructor;\nimport org.kohsuke.stapler.QueryParameter;\n\nimport hudson.AbortException;\nimport hudson.Extension;\nimport hudson.model.AbstractProject;\nimport hudson.model.FreeStyleBuild;\nimport hudson.model.Result;\nimport hudson.model.Run;\nimport hudson.plugins.performance.PerformancePublisher;\nimport hudson.plugins.performance.actions.PerformanceBuildAction;\nimport hudson.plugins.performance.constraints.blocks.PreviousResultsBlock;\nimport hudson.plugins.performance.constraints.blocks.TestCaseBlock;\nimport hudson.plugins.performance.descriptors.ConstraintDescriptor;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.reports.UriReport;\nimport hudson.plugins.performance.tools.SafeMaths;\nimport hudson.tasks.Publisher;\nimport hudson.util.FormValidation;\nimport hudson.util.RunList;\n\n/**\n * Compares new load test results with 1 or more load test results in the past in a dynamically\n * manner.\n *\n * @author Rene Kugel\n */\npublic class RelativeConstraint extends AbstractConstraint {\n    /**\n     * Percentage value of the tolerance\n     */\n    private double tolerance = 0;\n    /**\n     * True: relative constraint includes a user defined number of builds into the evaluation False:\n     * relative constraint includes all builds that have taken place in an user defined time frame\n     */\n    private boolean choicePreviousResults = true;\n\n    /**\n     * Start of the time frame (for internal use)\n     */\n    private Date timeframeStart = new Date();\n    /**\n     * End of the time frame (for internal use)\n     */\n    private Date timeframeEnd = new Date();\n    /**\n     * Holds the relevant information to determine which builds get included into the evaluation\n     */\n    private PreviousResultsBlock previousResultsBlock;\n    /**\n     * Start of the time frame (for UI use)\n     */\n    private String timeframeStartString = \"\";\n    /**\n     * End of the time frame (for UI use)\n     */\n    private String timeframeEndString = \"\";\n    /**\n     * Holds the user defined number of builds which are to include to the evaluation (for internal\n     * use)\n     */\n    private int previousResults = 0;\n    /**\n     * Holds the user defined number of builds which are to include to the evaluation (for UI use)\n     */\n    private String previousResultsString = \"\";\n\n    @Symbol(\"relative\")\n    @Extension\n    public static class DescriptorImpl extends ConstraintDescriptor {\n\n        @Override\n        public String getDisplayName() {\n            return \"Relative Constraint\";\n        }\n\n\n        public FormValidation doCheckRelatedPerfReport(@QueryParameter String relatedPerfReport) {\n            if (relatedPerfReport == null || relatedPerfReport.isEmpty()) {\n                return FormValidation.error(\"This field must not be empty\");\n            }\n            return FormValidation.ok();\n        }\n\n        public FormValidation doCheckTestCase(@QueryParameter String testCase) {\n            if (testCase == null || testCase.isEmpty()) {\n                return FormValidation.error(\"This field must not be empty\");\n            }\n            return FormValidation.ok();\n        }\n\n        public FormValidation doCheckTimeframeStartString(@QueryParameter String timeframeStartString) {\n            return dateCheck(timeframeStartString);\n        }\n\n        public FormValidation doCheckTimeframeEndString(@QueryParameter String timeframeEndString) {\n            if (NOW.equals(timeframeEndString)) {\n                return FormValidation.ok();\n            }\n            return dateCheck(timeframeEndString);\n        }\n\n        private FormValidation dateCheck(String dateString) {\n            final SimpleDateFormat dfLong = new SimpleDateFormat(\"yyyy-MM-dd HH:mm\");\n            final SimpleDateFormat dfShort = new SimpleDateFormat(\"yyyy-MM-dd\");\n            dfLong.setLenient(false);\n            dfShort.setLenient(false);\n            try {\n                if (\n                        (dfShort.parse(dateString) != null && dateString.length() == 10) \n                        || (dfLong.parse(dateString) != null && dateString.length() == 16)) { \n                    return FormValidation.ok();\n                }\n            } catch (ParseException e1) {\n                return FormValidation.error(\"Not a valid date!\");\n            }\n            return FormValidation.error(\"Not a valid date!\");\n        }\n\n        public FormValidation doCheckPreviousResultsString(@QueryParameter String previousResultsString, @AncestorInPath AbstractProject<?, ?> project) {\n            if (ANY.equals(previousResultsString)) {\n                return FormValidation.ok();\n            }\n            int previousResults;\n            try {\n                previousResults = Integer.parseInt(previousResultsString);\n            } catch (NumberFormatException e) {\n                return FormValidation.error(\"This is not a valid number\");\n            }\n            if (previousResults < 1) {\n                return FormValidation.error(\"This value can't be smaller 1\");\n            }\n            /*\n\t\t\t * Problem description: if you want to evaluate the 15 last builds in a relative\n\t\t\t * constraint, but you only store 10 builds of your job you will get in trouble.\n\t\t\t * similiar problem: you store 10 builds in you job and evaluate the last 7 SUCCESSFUL\n\t\t\t * builds with a relative constraint. what if 5 of your 10 stored builds are in status\n\t\t\t * FAILED or UNSTABLE? -> problem. this form validation solves this problem if your\n\t\t\t * enter a number greater than the available builds (regarding your confiugration\n\t\t\t * 'ignoreFailed' and 'ignoreUnstable') you will get a form validation error note: if\n\t\t\t * you change 'ignoreFailed' or 'ignoreUnstable' you first have to save your\n\t\t\t * configuration before you change the number of previous builds\n\t\t\t */\n            if (project == null) { // Counting builds makes no sense when in Pipeline snippet generator\n                return FormValidation.ok();\n            }\n            RunList<?> builds = project.getBuilds();\n            int buildsToAnalyze = 0;\n            int successBuilds = 0;\n            int failedBuilds = 0;\n            int unstableBuilds = 0;\n            String buildSizeMessage = \"This value cant be bigger than the amount of stored builds with the status: SUCCESS\";\n            ListIterator<?> it = builds.listIterator();\n            while (it.hasNext()) {\n                Object next = it.next();\n                if (next instanceof FreeStyleBuild) {\n                    FreeStyleBuild b = (FreeStyleBuild) next;\n                    Result buildResult = b.getResult();\n                    if (buildResult != null) {\n                        if (buildResult.equals(Result.FAILURE)) {\n                            failedBuilds++;\n                        } else if (buildResult.equals(Result.UNSTABLE)) {\n                            unstableBuilds++;\n                        } else if (buildResult.equals(Result.SUCCESS)) {\n                            successBuilds++;\n                        }\n                    }\n                }\n            }\n            buildsToAnalyze = successBuilds;\n            boolean ignoreFailedBuilds = false;\n            boolean ignoreUnstableBuilds = false;\n            List<Publisher> list = project.getPublishersList().toList();\n            for (Publisher p : list) {\n                if (p instanceof PerformancePublisher) {\n                    PerformancePublisher pp = (PerformancePublisher) p;\n\n                    // MWA: uncomment and check\n\t\t\t\t\tignoreFailedBuilds = pp.isIgnoreFailedBuilds();\n\t\t\t\t\tignoreUnstableBuilds = pp.isIgnoreUnstableBuilds();\n\t\t\t\t\tbreak;\n                }\n            }\n            if (!ignoreUnstableBuilds) {\n                buildsToAnalyze += unstableBuilds;\n                buildSizeMessage = buildSizeMessage + \", UNSTABLE\";\n            }\n            if (!ignoreFailedBuilds) {\n                buildsToAnalyze += failedBuilds;\n                buildSizeMessage = buildSizeMessage + \", FAILED\";\n            }\n            if (previousResults > buildsToAnalyze+1) { // at the time of evaluation there will be one more build (the next build that is run, which could be the very first or only build)\n                return FormValidation.error(buildSizeMessage);\n            } else {\n                return FormValidation.ok();\n            }\n        }\n    }\n\n     @DataBoundConstructor\n    public RelativeConstraint(Metric meteredValue, Operator operator, String relatedPerfReport, Escalation escalationLevel, boolean success, TestCaseBlock testCaseBlock,\n                              PreviousResultsBlock previousResultsBlock, double tolerance) {\n\n        super(meteredValue, operator, relatedPerfReport, escalationLevel, success, testCaseBlock);\n        this.tolerance = tolerance;\n        this.previousResultsBlock = previousResultsBlock;\n        if (this.previousResultsBlock.isChoicePreviousResults()) {\n            if (ANY.equals(this.previousResultsBlock.getPreviousResultsString())) {\n                this.previousResults = -1;\n            } else {\n                try {\n                    this.previousResults = Integer.parseInt(this.previousResultsBlock.getPreviousResultsString());\n                } catch (NumberFormatException ex) {\n                    this.previousResults = -1;\n                }\n            }\n            this.previousResultsString = this.previousResultsBlock.getPreviousResultsString();\n        }\n        if (this.previousResultsBlock.isChoiceTimeframe()) {\n            this.timeframeStartString = this.previousResultsBlock.getTimeframeStartString();\n            this.timeframeEndString = this.previousResultsBlock.getTimeframeEndString();\n            if (this.timeframeStartString.length() == 10) {\n                this.timeframeStartString = this.timeframeStartString + \" 00:00\";\n            }\n            if (this.timeframeEndString.length() == 10) {\n                this.timeframeEndString = this.timeframeEndString + \" 23:59\";\n            }\n            try {\n                final SimpleDateFormat dfLong = new SimpleDateFormat(\"yyyy-MM-dd HH:mm\");\n                this.timeframeStart = dfLong.parse(this.timeframeStartString);\n                if (!NOW.equals(this.timeframeEndString)) {\n                    this.timeframeEnd = dfLong.parse(this.timeframeEndString);\n                }\n            } catch (ParseException e) {\n                PrintStream logger = getSettings().getListener().getLogger();\n                logger.print(\"Error occurred parsing one of those dates, timeframeStartString:\"+timeframeStartString\n                        +\", timeframeEndString:\"+timeframeEndString\n                        +\" using format:yyyy-MM-dd HH:mm, message:\"+e.getMessage());\n                e.printStackTrace(logger);\n            }\n        }\n        if (this.previousResultsBlock.isChoiceBaselineBuild()) {\n             // nothing to do, baseline build number comes from settings\n        }\n    }\n\n    /**\n     * Cloning of a RelativeConstraint Note that this is not from the Interface Clonable\n     *\n     * @return clone of this object\n     */\n    @SuppressFBWarnings(\"CN_IMPLEMENTS_CLONE_BUT_NOT_CLONEABLE\")\n    public RelativeConstraint clone() {\n        return new RelativeConstraint(this.getMeteredValue(), this.getOperator(), \n                this.getRelatedPerfReport(), this.getEscalationLevel(), this.getSuccess(), \n                new TestCaseBlock(this.getTestCaseBlock().getTestCase()),\n                new PreviousResultsBlock(this.getPreviousResultsBlock().getValue(), this.getPreviousResultsString(),\n                this.getTimeframeStartString(), this.getTimeframeEndString()), this.getTolerance());\n    }\n\n    @Override\n    public ConstraintEvaluation evaluate(List<? extends Run<?, ?>> builds) throws AbortException, ParseException {\n        if (builds.isEmpty()) {\n            throw new AbortException(\"Performance: No builds found to evaluate!\");\n        }\n        checkForDefectiveParams(builds);\n        PerformanceReport pr = builds.get(0).getAction(PerformanceBuildAction.class).getPerformanceReportMap().getPerformanceReport(getRelatedPerfReport());\n        double calValue = 0;\n        if (!isSpecifiedTestCase()) {\n            calValue = checkMetredValueforPerfReport(getMeteredValue(), pr);\n        } else {\n            List<UriReport> uriList = pr.getUriListOrdered();\n            for (UriReport ur : uriList) {\n                if (getTestCaseBlock().getTestCase().equals(ur.getUri())) {\n                    calValue = checkMetredValueforUriReport(getMeteredValue(), ur);\n                    break;\n                }\n            }\n        }\n        return check(builds, calValue);\n    }\n\n    /**\n     * Compares the values and sets the success and a result message of a constraint.\n     *\n     * @param builds   all builds that are saved in Jenkins\n     * @param newValue value of the measured metric of the new build\n     * @return evaluated constraint\n     */\n    private ConstraintEvaluation check(List<? extends Run<?, ?>> builds, double newValue) {\n        double calculatedValue = calcAveOfReports(builds);\n\t\t/*\n\t\t * If calculatedValue == Long.MIN_VALUE there was no build found to evaluate this constraint\n\t\t * The process should not get aborted, but this constraint should be marked as failed, unless it is the very first or only build.\n\t\t */\n        if (calculatedValue == Long.MIN_VALUE) {\n            boolean isVeryFirstBuild = (builds.size() == 1);\n            setSuccess(isVeryFirstBuild);\n            setResultMessage(\"Relative constraint \" + (isVeryFirstBuild ? \"skipped.\" : \"failed!\") + \" - Report: \" + getRelatedPerfReport() + \"\\n\" + \"There were no builds found to evaluate!\");\n            return new ConstraintEvaluation(this, 0, 0);\n        }\n        double result = 0;\n        if (getOperator().equals(Operator.NOT_GREATER)) {\n            result = calculatedValue * (1 + getTolerance() / 100);\n        } else if (getOperator().equals(Operator.NOT_LESS)) {\n            result = calculatedValue * (1 - getTolerance() / 100);\n        } else {\n            try {\n                throw new AbortException(\"Performance Plugin: Relative Constraints can only handle \\\"not greater than\\\" and \\\"not less than\\\" operators. Please check your constraint configuration\");\n            } catch (AbortException e) {\n                PrintStream logger = getSettings().getListener().getLogger();\n                e.printStackTrace(logger);\n            }\n        }\n\n        switch (getOperator()) {\n            case NOT_LESS:\n                setSuccess(result < newValue);\n                break;\n            case NOT_GREATER:\n                setSuccess(result >= newValue);\n                break;\n            default:\n                setSuccess(false);\n                break;\n        }\n        ConstraintEvaluation evaluation = new ConstraintEvaluation(this, result, calculatedValue);\n\n        String measuredLevel = isSpecifiedTestCase() ? getTestCaseBlock().getTestCase() : \"all test cases\";\n        if (getSuccess()) {\n            setResultMessage(\"Relative constraint successful! - Report: \" + getRelatedPerfReport() + \"\\n\" + \"The constraint says: \" + getMeteredValue() + \" of \" + measuredLevel + \" must \"\n                    + getOperator().text + \" \" + result + \"\\n\" + \"Measured value for \" + getMeteredValue() + \": \" + newValue + \"\\n\" + \"Included builds: \" + getPreviousResults() + \" builds \\n\"\n                    + \"Escalation Level: \" + getEscalationLevel());\n        } else {\n            setResultMessage(\"Relative constraint failed! - Report: \" + getRelatedPerfReport() + \"\\n\" + \"The constraint says: \" + getMeteredValue() + \" of \" + measuredLevel + \" must \"\n                    + getOperator().text + \" \" + result + \"\\n\" + \"Measured value for \" + getMeteredValue() + \": \" + newValue + \"\\n\" + \"Included builds: Last \" + getPreviousResults() + \" builds \\n\"\n                    + \"Escalation Level: \" + getEscalationLevel());\n        }\n\n        String unit = getMeteredValue()==Metric.ERRORPRC ? \"percent\" : \"milliseconds\";\n        setJunitResult(String.format(\"<testcase classname=\\\"%s\\\" name=\\\"%s of %s must %s %.3f percent above/below previous\\\">%n\",\n            getRelatedPerfReport(), getMeteredValue(), measuredLevel, getOperator().text, getTolerance())\n            + (getSuccess() ? \"\" :\n                String.format(\"    <failure type=\\\"%s\\\">Measured value for %s: %.0f %s. Previous value: %.0f %s. Deviation: %.3f %%</failure>%n\",\n                getEscalationLevel(), getMeteredValue(), newValue, unit, calculatedValue, unit, (newValue/calculatedValue-1)*100))\n            + \"</testcase>\\n\");\n\n        return evaluation;\n    }\n\n    /**\n     * Calculates the average of an meteredValue from UriReports/PerfomanceReports over several\n     * builds.\n     *\n     * @param builds all builds that are saved in Jenkins\n     * @return average of measured metric over included builds\n     */\n    private long calcAveOfReports(List<? extends Run<?, ?>> builds) {\n        List<Run<?, ?>> buildsToAnalyze = new ArrayList<>();\n        long tmpResult = 0;\n        int counter = 0;\n        long result = 0;\n        Run<?, ?> newBuild = builds.get(0);\n        if (getPreviousResultsBlock().isChoiceTimeframe()) {\n            buildsToAnalyze.addAll(evaluateDate(builds));\n        }\n        if (getPreviousResultsBlock().isChoicePreviousResults()) {\n            buildsToAnalyze.addAll(evaluatePreviousBuilds(builds));\n        }\n        if (getPreviousResultsBlock().isChoiceBaselineBuild()) {\n            buildsToAnalyze.add(builds.get(getSettings().getBaselineBuild()));\n        }\n        setPreviousResults(buildsToAnalyze.size());\n        if (!buildsToAnalyze.isEmpty()) {\n            for (Run<?, ?> actBuild : buildsToAnalyze) {\n                if (actBuild.getAction(PerformanceBuildAction.class) != null && !actBuild.equals(newBuild)) {\n                    List<PerformanceReport> tmpList = actBuild.getAction(PerformanceBuildAction.class).getPerformanceReportMap().getPerformanceListOrdered();\n                    for (PerformanceReport pr : tmpList) {\n                        if (getRelatedPerfReport().equals(pr.getReportFileName())) {\n                            if (!isSpecifiedTestCase()) {\n                                tmpResult += checkMetredValueforPerfReport(getMeteredValue(), pr);\n                            } else {\n                                tmpResult += getUriValue(pr);\n                            }\n                            counter++;\n                        }\n                    }\n                } else {\n                    PrintStream logger = getSettings().getListener().getLogger();\n                    logger.println(\"Performance: There are no comaparable data available for build #\" + actBuild.getNumber() + \". Skipping this build!\");\n                    setPreviousResults(getPreviousResults() - 1);\n                }\n            }\n            result = (long)SafeMaths.safeDivide(tmpResult, counter);\n        } else {\n\t\t\t/*\n\t\t\t * If no build was found to analyze return Long.MIN_VALUE. This will cause the\n\t\t\t * constraint to be marked as failed (except for the first/only build).\n\t\t\t */\n            PrintStream logger = getSettings().getListener().getLogger();\n            logger.println(\"Performance: There were no builds found to evaluate for a relative constraint!\");\n            return Long.MIN_VALUE;\n        }\n        return result;\n    }\n\n    /**\n     * Is executed when the RadioButton \"Compare with builds in a timeframe\" is choosen. Determines\n     * the builds that are included in the evaluation based on the constraint settings and the given\n     * timeframe.\n     *\n     * @param builds all builds that are saved in Jenkins\n     * @return builds list of builds that have taken place in a user defined time frame respecting\n     * the constraint settings\n     */\n    private List<Run<?, ?>> evaluateDate(List<? extends Run<?, ?>> builds) {\n        List<Run<?, ?>> result = new ArrayList<>();\n        Calendar timeframeStartAsCalendar = Calendar.getInstance();\n        timeframeStartAsCalendar.setTime(getTimeframeStart());\n        Calendar timeframeEndAsCalendar = Calendar.getInstance();\n        timeframeEndAsCalendar.setTime(getTimeframeEnd());\n\n        if (NOW.equals(getTimeframeEndString())) {\n            timeframeEndAsCalendar.setTime(new Date());\n        }\n        \n        for (Run<?, ?> build : builds) {\n            Result buildResult = build.getResult();\n            if (buildResult != null && \n                    (buildResult.equals(Result.SUCCESS) \n                        || (buildResult.equals(Result.UNSTABLE) \n                        && !getSettings().isIgnoreUnstableBuilds()) \n                        || (buildResult.equals(Result.FAILURE)\n                        && !getSettings().isIgnoreFailedBuilds()))\n                        && (!build.getTimestamp().before(timeframeStartAsCalendar) \n                                && !build.getTimestamp().after(timeframeEndAsCalendar) \n                                && !build.equals(builds.get(0)))) {\n                result.add(build);\n            }\n        }\n        return result;\n    }\n\n    /**\n     * Is executed when the RadioButton \"Compare with previous builds\" is chosen. Determines the\n     * builds that are included in the evaluation based on the constraint settings\n     *\n     * @param builds all builds that are saved in Jenkins\n     * @return build list of previous builds that get included into the evaluation\n     */\n    private List<Run<?, ?>> evaluatePreviousBuilds(List<? extends Run<?, ?>> builds) {\n        List<Run<?, ?>> result = new ArrayList<>();\n        if (getPreviousResults() == -1) {\n            setPreviousResults(builds.size() - 1);\n        }\n        int i = 1;\n        int j = 0;\n        while (j < getPreviousResults() && i < builds.size()) {\n            if (Objects.equals(builds.get(i).getResult(), Result.SUCCESS)\n                    || (Objects.equals(builds.get(i).getResult(), Result.UNSTABLE)\n                    && !getSettings().isIgnoreUnstableBuilds())\n                    || (Result.FAILURE.equals(builds.get(i).getResult()) && !getSettings().isIgnoreFailedBuilds())) {\n                result.add(builds.get(i));\n                j++;\n            }\n            i++;\n        }\n        return result;\n    }\n\n    /**\n     * Searches a value in a URIReport. Metric and PerformanceReport are defined in the constraint.\n     *\n     * @param pr performance report where to search for the URI report\n     * @return value of the specified metric\n     */\n    private double getUriValue(PerformanceReport pr) {\n        double result = 0;\n        for (UriReport ur : pr.getUriListOrdered()) {\n            if (getTestCaseBlock().getTestCase().equals(ur.getUri())) {\n                result = checkMetredValueforUriReport(getMeteredValue(), ur);\n            }\n        }\n        return result;\n    }\n\n    public int getPreviousResults() {\n        return previousResults;\n    }\n\n    public void setPreviousResults(int previousResults) {\n        this.previousResults = previousResults;\n    }\n\n    public double getTolerance() {\n        return tolerance;\n    }\n\n    public void setTolerance(double d) {\n        this.tolerance = d;\n    }\n\n    public boolean getChoicePreviousResults() {\n        return choicePreviousResults;\n    }\n\n    public void setChoicePreviousResults(boolean choicePreviousResults) {\n        this.choicePreviousResults = choicePreviousResults;\n    }\n\n    public String getTimeframeStartString() {\n        return timeframeStartString;\n    }\n\n    public void setTimeframeStartString(String timeframeStartString) {\n        this.timeframeStartString = timeframeStartString;\n    }\n\n    public String getTimeframeEndString() {\n        return timeframeEndString;\n    }\n\n    public void setTimeframeEndString(String timeframeEndString) {\n        this.timeframeEndString = timeframeEndString;\n    }\n\n    public Date getTimeframeStart() {\n        return timeframeStart;\n    }\n\n    public void setTimeframeStart(Date timeframeStart) {\n        this.timeframeStart = timeframeStart;\n    }\n\n    public Date getTimeframeEnd() {\n        return timeframeEnd;\n    }\n\n    public void setTimeframeEnd(Date timeframeEnd) {\n        this.timeframeEnd = timeframeEnd;\n    }\n\n    public PreviousResultsBlock getPreviousResultsBlock() {\n        return previousResultsBlock;\n    }\n\n    public void setPreviousResultsBlock(PreviousResultsBlock previousResultsBlock) {\n        this.previousResultsBlock = previousResultsBlock;\n    }\n\n    public String getPreviousResultsString() {\n        return previousResultsString;\n    }\n\n    public void setPreviousResultsString(String previousResultsString) {\n        this.previousResultsString = previousResultsString;\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/constraints/blocks/PreviousResultsBlock.java",
    "content": "package hudson.plugins.performance.constraints.blocks;\n\nimport hudson.Extension;\nimport hudson.model.AbstractDescribableImpl;\nimport hudson.model.Descriptor;\n\nimport org.jenkinsci.Symbol;\nimport org.kohsuke.stapler.DataBoundConstructor;\n\n/**\n * Holds the informations which builds get included into the evaluation of relative constraints.\n *\n * @author Rene Kugel\n */\npublic class PreviousResultsBlock extends AbstractDescribableImpl<PreviousResultsBlock> {\n    /**\n     * True: relative constraint includes a user defined number of builds into the evaluation False:\n     * relative constraint includes all builds that have taken place in an user defined time frame\n     * BASELINE: relative constraint includes baseline build defined in the PerformancePublisher settings.\n     * True and false are retained for backward compatibility.\n     */\n    public static final String PREVIOUS = \"true\", TIMEFRAME = \"false\", BASELINE = \"BASELINE\";\n    private String choicePreviousResults = TIMEFRAME; // keep field name for backward compatibility\n    /**\n     * Holds the user defined number of builds which are to include to the evaluation\n     */\n    private String previousResultsString;\n    /**\n     * Start of the time frame\n     */\n    private String timeframeStartString;\n    /**\n     * End of the time frame\n     */\n    private String timeframeEndString;\n\n    @Symbol(\"previous\")\n    @Extension\n    public static class DescriptorImpl extends Descriptor<PreviousResultsBlock> {\n        @Override\n        public String getDisplayName() {\n            return \"PreviousResultsBlock\";\n        }\n    }\n\n    @DataBoundConstructor\n    public PreviousResultsBlock(String value, String previousResultsString, String timeframeStartString, String timeframeEndString) {\n        this.setValue(value);\n        this.previousResultsString = previousResultsString;\n        this.timeframeStartString = timeframeStartString;\n        this.timeframeEndString = timeframeEndString;\n    }\n\n    public boolean isChoicePreviousResults() {\n        return PREVIOUS.equals(choicePreviousResults);\n    }\n\n    public void setChoicePreviousResults(boolean choicePreviousResults) {\n        this.choicePreviousResults = choicePreviousResults ? PREVIOUS : TIMEFRAME; // backward compatibility\n    }\n\n    public boolean isChoiceTimeframe() {\n        return TIMEFRAME.equals(choicePreviousResults);\n    }\n\n    public boolean isChoiceBaselineBuild() {\n        return BASELINE.equals(choicePreviousResults);\n    }\n\n    // Workaround for radioBlock sending 'value' instead of field name (JENKINS-45988):\n    public String getValue() {\n        return choicePreviousResults;\n    }\n\n    public void setValue(String value) {\n        this.choicePreviousResults = value;\n    }\n\n    public String getPreviousResultsString() {\n        return previousResultsString;\n    }\n\n    public void setPreviousResultsString(String previousResultsString) {\n        this.previousResultsString = previousResultsString;\n    }\n\n    public String getTimeframeStartString() {\n        return timeframeStartString;\n    }\n\n    public void setTimeframeStartString(String timeframeStartString) {\n        this.timeframeStartString = timeframeStartString;\n    }\n\n    public String getTimeframeEndString() {\n        return timeframeEndString;\n    }\n\n    public void setTimeframeEndString(String timeframeEndString) {\n        this.timeframeEndString = timeframeEndString;\n    }\n\n}"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/constraints/blocks/TestCaseBlock.java",
    "content": "package hudson.plugins.performance.constraints.blocks;\n\nimport hudson.Extension;\nimport hudson.model.AbstractDescribableImpl;\nimport hudson.model.Descriptor;\n\nimport org.jenkinsci.Symbol;\nimport org.kohsuke.stapler.DataBoundConstructor;\n\n/**\n * Holds the testCase information for constraints.\n *\n * @author Rene Kugel\n */\npublic class TestCaseBlock extends AbstractDescribableImpl<TestCaseBlock> {\n    private String testCase;\n\n    @Symbol(\"testCase\")\n    @Extension\n    public static class DescriptorImpl extends Descriptor<TestCaseBlock> {\n        @Override\n        public String getDisplayName() {\n            return \"TestCaseBlock\";\n        }\n    }\n\n    @DataBoundConstructor\n    public TestCaseBlock(String testCase) {\n        this.testCase = testCase;\n    }\n\n    public String getTestCase() {\n        return testCase;\n    }\n\n    public void setTestCase(String testCase) {\n        this.testCase = testCase;\n    }\n\n}"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/cookie/CookieHandler.java",
    "content": "package hudson.plugins.performance.cookie;\n\n\nimport org.kohsuke.stapler.Ancestor;\n\nimport javax.servlet.http.Cookie;\nimport java.util.List;\n\n/**\n * Creates and converts cookies.\n *\n * @author Ulli Hafner\n */\npublic class CookieHandler {\n    /**\n     * One year (in seconds).\n     */\n    private static final int ONE_YEAR = 60 * 60 * 24 * 365;\n    /**\n     * The name of the cookie.\n     */\n    private final String name;\n\n    /**\n     * Creates a new instance of {@link CookieHandler}.\n     *\n     * @param name the name of the cookie\n     */\n    public CookieHandler(final String name) {\n        this.name = \"hudson.plugins.\" + name;\n    }\n\n    /**\n     * Sends a cookie with the specified value.\n     *\n     * @param requestAncestors the ancestors of the request\n     * @param value            the cookie value\n     * @return the created cookie\n     */\n    public Cookie create(final List<Ancestor> requestAncestors, final String value) {\n        Cookie cookie = new Cookie(name, value);\n        Ancestor ancestor = requestAncestors.get(requestAncestors.size() - 3);\n        cookie.setPath(ancestor.getUrl());\n        cookie.setMaxAge(ONE_YEAR);\n\n        return cookie;\n    }\n\n    /**\n     * Selects the correct cookie from the specified cookies and returns its\n     * value. If there is no such cookie, then an empty string is returned.\n     *\n     * @param cookies the cookies to scan\n     * @return the cookie value or an empty string if the cookie is not found\n     */\n    public String getValue(final Cookie[] cookies) {\n        String values = \"\";\n        if (cookies != null) {\n            for (Cookie cookie : cookies) {\n                if (cookie.getName().equals(name)) {\n                    values = cookie.getValue();\n                }\n            }\n        }\n        return values;\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/data/ConstraintSettings.java",
    "content": "package hudson.plugins.performance.data;\n\nimport hudson.model.TaskListener;\n\n/**\n * Holds the global settings for constraints.\n *\n * @author Rene Kugel\n */\npublic class ConstraintSettings {\n\n    /**\n     * Build listener which is used to print relevant information to the console while evaluating\n     * constraints\n     */\n    private transient TaskListener listener;\n    /**\n     * If true: relative constraints won't include builds in the past with the status FAILURE into\n     * the evaluation\n     */\n    private boolean ignoreFailedBuilds;\n    /**\n     * If true: relative constraints won't include builds in the past with the status UNSTABLE into\n     * the evaluation\n     */\n    private boolean ignoreUnstableBuilds;\n    /**\n     * If true: the constraint log will get written into a log file\n     */\n    private boolean persistConstraintLog;\n\n    /**\n     * Relative constraints may need access to globally configured baseline build number to evaluate against\n     */\n    private int baselineBuild;\n\n    public ConstraintSettings(TaskListener listener, boolean ignoreFailedBuilds, boolean ignoreUnstableBuilds, boolean persistConstraintLog,\n                              int baselineBuild) {\n        this.setListener(listener);\n        this.setIgnoreFailedBuilds(ignoreFailedBuilds);\n        this.setIgnoreUnstableBuilds(ignoreUnstableBuilds);\n        this.setPersistConstraintLog(persistConstraintLog);\n        this.setBaselineBuild(baselineBuild);\n    }\n\n    public TaskListener getListener() {\n        return listener;\n    }\n\n    private void setListener(TaskListener listener) {\n        this.listener = listener;\n    }\n\n    public boolean isIgnoreFailedBuilds() {\n        return ignoreFailedBuilds;\n    }\n\n    public void setIgnoreFailedBuilds(boolean ignoreFailedBuilds) {\n        this.ignoreFailedBuilds = ignoreFailedBuilds;\n    }\n\n    public boolean isIgnoreUnstableBuilds() {\n        return ignoreUnstableBuilds;\n    }\n\n    public void setIgnoreUnstableBuilds(boolean ignoreUnstableBuilds) {\n        this.ignoreUnstableBuilds = ignoreUnstableBuilds;\n    }\n\n    public boolean isPersistConstraintLog() {\n        return persistConstraintLog;\n    }\n\n    public void setPersistConstraintLog(boolean persistConstraintLog) {\n        this.persistConstraintLog = persistConstraintLog;\n    }\n\n    public int getBaselineBuild() {\n        return baselineBuild;\n    }\n\n    public void setBaselineBuild(int baselineBuild) {\n        this.baselineBuild = baselineBuild;\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/data/HttpSample.java",
    "content": "package hudson.plugins.performance.data;\n\nimport hudson.plugins.performance.reports.UriReport;\n\nimport java.io.Serializable;\nimport java.util.Date;\nimport java.util.Objects;\n\n/**\n * Information about a particular HTTP request and how that went.\n * <p>\n * This object belongs under {@link UriReport}.\n */\npublic class HttpSample implements Serializable, Comparable<HttpSample> {\n\n    private static final long serialVersionUID = -3531990216789038711L;\n\n    private long duration;\n\n    private boolean successful;\n\n    private boolean errorObtained;\n\n    private Date date;\n\n    private String uri;\n\n    private String httpCode = \"\";\n\n    private double sizeInKb;\n\n    // Summarizer fields\n    private boolean isSummarizer;\n\n    private long summarizerMin;\n\n    private long summarizerMax;\n\n    private float summarizerErrors;\n\n    private long summarizerSamples;\n\n    public long getDuration() {\n        return duration;\n    }\n\n    public Date getDate() {\n        return date;\n    }\n\n    public String getUri() {\n        return uri;\n    }\n\n    public String getHttpCode() {\n        return httpCode;\n    }\n\n    public long getSummarizerSamples() {\n        return summarizerSamples;\n    }\n\n    public long getSummarizerMin() {\n        return summarizerMin;\n    }\n\n    public long getSummarizerMax() {\n        return summarizerMax;\n    }\n\n    public float getSummarizerErrors() {\n        return summarizerErrors;\n    }\n\n    public boolean isFailed() {\n        return !isSuccessful();\n    }\n\n    public boolean isSuccessful() {\n        return successful;\n    }\n\n    public void setDuration(long duration) {\n        this.duration = duration;\n    }\n\n    public void setSuccessful(boolean successful) {\n        this.successful = successful;\n    }\n\n    public void setErrorObtained(boolean errorObtained) {\n        this.errorObtained = errorObtained;\n    }\n\n    public boolean hasError() {\n        return errorObtained;\n    }\n\n    public void setDate(Date time) {\n        this.date = time;\n    }\n\n    public void setUri(String uri) {\n        this.uri = uri;\n    }\n\n    public void setHttpCode(String httpCode) {\n        this.httpCode = httpCode;\n    }\n\n    public void setSummarizerSamples(long summarizerSamples) {\n        this.summarizerSamples = summarizerSamples;\n    }\n\n    public void setSummarizerMin(long summarizerMin) {\n        this.summarizerMin = summarizerMin;\n    }\n\n    public void setSummarizerMax(long summarizerMax) {\n        this.summarizerMax = summarizerMax;\n    }\n\n    public void setSummarizerErrors(float summarizerErrors) {\n        this.summarizerErrors = summarizerErrors;\n    }\n\n    public int compareTo(HttpSample o) {\n        return (int) (getDuration() - o.getDuration());\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (this == obj) return true;\n        if (obj == null || getClass() != obj.getClass()) return false;\n        HttpSample that = (HttpSample) obj;\n        return getDuration() == that.getDuration();\n    }\n\n    @Override\n    public int hashCode() {\n        return Objects.hash(getDuration());\n    }\n\n    public double getSizeInKb() {\n        return sizeInKb;\n    }\n\n    public void setSizeInKb(double d) {\n        this.sizeInKb = d;\n    }\n\n    public boolean isErrorObtained() {\n        return errorObtained;\n    }\n\n    public boolean isSummarizer() {\n        return isSummarizer;\n    }\n\n    public void setSummarizer(boolean summarizer) {\n        isSummarizer = summarizer;\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/data/PerformanceReportPosition.java",
    "content": "package hudson.plugins.performance.data;\n\npublic class PerformanceReportPosition {\n    private String performanceReportPosition;\n    private String summarizerReportType;\n    private String summarizerTrendUri;\n\n    public String getPerformanceReportPosition() {\n        return performanceReportPosition;\n    }\n\n    public String getSummarizerReportType() {\n        return summarizerReportType;\n    }\n\n    public String getSummarizerTrendUri() {\n        return summarizerTrendUri;\n    }\n\n    public void setPerformanceReportPosition(String performanceReportPosition) {\n        this.performanceReportPosition = performanceReportPosition;\n    }\n\n    public void setSummarizerReportType(String summarizerReportType) {\n        this.summarizerReportType = summarizerReportType;\n    }\n\n    public void setSummarizerTrendUri(String summarizerTrendUri) {\n        this.summarizerTrendUri = summarizerTrendUri;\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/data/ReportValueSelector.java",
    "content": "package hudson.plugins.performance.data;\n\nimport hudson.model.AbstractProject;\nimport hudson.model.Job;\nimport hudson.plugins.performance.PerformancePublisher;\nimport hudson.plugins.performance.reports.AbstractReport;\n\npublic abstract class ReportValueSelector {\n\n    public abstract long getValue(AbstractReport report);\n\n    public abstract String getGraphType();\n\n    public static ReportValueSelector get(Job<?, ?> job) {\n        if (job instanceof AbstractProject) {\n            // can't get a AbstractProject reference from PerformanceReportMap :/\n            AbstractProject<?, ?> project = (AbstractProject<?, ?>) job;\n            return get(project.getPublishersList().get(PerformancePublisher.class));\n        }\n        return get((PerformancePublisher) null);\n    }\n\n    public static ReportValueSelector get(PerformancePublisher publisher) {\n        if (publisher == null)\n            return new SelectAverage();\n\n        String graphType = publisher.getGraphType();\n        if (graphType == null)\n            return new SelectAverage();\n        if (graphType.equals(PerformancePublisher.MRT))\n            return new SelectMedian();\n        if (graphType.equals(PerformancePublisher.PRT))\n            return new SelectPercentile();\n        return new SelectAverage(); // default\n    }\n\n    private static class SelectAverage extends ReportValueSelector {\n\n        @Override\n        public long getValue(AbstractReport report) {\n            return report.getAverage();\n        }\n\n        @Override\n        public String getGraphType() {\n            return PerformancePublisher.ART;\n        }\n    }\n\n    private static class SelectMedian extends ReportValueSelector {\n\n        @Override\n        public long getValue(AbstractReport report) {\n            return report.getMedian();\n        }\n\n        @Override\n        public String getGraphType() {\n            return PerformancePublisher.MRT;\n        }\n    }\n\n    private static class SelectPercentile extends ReportValueSelector {\n\n        @Override\n        public long getValue(AbstractReport report) {\n            return report.get90Line();\n        }\n\n        @Override\n        public String getGraphType() {\n            return PerformancePublisher.PRT;\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/data/TaurusFinalStats.java",
    "content": "package hudson.plugins.performance.data;\n\nimport java.io.Serializable;\n\npublic class TaurusFinalStats implements Serializable {\n\n    public static final String DEFAULT_TAURUS_LABEL = \"SUMMARY\";\n\n    private String label;\n\n    private int succ;\n    private int fail;\n    private long bytes;\n\n    // ALL TIME IN MILLISECONDS!\n    private double averageResponseTime;\n\n    private double perc0;\n    private double perc50;\n    private double perc90;\n    private double perc95;\n    private double perc100;\n\n    private Double testDuration;\n\n    private long throughput;\n\n\n    public String getLabel() {\n        return label;\n    }\n\n    public void setLabel(String label) {\n        this.label = label;\n    }\n\n    public int getSucc() {\n        return succ;\n    }\n\n    public void setSucc(int succ) {\n        this.succ = succ;\n    }\n\n    public int getFail() {\n        return fail;\n    }\n\n    public void setFail(int fail) {\n        this.fail = fail;\n    }\n\n    public double getAverageResponseTime() {\n        return averageResponseTime;\n    }\n\n    public void setAverageResponseTime(double averageResponseTime) {\n        this.averageResponseTime = averageResponseTime;\n    }\n\n    public long getBytes() {\n        return bytes;\n    }\n\n    public void setBytes(long bytes) {\n        this.bytes = bytes;\n    }\n\n    public double getPerc50() {\n        return perc50;\n    }\n\n    public void setPerc50(double perc50) {\n        this.perc50 = perc50;\n    }\n\n    public double getPerc90() {\n        return perc90;\n    }\n\n    public double getPerc95() {\n        return perc95;\n    }\n\n    public void setPerc90(double perc90) {\n        this.perc90 = perc90;\n    }\n\n    public void setPerc95(double perc95) {\n        this.perc95 = perc95;\n    }\n\n    public double getPerc0() {\n        return perc0;\n    }\n\n    public void setPerc0(double perc0) {\n        this.perc0 = perc0;\n    }\n\n    public double getPerc100() {\n        return perc100;\n    }\n\n    public void setPerc100(double perc100) {\n        this.perc100 = perc100;\n    }\n\n    public long getThroughput() {\n        return throughput;\n    }\n\n    public void setThroughput(long throughput) {\n        this.throughput = throughput;\n    }\n\n    public Double getTestDuration() {\n        return testDuration;\n    }\n\n    public void setTestDuration(Double testDuration) {\n        this.testDuration = testDuration;\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/descriptors/ConstraintDescriptor.java",
    "content": "package hudson.plugins.performance.descriptors;\n\nimport hudson.DescriptorExtensionList;\nimport hudson.model.Descriptor;\nimport hudson.plugins.performance.constraints.AbstractConstraint;\nimport jenkins.model.Jenkins;\n\npublic abstract class ConstraintDescriptor extends Descriptor<AbstractConstraint> {\n\n    public final String getId() {\n        return getClass().getName();\n    }\n\n    public static DescriptorExtensionList<AbstractConstraint, ConstraintDescriptor> all() {\n        return Jenkins.get().getDescriptorList(AbstractConstraint.class);\n    }\n\n    public static ConstraintDescriptor getById(String id) {\n        for (ConstraintDescriptor d : all())\n            if (d.getId().equals(id))\n                return d;\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/descriptors/PerformanceReportParserDescriptor.java",
    "content": "package hudson.plugins.performance.descriptors;\n\nimport hudson.DescriptorExtensionList;\nimport hudson.model.Descriptor;\nimport hudson.plugins.performance.parsers.PerformanceReportParser;\nimport jenkins.model.Jenkins;\n\n/**\n * @author Kohsuke Kawaguchi\n */\npublic abstract class PerformanceReportParserDescriptor extends\n        Descriptor<PerformanceReportParser> {\n\n    /**\n     * Internal unique ID that distinguishes a parser.\n     */\n    public final String getId() {\n        return getClass().getName();\n    }\n\n    /**\n     * Returns all the registered {@link PerformanceReportParserDescriptor}s.\n     */\n    public static DescriptorExtensionList<PerformanceReportParser, PerformanceReportParserDescriptor> all() {\n        return Jenkins.get().getDescriptorList(PerformanceReportParser.class);\n    }\n\n    public static PerformanceReportParserDescriptor getById(String id) {\n        for (PerformanceReportParserDescriptor d : all())\n            if (d.getId().equals(id))\n                return d;\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/details/GraphConfigurationDetail.java",
    "content": "package hudson.plugins.performance.details;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.nio.charset.Charset;\nimport java.text.DateFormat;\nimport java.text.ParseException;\nimport java.text.SimpleDateFormat;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Date;\nimport java.util.GregorianCalendar;\nimport java.util.List;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\nimport javax.servlet.ServletException;\nimport javax.servlet.http.Cookie;\n\nimport org.apache.commons.io.IOUtils;\n\nimport org.kohsuke.stapler.StaplerRequest;\nimport org.kohsuke.stapler.StaplerResponse;\n\nimport hudson.model.Job;\nimport hudson.model.ModelObject;\nimport hudson.plugins.performance.Messages;\nimport hudson.plugins.performance.cookie.CookieHandler;\nimport net.sf.json.JSONException;\nimport net.sf.json.JSONObject;\n\n/**\n * Configures the trend graph of this plug-in.\n */\npublic class GraphConfigurationDetail implements ModelObject {\n\n    /**\n     * Logger.\n     */\n    private static final Logger LOGGER = Logger.getLogger(GraphConfigurationDetail.class.getName());\n\n    public static final String LEGACY_SEPARATOR = \";\";\n    public static final String SEPARATOR = \":\";\n    /**\n     * The number of builds to consider.\n     */\n    private int buildCount;\n    /**\n     * The first days to consider.\n     */\n    private String firstDayCount;\n    /**\n     * The last days to consider.\n     */\n    private String lastDayCount;\n    /**\n     * The type of config to use.\n     */\n    private String configType;\n    /**\n     * The build step to consider.\n     */\n    private int buildStep;\n\n\n    public static final int DEFAULT_COUNT = 0;\n\n    public static final int DEFAULT_STEP = 1;\n\n    public static final String DEFAULT_DATE = \"dd/MM/yyyy\";\n\n    public static final String NONE_CONFIG = \"NONE\";\n\n    public static final String BUILD_CONFIG = \"BUILD\";\n\n    public static final String DATE_CONFIG = \"DATE\";\n\n    public static final String BUILDNTH_CONFIG = \"BUILDNTH\";\n\n    public boolean isNone() {\n        return configType.compareToIgnoreCase(GraphConfigurationDetail.NONE_CONFIG) == 0;\n    }\n\n    public boolean isBuildCount() {\n        return configType.compareToIgnoreCase(GraphConfigurationDetail.BUILD_CONFIG) == 0;\n    }\n\n    public boolean isBuildNth() {\n        return configType.compareToIgnoreCase(GraphConfigurationDetail.BUILDNTH_CONFIG) == 0;\n    }\n\n    public boolean isDate() {\n        return configType.compareToIgnoreCase(GraphConfigurationDetail.DATE_CONFIG) == 0;\n    }\n\n    public boolean isDefaultDates() {\n        return DEFAULT_DATE.compareTo(firstDayCount) == 0\n                && DEFAULT_DATE.compareTo(lastDayCount) == 0;\n    }\n\n    public GraphConfigurationDetail(final Job<?, ?> project,\n                                    final String pluginName, final StaplerRequest request) {\n\n        String value = createCookieHandler(pluginName).getValue(\n                request.getCookies());\n        List<Integer> initializationListResult = initializeFrom(value);\n        if (!initializationListResult.isEmpty()) {\n            File defaultsFile = createDefaultsFile(project, pluginName);\n            if (defaultsFile.exists()) {\n                String defaultValue = readFromDefaultsFile(defaultsFile);\n                initializationListResult = initializeFrom(defaultValue);\n                if (!initializationListResult.isEmpty()) {\n                    reset(initializationListResult);\n                }\n            } else {\n                reset(initializationListResult);\n            }\n        }\n    }\n\n    /**\n     * Saves the configured values. Subclasses need to implement the actual\n     * persistence.\n     *\n     * @param request  Stapler request\n     * @param response Stapler response\n     */\n    public void doSave(final StaplerRequest request,\n                       final StaplerResponse response) {\n        try {\n            JSONObject formData = request.getSubmittedForm();\n            String buildCountString = formData.getString(\"buildCountString\");\n            int buildCount = 0;\n            if (buildCountString != null && !buildCountString.isBlank()) {\n                buildCount = formData.getInt(\"buildCountString\");\n            }\n            String firstDayCountString = formData.getString(\"firstDayCountString\");\n            String firstDayCount = DEFAULT_DATE;\n            if (firstDayCountString != null && !firstDayCountString.isBlank()) {\n                firstDayCount = formData.getString(\"firstDayCountString\");\n            }\n            String lastDayCountString = formData.getString(\"lastDayCountString\");\n            String lastDayCount = DEFAULT_DATE;\n            if (lastDayCountString != null && !lastDayCountString.isBlank()) {\n                lastDayCount = formData.getString(\"lastDayCountString\");\n            }\n            String radioConfigType = formData.getString(\"radioConfigType\");\n            String configType = NONE_CONFIG;\n            if (radioConfigType != null && !radioConfigType.isBlank()) {\n                configType = formData.getString(\"radioConfigType\");\n            }\n\n            int buildStep = DEFAULT_STEP;\n            if (formData.has(\"buildStepString\")) {\n                String buildStepString = formData.getString(\"buildStepString\");\n\n                if (buildStepString != null && !buildStepString.isBlank()) {\n                    buildStep = formData.getInt(\"buildStepString\");\n                }\n            }\n\n            String value = serializeToString(configType, buildCount, firstDayCount,\n                    lastDayCount, buildStep);\n            persistValue(value, request, response);\n\n        } catch (JSONException exception) {\n            LOGGER.log(Level.SEVERE, \"Can't parse the form data: \" + request,\n                    exception);\n        } catch (IllegalArgumentException exception) {\n            LOGGER.log(Level.SEVERE, \"Can't parse the form data: \" + request,\n                    exception);\n        } catch (ServletException exception) {\n            LOGGER.log(Level.SEVERE, \"Can't process the form data: \" + request,\n                    exception);\n        } finally {\n            try {\n                response.sendRedirect(\"../\");\n            } catch (IOException exception) {\n                LOGGER.log(Level.SEVERE, \"Can't redirect\", exception);\n            }\n        }\n    }\n\n    public String getDisplayName() {\n        return Messages.GraphConfigurationDetail_DisplayName();\n    }\n\n    /**\n     * Creates a new cookie handler to convert the cookie to a string value.\n     *\n     * @param cookieName the suffix of the cookie name that is used to persist the\n     *                   configuration per user\n     * @return the new cookie handler\n     */\n    private static CookieHandler createCookieHandler(final String cookieName) {\n        return new CookieHandler(cookieName);\n    }\n\n    protected void persistValue(final String value, final StaplerRequest request,\n                                final StaplerResponse response) {\n\n        // First check for URL values\n        String buildCount = request.getParameter(\"buildCount\");\n        if (buildCount != null) {\n            setBuildCount(Integer.parseInt(buildCount));\n            setConfigType(GraphConfigurationDetail.BUILD_CONFIG);\n            return;\n        }\n\n        String buildStep = request.getParameter(\"buildStep\");\n        if (buildStep != null) {\n            setBuildStep(Integer.parseInt(buildStep));\n            setConfigType(GraphConfigurationDetail.BUILDNTH_CONFIG);\n            return;\n        }\n\n        // If not found, check cookie\n        Cookie cookie = createCookieHandler(\"performance\").create(\n                request.getAncestors(), value);\n        response.addCookie(cookie);\n    }\n\n    protected String serializeToString(final String configType,\n                                       final int buildCount, final String firstDayCount,\n                                       final String lastDayCount, final int buildStep) {\n        return configType + SEPARATOR + buildCount + SEPARATOR + firstDayCount\n                + SEPARATOR + lastDayCount + SEPARATOR + buildStep;\n    }\n\n    /**\n     * Creates a file with for the default values.\n     *\n     * @param project    the project used as directory for the file\n     * @param pluginName the name of the plug-in\n     * @return the created file\n     */\n    protected static File createDefaultsFile(final Job<?, ?> project,\n                                             final String pluginName) {\n        return new File(project.getRootDir(), pluginName + \".txt\");\n    }\n\n    /**\n     * Parses the provided string and initializes the members. If the string is\n     * not in the expected format, a list containing -1, 1, 2 and/or 3 is\n     * returned. -1 is a global error, 1 is a dayCount error, 2 is a first date\n     * error, 3 is a last date error. Return an empty list if all is good.\n     *\n     * @param value the initialization value stored in the format\n     *              <code>configType;buildCount;firstDayCount;lastDayCount</code>\n     * @return an empty list is the initialization was successful, a list\n     * containing -1, 1, 2 or 3 otherwise\n     */\n    private List<Integer> initializeFrom(final String value) {\n        List<Integer> listErrors = new ArrayList<Integer>(0);\n        if (value == null || value.isBlank()) {\n            listErrors.add(-1);\n            return listErrors;\n        }\n\n        String[] values;\n        if (value.contains(LEGACY_SEPARATOR))\n            values = value.split(LEGACY_SEPARATOR);\n        else\n            values = value.split(SEPARATOR);\n\n        if ((values.length != 4) && (values.length != 5)) {\n            listErrors.add(-1);\n            return listErrors;\n        }\n        configType = values[0];\n        if (BUILD_CONFIG.compareToIgnoreCase(configType) != 0\n                && BUILDNTH_CONFIG.compareToIgnoreCase(configType) != 0\n                && DATE_CONFIG.compareToIgnoreCase(configType) != 0\n                && NONE_CONFIG.compareToIgnoreCase(configType) != 0) {\n            listErrors.add(-1);\n        }\n        try {\n            buildCount = Integer.parseInt(values[1]);\n        } catch (JSONException e) {\n            listErrors.add(1);\n            e.printStackTrace();\n        }\n        firstDayCount = values[2];\n        lastDayCount = values[3];\n        GregorianCalendar firstDate = null;\n        GregorianCalendar lastDate = null;\n        if (firstDayCount.compareTo(DEFAULT_DATE) == 0\n                && DATE_CONFIG.compareToIgnoreCase(configType) == 0) {\n            listErrors.add(2);\n        }\n        if (lastDayCount.compareTo(DEFAULT_DATE) == 0\n                && DATE_CONFIG.compareToIgnoreCase(configType) == 0) {\n            listErrors.add(3);\n        }\n        if (firstDayCount.compareTo(DEFAULT_DATE) != 0) {\n            try {\n                firstDate = getGregorianCalendarFromString(firstDayCount);\n            } catch (IllegalArgumentException e) {\n                listErrors.add(2);\n                e.printStackTrace();\n            } catch (ParseException e) {\n                listErrors.add(2);\n                e.printStackTrace();\n            }\n        }\n        if (lastDayCount.compareTo(DEFAULT_DATE) != 0) {\n            try {\n                lastDate = getGregorianCalendarFromString(lastDayCount);\n            } catch (IllegalArgumentException e) {\n                listErrors.add(3);\n                e.printStackTrace();\n            } catch (ParseException e) {\n                listErrors.add(3);\n                e.printStackTrace();\n            }\n        }\n        if (firstDate != null && lastDate != null && firstDate.after(lastDate)) {\n            listErrors.add(2);\n            listErrors.add(3);\n        }\n\n        try {\n            if (values.length == 5) {\n                buildStep = Integer.parseInt(values[4]);\n            }\n        } catch (JSONException e) {\n            listErrors.add(4);\n            e.printStackTrace();\n        }\n\n        // clean the error list\n        if (!listErrors.isEmpty()) {\n            Collections.sort(listErrors);\n            if (listErrors.get(0) == -1) {\n                listErrors = new ArrayList<Integer>(1);\n                listErrors.add(-1);\n            } else {\n                int actualErrorType = 0;\n                List<Integer> realListErrors = new ArrayList<Integer>(0);\n                for (Integer typeError : listErrors) {\n                    if (actualErrorType != typeError) {\n                        actualErrorType = typeError;\n                        realListErrors.add(typeError);\n                    }\n                }\n                listErrors = realListErrors;\n            }\n        }\n        return listErrors;\n    }\n\n    /**\n     * <p>\n     * Get a gregorian calendar from a String of type : DD/MM/YYYY\n     * </p>\n     *\n     * @param dateString\n     * @return GregorianCalendar\n     * @throws ParseException\n     */\n    public static GregorianCalendar getGregorianCalendarFromString(\n            String dateString) throws ParseException {\n        DateFormat format = new SimpleDateFormat(DEFAULT_DATE);\n        Date date = format.parse(dateString);\n        GregorianCalendar outCalendar = new GregorianCalendar();\n        outCalendar.setTime(date);\n        return outCalendar;\n    }\n\n    /**\n     * Resets the graph configuration to the default values.\n     */\n    private void reset(List<Integer> initializationResult) {\n        configType = NONE_CONFIG;\n        for (Integer errorNumber : initializationResult) {\n            if (errorNumber == -1) {\n                buildCount = DEFAULT_COUNT;\n                firstDayCount = DEFAULT_DATE;\n                lastDayCount = DEFAULT_DATE;\n                buildStep = DEFAULT_STEP;\n            } else if (errorNumber == 1) {\n                buildCount = DEFAULT_COUNT;\n            } else if (errorNumber == 2) {\n                firstDayCount = DEFAULT_DATE;\n            } else if (errorNumber == 3) {\n                lastDayCount = DEFAULT_DATE;\n            } else if (errorNumber == 4) {\n                buildStep = DEFAULT_STEP;\n            }\n        }\n    }\n\n    /**\n     * Reads the default values from file.\n     *\n     * @param defaultsFile the file with the default values\n     * @return the default values from file.\n     */\n    private String readFromDefaultsFile(final File defaultsFile) {\n        String defaultValue = \"\";\n        FileInputStream input = null;\n        try {\n            input = new FileInputStream(defaultsFile);\n            defaultValue = IOUtils.toString(input, Charset.defaultCharset());\n        } catch (IOException exception) {\n            // ignore\n        } finally {\n            IOUtils.closeQuietly(input);\n        }\n        return defaultValue;\n    }\n\n    public int getBuildCount() {\n        return buildCount;\n    }\n\n    public void setBuildCount(int buildCount) {\n        this.buildCount = buildCount;\n    }\n\n    public int getBuildStep() {\n        return buildStep;\n    }\n\n    public void setBuildStep(int buildStep) {\n        this.buildStep = buildStep;\n    }\n\n    public String getFirstDayCount() {\n        return firstDayCount;\n    }\n\n    public void setFirstDayCount(String firstDayCount) {\n        this.firstDayCount = firstDayCount;\n    }\n\n    public String getLastDayCount() {\n        return lastDayCount;\n    }\n\n    public void setLastDayCount(String lastDayCount) {\n        this.lastDayCount = lastDayCount;\n    }\n\n    public String getConfigType() {\n        return configType;\n    }\n\n    public void setConfigType(String configType) {\n        this.configType = configType;\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/details/TestSuiteReportDetail.java",
    "content": "package hudson.plugins.performance.details;\n\nimport hudson.model.Job;\nimport hudson.model.ModelObject;\nimport hudson.model.Run;\nimport hudson.plugins.performance.Messages;\nimport hudson.plugins.performance.actions.PerformanceBuildAction;\nimport hudson.plugins.performance.actions.PerformanceProjectAction.Range;\nimport hudson.plugins.performance.data.ReportValueSelector;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.reports.UriReport;\nimport hudson.util.ChartUtil;\nimport hudson.util.ChartUtil.NumberOnlyBuildLabel;\nimport hudson.util.ColorPalette;\nimport hudson.util.DataSetBuilder;\nimport hudson.util.Graph;\nimport hudson.util.ShiftedCategoryAxis;\nimport org.jfree.chart.ChartFactory;\nimport org.jfree.chart.JFreeChart;\nimport org.jfree.chart.axis.CategoryAxis;\nimport org.jfree.chart.axis.CategoryLabelPositions;\nimport org.jfree.chart.axis.NumberAxis;\nimport org.jfree.chart.plot.CategoryPlot;\nimport org.jfree.chart.plot.PlotOrientation;\nimport org.jfree.chart.renderer.category.LineAndShapeRenderer;\nimport org.jfree.chart.title.LegendTitle;\nimport org.jfree.data.category.CategoryDataset;\nimport org.jfree.ui.RectangleEdge;\nimport org.jfree.ui.RectangleInsets;\nimport org.kohsuke.stapler.StaplerRequest;\nimport org.kohsuke.stapler.StaplerResponse;\n\nimport java.awt.Color;\nimport java.awt.BasicStroke;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\n/**\n * Configures the trend graph of this plug-in.\n */\npublic class TestSuiteReportDetail implements ModelObject {\n\n    private final Job<?, ?> project;\n    private final String filename;\n    private final Range buildsLimits;\n\n    private transient List<String> performanceReportTestCaseList;\n\n    public TestSuiteReportDetail(final Job<?, ?> project, String filename,\n                                 Range buildsLimits) {\n        this.project = project;\n        this.filename = filename;\n        this.buildsLimits = buildsLimits;\n    }\n\n    public void doRespondingTimeGraphPerTestCaseMode(StaplerRequest request,\n                                                     StaplerResponse response) throws IOException {\n        if (ChartUtil.awtProblemCause != null) {\n            // not available. send out error message\n            response.sendRedirect2(request.getContextPath() + \"/images/headless.png\");\n            return;\n        }\n        String testUri = request.getParameter(\"performanceReportTest\");\n\n        new Graph(-1, 600, 200) {\n            @Override\n            protected JFreeChart createGraph() {\n                return createRespondingTimeChart(\n                        getChartDatasetBuilderForBuilds(testUri, getProject().getBuilds()).build());\n            }\n        }.doPng(request, response);      \n    }\n\n    DataSetBuilder<String, NumberOnlyBuildLabel> getChartDatasetBuilderForBuilds(String testUri, List<? extends Run<?, ?>> builds) {\n        DataSetBuilder<String, NumberOnlyBuildLabel> dataSetBuilder = new DataSetBuilder<String, NumberOnlyBuildLabel>();\n        ReportValueSelector valueSelector = ReportValueSelector.get(getProject());\n        int nbBuildsToAnalyze = builds.size();\n        for (Run<?, ?> build : builds) {\n            if (buildsLimits.in(nbBuildsToAnalyze)) {\n\n                if (!buildsLimits.includedByStep(build.number)) {\n                    continue;\n                }\n                NumberOnlyBuildLabel label = new NumberOnlyBuildLabel(build);\n                PerformanceBuildAction performanceBuildAction = build\n                        .getAction(PerformanceBuildAction.class);\n                if (performanceBuildAction == null) {\n                    continue;\n                }\n                PerformanceReport performanceReport = performanceBuildAction\n                        .getPerformanceReportMap().getPerformanceReport(this.filename);\n                if (performanceReport == null) {\n                    nbBuildsToAnalyze--;\n                    continue;\n                }\n\n                String testStaplerUri = PerformanceReport.asStaplerURI(testUri);\n                UriReport reportForTestUri = performanceReport.getUriReportMap().get(testStaplerUri);\n                if (reportForTestUri != null) {\n                    dataSetBuilder.add(valueSelector.getValue(reportForTestUri), testUri, label);\n                }\n            }\n            nbBuildsToAnalyze--;\n        }\n        return dataSetBuilder;\n    }\n\n    protected static JFreeChart createRespondingTimeChart(CategoryDataset dataset) {\n\n        final JFreeChart chart = ChartFactory.createLineChart(\n                Messages.ProjectAction_RespondingTime(), // charttitle\n                null, // unused\n                \"ms\", // range axis label\n                dataset, // data\n                PlotOrientation.VERTICAL, // orientation\n                true, // include legend\n                true, // tooltips\n                false // urls\n        );\n\n        // NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART...\n\n        final LegendTitle legend = chart.getLegend();\n        legend.setPosition(RectangleEdge.BOTTOM);\n\n        chart.setBackgroundPaint(Color.white);\n\n        final CategoryPlot plot = chart.getCategoryPlot();\n\n        // plot.setAxisOffset(new Spacer(Spacer.ABSOLUTE, 5.0, 5.0, 5.0, 5.0));\n        plot.setBackgroundPaint(Color.WHITE);\n        plot.setOutlinePaint(null);\n        plot.setRangeGridlinesVisible(true);\n        plot.setRangeGridlinePaint(Color.black);\n\n        CategoryAxis domainAxis = new ShiftedCategoryAxis(null);\n        plot.setDomainAxis(domainAxis);\n        domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_90);\n        domainAxis.setLowerMargin(0.0);\n        domainAxis.setUpperMargin(0.0);\n        domainAxis.setCategoryMargin(0.0);\n\n        final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();\n        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());\n\n        final LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot\n                .getRenderer();\n        renderer.setBaseStroke(new BasicStroke(4.0f));\n        ColorPalette.apply(renderer);\n\n        // crop extra space around the graph\n        plot.setInsets(new RectangleInsets(5.0, 0, 0, 5.0));\n\n        return chart;\n    }\n\n    public List<String> getPerformanceReportTestCaseList() {\n        this.performanceReportTestCaseList = new ArrayList<String>(0);\n        String performanceReportNameFile = this.getFilename();\n\n        List<? extends Run<?, ?>> builds = getProject().getBuilds();\n\n        for (Run<?, ?> build : builds) {\n\n            PerformanceBuildAction performanceBuildAction = build\n                    .getAction(PerformanceBuildAction.class);\n            if (performanceBuildAction == null) {\n                continue;\n            }\n\n            PerformanceReport performanceReport = performanceBuildAction\n                    .getPerformanceReportMap().getPerformanceReport(\n                            performanceReportNameFile);\n            if (performanceReport == null) {\n                continue;\n            }\n\n            for (UriReport currentReport : performanceReport.getUriReportMap().values()) {\n                if (!performanceReportTestCaseList.contains(currentReport.getUri())) {\n                    performanceReportTestCaseList.add(currentReport.getUri());\n                }\n            }\n        }\n\n        Collections.sort(performanceReportTestCaseList);\n\n        return this.performanceReportTestCaseList;\n    }\n\n    public Job<?, ?> getProject() {\n        return project;\n    }\n\n    public String getFilename() {\n        return filename;\n    }\n\n    public String getDisplayName() {\n        return Messages.TestSuiteReportDetail_DisplayName();\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/details/TrendReportDetail.java",
    "content": "package hudson.plugins.performance.details;\n\nimport hudson.model.Job;\nimport hudson.model.ModelObject;\nimport hudson.plugins.performance.Messages;\nimport org.jfree.data.category.CategoryDataset;\nimport org.kohsuke.stapler.StaplerRequest;\n\nimport java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.List;\n\n/**\n * Configures the trend graph of this plug-in.\n */\npublic class TrendReportDetail implements ModelObject,\n        Iterable<TrendReportDetail.Row> {\n\n    private Job<?, ?> project;\n    private String filename;\n    private CategoryDataset dataSet;\n\n    public TrendReportDetail(final Job<?, ?> project,\n                             final String pluginName, final StaplerRequest request, String filename,\n                             CategoryDataset dataSet) {\n        this.project = project;\n        this.filename = filename;\n        this.dataSet = dataSet;\n    }\n\n    public Job<?, ?> getProject() {\n        return project;\n    }\n\n    public String getFilename() {\n        return filename;\n    }\n\n    public String getDisplayName() {\n        return Messages.TrendReportDetail_DisplayName();\n    }\n\n    public Iterator<Row> iterator() {\n        return new RowIterator();\n    }\n\n    public Iterator<Row> getIterator() {\n        return iterator();\n    }\n\n    public List<?> getColumnLabels() {\n        return dataSet.getRowKeys();\n    }\n\n    public class RowIterator implements Iterator<Row> {\n\n        private int entry = 0;\n\n        public boolean hasNext() {\n            return (entry < dataSet.getColumnCount());\n        }\n\n        public Row next() {\n            return new Row(entry++);\n        }\n\n        public void remove() {\n            throw new UnsupportedOperationException();\n        }\n    }\n\n    public class Row {\n\n        private int entry;\n\n        public Row(int entry) {\n            this.entry = entry;\n        }\n\n        public Object getLabel() {\n            return dataSet.getColumnKey(entry);\n        }\n\n        public List<?> getLabels() {\n            return dataSet.getRowKeys();\n        }\n\n        public List<Number> getValues() {\n            int count = dataSet.getRowCount();\n            List<Number> list = new ArrayList<>(count);\n            for (int i = 0; i < count; i++) {\n                list.add(dataSet.getValue(dataSet.getRowKey(i),\n                        dataSet.getColumnKey(entry)));\n            }\n            return list;\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/parsers/AbstractParser.java",
    "content": "package hudson.plugins.performance.parsers;\n\nimport java.io.BufferedInputStream;\nimport java.io.BufferedOutputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\nimport java.io.ObjectStreamClass;\nimport java.text.ParseException;\nimport java.text.SimpleDateFormat;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.Date;\nimport java.util.Hashtable;\nimport java.util.List;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\nimport com.google.common.cache.Cache;\nimport com.google.common.cache.CacheBuilder;\n\nimport hudson.model.Run;\nimport hudson.model.TaskListener;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.reports.UriReport;\n\n/**\n * An abstraction for parsing data to PerformanceReport instances. This class\n * provides functionality that optimizes the parsing process, such as caching as\n * well as saving/loaded parsed data in serialized form to/from disc.\n *\n * @author Guus der Kinderen, guus.der.kinderen@gmail.com\n */\npublic abstract class AbstractParser extends PerformanceReportParser {\n    private static final Logger LOGGER = Logger.getLogger(JMeterParser.class.getName());\n\n    /**\n     * A suffix to be used for files in which a serialized PerformanceReport instance is stored.\n     */\n    private static final String SERIALIZED_DATA_FILE_SUFFIX = \".serialized\";\n\n    /**\n     * A cache that contains serialized PerformanceReport instances. This cache intends to limit disc IO.\n     */\n    private static final Cache<String, PerformanceReport> CACHE = CacheBuilder.newBuilder().maximumSize(1000).softValues().build();\n\n    protected boolean isNumberDateFormat = false;\n    protected transient SimpleDateFormat format;\n\n    static final String[] DATE_FORMATS = new String[]{\n            \"yyyy/MM/dd HH:mm:ss.SSS\", \"yyyy-MM-dd HH:mm:ss.SSS\", \"yyyy-MM-dd HH:mm:ss,SSS\", \"yyyy/mm/dd HH:mm:ss\"\n    };\n\n    protected String percentiles;\n\n    protected String filterRegex;\n\n    public AbstractParser(String glob, String percentiles, String filterRegex) {\n        super(glob);\n        this.percentiles = percentiles;\n        this.filterRegex = filterRegex;\n    }\n\n    @Override\n    public Collection<PerformanceReport> parse(Run<?, ?> build, Collection<File> reports, TaskListener listener) throws IOException {\n        final List<PerformanceReport> result = new ArrayList<>();\n\n        for (File reportFile : reports) {\n            // Attempt to load previously serialized instances from file or cache.\n            final PerformanceReport deserializedReport = loadSerializedReport(reportFile);\n            if (deserializedReport != null) {\n                result.add(deserializedReport);\n                continue;\n            }\n\n            // When serialized data cannot be used, the original JMeter files are to be processed.\n            try {\n                listener.getLogger().println(\"Performance: Parsing report file '\" + reportFile + \"' with filterRegex '\"+filterRegex+\"'.\");\n                final PerformanceReport report = parse(reportFile);\n                result.add(report);\n                passBaselineBuild(report);\n                saveSerializedReport(reportFile, report);\n            } catch (Throwable e) {\n                listener.getLogger().println(\"Performance: Failed to parse file '\" + reportFile + \"': \" + e.getMessage());\n                e.printStackTrace(listener.getLogger());\n            }\n        }\n        return result;\n    }\n\n    private void passBaselineBuild(PerformanceReport report) {\n        report.setBaselineBuild(baselineBuild);\n    }\n\n    /**\n     * Performs the actual parsing of data. When the implementation throws any\n     * exception, the input file is ignored. This does not abort parsing of\n     * subsequent files.\n     *\n     * @param reportFile The source file (cannot be null).\n     * @return The parsed data (never null).\n     * @throws Throwable On any exception.\n     */\n    abstract PerformanceReport parse(File reportFile) throws Exception;\n\n    /**\n     * Returns a PerformanceReport instance for the provided report file, based on\n     * previously serialized data.\n     * <p>\n     * This method first attempts to load data from an internal cache. If the data\n     * is not in cache, data is obtained from a file on disc.\n     * <p>\n     * When no PerformanceReport instance has previously been serialized (or when\n     * such data cannot be read, for instance because of class file changes), this\n     * method returns null.\n     *\n     * @param reportFile Report for which to return data. Cannot be null.\n     * @return deserialized data, possibly null.\n     */\n    protected static PerformanceReport loadSerializedReport(File reportFile) {\n        if (reportFile == null) {\n            throw new IllegalArgumentException(\"Argument 'reportFile' cannot be null.\");\n        }\n        final String serialized = reportFile.getPath() + SERIALIZED_DATA_FILE_SUFFIX;\n        File file = new File(serialized);\n        synchronized (CACHE) {\n            PerformanceReport report = CACHE.getIfPresent(serialized);\n            if (report == null && file.exists() && file.canRead()) {\n                try (FileInputStream fis = new FileInputStream(serialized);\n                        BufferedInputStream bis = new BufferedInputStream(fis);\n                        ObjectInputStream in = new ObjectInputStreamWithClassMapping(bis)) {\n                    report = (PerformanceReport) in.readObject();\n                    CACHE.put(serialized, report);\n                    return report;\n                } catch (FileNotFoundException ex) {\n                    // That's OK\n                } catch (Exception ex) {\n                    LOGGER.log(Level.WARNING, \"Reading serialized PerformanceReport instance from file '\" + serialized + \"' failed.\", ex);\n                }\n            }\n            return report;\n        }\n    }\n\n    /**\n     * Saves a PerformanceReport instance as serialized data into a file on disc.\n     *\n     * @param reportFile The file from which the original data is obtained (<em>not</em>\n     *                   the file into which serialized data is to be saved!) Cannot be\n     *                   null.\n     * @param report     The instance to serialize. Cannot be null.\n     */\n    protected static void saveSerializedReport(File reportFile, PerformanceReport report) {\n        if (reportFile == null) {\n            throw new IllegalArgumentException(\"Argument 'reportFile' cannot be null.\");\n        }\n        if (report == null) {\n            throw new IllegalArgumentException(\"Argument 'report' cannot be null.\");\n        }\n        final String serialized = reportFile.getPath() + SERIALIZED_DATA_FILE_SUFFIX;\n\n        synchronized (CACHE) {\n            CACHE.put(serialized, report);\n        }\n        try (FileOutputStream fos = new FileOutputStream(serialized);\n                BufferedOutputStream bos = new BufferedOutputStream(fos);\n                ObjectOutputStream out = new ObjectOutputStream(bos)) {\n            out.writeObject(report);\n        } catch (Exception ex) {\n            LOGGER.log(Level.WARNING, \"Saving serialized PerformanceReport instance to file '\" + serialized + \"' failed.\", ex);\n        }\n    }\n\n    public static class ObjectInputStreamWithClassMapping extends ObjectInputStream {\n        protected Hashtable<String, Class<?>> classMapping = new Hashtable<>(); \n\n        public ObjectInputStreamWithClassMapping(InputStream in) throws IOException {\n            super(in);\n            classMapping.put(\"hudson.plugins.performance.PerformanceReport\", PerformanceReport.class);\n            classMapping.put(\"hudson.plugins.performance.UriReport\", UriReport.class);\n            classMapping.put(\"hudson.plugins.performance.UriReport$Sample\", UriReport.Sample.class);\n        }\n\n        @Override\n        protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException,\n                ClassNotFoundException {\n            return (classMapping.containsKey(desc.getName())) ?\n                    classMapping.get(desc.getName()) :\n                    super.resolveClass(desc);\n        }\n    }\n\n\n    public void clearDateFormat() {\n        this.format = null;\n        this.isNumberDateFormat = false;\n    }\n\n    public Date parseTimestamp(String timestamp) {\n        if (this.format == null) {\n            initDateFormat(timestamp);\n        }\n\n        try {\n            return isNumberDateFormat ?\n                    new Date(Long.parseLong(timestamp)) :\n                    format.parse(timestamp);\n        } catch (ParseException e) {\n            throw new IllegalArgumentException(\"Cannot parse timestamp: \" + timestamp +\n                    \". Please, use one of supported formats: \" + Arrays.toString(DATE_FORMATS), e);\n        }\n    }\n\n    private void initDateFormat(String timestamp) {\n        Date result = null;\n        for (String format : DATE_FORMATS) {\n            try {\n                this.format = new SimpleDateFormat(format);\n                result = this.format.parse(timestamp);\n            } catch (ParseException ex) {\n                // ok\n                this.format = null;\n            }\n\n            if (result != null) {\n                break;\n            }\n        }\n\n        if (result == null) {\n            try {\n                Long.valueOf(timestamp);\n                isNumberDateFormat = true;\n            } catch (NumberFormatException ex) {\n                throw new IllegalArgumentException(\"Cannot parse timestamp: \" + timestamp +\n                        \". Please, use one of supported formats: \" + Arrays.toString(DATE_FORMATS), ex);\n            }\n        }\n    }\n\n    protected PerformanceReport createPerformanceReport() {\n        return new PerformanceReport(percentiles, filterRegex);\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/parsers/IagoParser.java",
    "content": "package hudson.plugins.performance.parsers;\n\nimport java.io.BufferedReader;\nimport java.io.File;\nimport java.io.FileReader;\nimport java.lang.reflect.Type;\nimport java.nio.charset.StandardCharsets;\nimport java.text.ParseException;\nimport java.text.SimpleDateFormat;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\nimport org.kohsuke.stapler.DataBoundConstructor;\n\nimport com.google.gson.Gson;\nimport com.google.gson.GsonBuilder;\nimport com.google.gson.JsonDeserializationContext;\nimport com.google.gson.JsonDeserializer;\nimport com.google.gson.JsonElement;\nimport com.google.gson.JsonObject;\nimport com.google.gson.JsonParseException;\nimport com.google.gson.annotations.SerializedName;\n\nimport hudson.Extension;\nimport hudson.plugins.performance.data.HttpSample;\nimport hudson.plugins.performance.descriptors.PerformanceReportParserDescriptor;\nimport hudson.plugins.performance.reports.PerformanceReport;\n\n/**\n * Parses Iago results as dumped by the server.\n *\n * @author jwstric2\n */\npublic class IagoParser extends AbstractParser {\n\n    private static final String STATS_DATE_FORMAT = \"yyyymmdd-HH:mm:ss.SSS\";\n\n    @Extension\n    public static class DescriptorImpl extends PerformanceReportParserDescriptor {\n        @Override\n        public String getDisplayName() {\n            return \"Iago\";\n        }\n    }\n\n    public IagoParser(String glob, String percentiles) {\n        this(glob, percentiles, PerformanceReport.INCLUDE_ALL);\n    }\n    \n    @DataBoundConstructor\n    public IagoParser(String glob, String percentiles, String filterRegex) {\n        super(glob, percentiles, filterRegex);\n    }\n\n    @Override\n    public String getDefaultGlobPattern() {\n        //Normally just a parrot server result file; if using multiple\n        //user will need to add their own recognizable glob extensions\n        return \"parrot-server-stats.log\";\n    }\n\n    @Override\n    PerformanceReport parse(File reportFile) throws Exception {\n        final PerformanceReport report = createPerformanceReport();\n        report.setExcludeResponseTime(excludeResponseTime);\n        report.setShowTrendGraphs(showTrendGraphs);\n        report.setReportFileName(reportFile.getName());\n\n        try (FileReader fr = new FileReader(reportFile, StandardCharsets.UTF_8);\n             BufferedReader reader = new BufferedReader(fr)){\n            String line = reader.readLine();\n            while (line != null) {\n                final HttpSample sample = this.getSample(line, reportFile.getName());\n                String nextLine = reader.readLine();\n                if (sample != null) {\n                    report.addSample(sample);\n                }\n                line = nextLine;\n            }\n        }\n\n        return report;\n    }\n\n\n    /**\n     * Parses a line and return a HttpSample\n     * INF [20140611-21:34:01.224] stats: {\"400\":84,\"client\\/available\":1,\"client\\/cancelled_connects\":0,\"client\\/closechans\":85,\"client\\/closed\":85,\"client\\/closes\":84,\"client\\/codec_connection_preparation_latency_ms_average\":3,\"client\\/codec_connection_preparation_latency_ms_count\":85,\"client\\/codec_connection_preparation_latency_ms_maximum\":142,\"client\\/codec_connection_preparation_latency_ms_minimum\":1,\"client\\/codec_connection_preparation_latency_ms_p50\":2,\"client\\/codec_connection_preparation_latency_ms_p90\":4,\"client\\/codec_connection_preparation_latency_ms_p95\":4,\"client\\/codec_connection_preparation_latency_ms_p99\":142,\"client\\/codec_connection_preparation_latency_ms_p999\":142,\"client\\/codec_connection_preparation_latency_ms_p9999\":142,\"client\\/codec_connection_preparation_latency_ms_sum\":316,\"client\\/connect_latency_ms_average\":2,\"client\\/connect_latency_ms_count\":85,\"client\\/connect_latency_ms_maximum\":142,\"client\\/connect_latency_ms_minimum\":0,\"client\\/connect_latency_ms_p50\":1,\"client\\/connect_latency_ms_p90\":2,\"client\\/connect_latency_ms_p95\":4,\"client\\/connect_latency_ms_p99\":142,\"client\\/connect_latency_ms_p999\":142,\"client\\/connect_latency_ms_p9999\":142,\"client\\/connect_latency_ms_sum\":238,\"client\\/connection_duration_average\":5,\"client\\/connection_duration_count\":85,\"client\\/connection_duration_maximum\":173,\"client\\/connection_duration_minimum\":2,\"client\\/connection_duration_p50\":3,\"client\\/connection_duration_p90\":6,\"client\\/connection_duration_p95\":7,\"client\\/connection_duration_p99\":173,\"client\\/connection_duration_p999\":173,\"client\\/connection_duration_p9999\":173,\"client\\/connection_duration_sum\":477,\"client\\/connection_received_bytes_average\":604,\"client\\/connection_received_bytes_count\":85,\"client\\/connection_received_bytes_maximum\":576,\"client\\/connection_received_bytes_minimum\":576,\"client\\/connection_received_bytes_p50\":576,\"client\\/connection_received_bytes_p90\":576,\"client\\/connection_received_bytes_p95\":576,\"client\\/connection_received_bytes_p99\":576,\"client\\/connection_received_bytes_p999\":576,\"client\\/connection_received_bytes_p9999\":576,\"client\\/connection_received_bytes_sum\":51340,\"client\\/connection_requests_average\":1,\"client\\/connection_requests_count\":85,\"client\\/connection_requests_maximum\":1,\"client\\/connection_requests_minimum\":1,\"client\\/connection_requests_p50\":1,\"client\\/connection_requests_p90\":1,\"client\\/connection_requests_p95\":1,\"client\\/connection_requests_p99\":1,\"client\\/connection_requests_p999\":1,\"client\\/connection_requests_p9999\":1,\"client\\/connection_requests_sum\":85,\"client\\/connection_sent_bytes_average\":140,\"client\\/connection_sent_bytes_count\":85,\"client\\/connection_sent_bytes_maximum\":142,\"client\\/connection_sent_bytes_minimum\":142,\"client\\/connection_sent_bytes_p50\":142,\"client\\/connection_sent_bytes_p90\":142,\"client\\/connection_sent_bytes_p95\":142,\"client\\/connection_sent_bytes_p99\":142,\"client\\/connection_sent_bytes_p999\":142,\"client\\/connection_sent_bytes_p9999\":142,\"client\\/connection_sent_bytes_sum\":11919,\"client\\/connections\":0,\"client\\/connects\":85,\"client\\/failed_connect_latency_ms_count\":0,\"client\\/failfast\":0,\"client\\/failfast\\/unhealthy_for_ms\":0,\"client\\/failfast\\/unhealthy_num_tries\":0,\"client\\/failures\":1,\"client\\/failures\\/com.twitter.finagle.ChannelClosedException\":1,\"client\\/idle\":0,\"client\\/jonatstr-dt-otc_80\\/available\":1,\"client\\/jonatstr-dt-otc_80\\/cancelled_connects\":0,\"client\\/jonatstr-dt-otc_80\\/closechans\":85,\"client\\/jonatstr-dt-otc_80\\/closed\":85,\"client\\/jonatstr-dt-otc_80\\/closes\":84,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_average\":2,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_count\":85,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_maximum\":142,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_minimum\":0,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_p50\":1,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_p90\":2,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_p95\":4,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_p99\":142,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_p999\":142,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_p9999\":142,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_sum\":238,\"client\\/jonatstr-dt-otc_80\\/connection_duration_average\":5,\"client\\/jonatstr-dt-otc_80\\/connection_duration_count\":85,\"client\\/jonatstr-dt-otc_80\\/connection_duration_maximum\":173,\"client\\/jonatstr-dt-otc_80\\/connection_duration_minimum\":2,\"client\\/jonatstr-dt-otc_80\\/connection_duration_p50\":3,\"client\\/jonatstr-dt-otc_80\\/connection_duration_p90\":6,\"client\\/jonatstr-dt-otc_80\\/connection_duration_p95\":7,\"client\\/jonatstr-dt-otc_80\\/connection_duration_p99\":173,\"client\\/jonatstr-dt-otc_80\\/connection_duration_p999\":173,\"client\\/jonatstr-dt-otc_80\\/connection_duration_p9999\":173,\"client\\/jonatstr-dt-otc_80\\/connection_duration_sum\":477,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_average\":604,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_count\":85,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_maximum\":576,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_minimum\":576,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_p50\":576,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_p90\":576,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_p95\":576,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_p99\":576,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_p999\":576,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_p9999\":576,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_sum\":51340,\"client\\/jonatstr-dt-otc_80\\/connection_requests_average\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_count\":85,\"client\\/jonatstr-dt-otc_80\\/connection_requests_maximum\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_minimum\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_p50\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_p90\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_p95\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_p99\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_p999\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_p9999\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_sum\":85,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_average\":140,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_count\":85,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_maximum\":142,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_minimum\":142,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_p50\":142,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_p90\":142,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_p95\":142,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_p99\":142,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_p999\":142,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_p9999\":142,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_sum\":11919,\"client\\/jonatstr-dt-otc_80\\/connections\":0,\"client\\/jonatstr-dt-otc_80\\/connects\":85,\"client\\/jonatstr-dt-otc_80\\/failed_connect_latency_ms_count\":0,\"client\\/jonatstr-dt-otc_80\\/failfast\":0,\"client\\/jonatstr-dt-otc_80\\/failfast\\/unhealthy_for_ms\":0,\"client\\/jonatstr-dt-otc_80\\/failfast\\/unhealthy_num_tries\":0,\"client\\/jonatstr-dt-otc_80\\/failures\":1,\"client\\/jonatstr-dt-otc_80\\/failures\\/com.twitter.finagle.ChannelClosedException\":1,\"client\\/jonatstr-dt-otc_80\\/idle\":0,\"client\\/jonatstr-dt-otc_80\\/lifetime\":0,\"client\\/jonatstr-dt-otc_80\\/load\":0,\"client\\/jonatstr-dt-otc_80\\/pending\":0,\"client\\/jonatstr-dt-otc_80\\/pool_cached\":0,\"client\\/jonatstr-dt-otc_80\\/pool_num_waited\":0,\"client\\/jonatstr-dt-otc_80\\/pool_size\":0,\"client\\/jonatstr-dt-otc_80\\/pool_waiters\":0,\"client\\/jonatstr-dt-otc_80\\/received_bytes\":51340,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_average\":3,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_count\":85,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_maximum\":105,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_minimum\":1,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_p50\":2,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_p90\":4,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_p95\":4,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_p99\":105,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_p999\":105,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_p9999\":105,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_sum\":276,\"client\\/jonatstr-dt-otc_80\\/requests\":85,\"client\\/jonatstr-dt-otc_80\\/sent_bytes\":11919,\"client\\/jonatstr-dt-otc_80\\/socket_unwritable_ms\":0,\"client\\/jonatstr-dt-otc_80\\/socket_writable_ms\":207,\"client\\/jonatstr-dt-otc_80\\/success\":84,\"client\\/lifetime\":0,\"client\\/load\":0,\"client\\/loadbalancer\\/adds\":0,\"client\\/loadbalancer\\/available\":1,\"client\\/loadbalancer\\/load\":0,\"client\\/loadbalancer\\/removes\":0,\"client\\/loadbalancer\\/size\":1,\"client\\/pending\":0,\"client\\/pool_cached\":0,\"client\\/pool_num_waited\":0,\"client\\/pool_size\":0,\"client\\/pool_waiters\":0,\"client\\/received_bytes\":51340,\"client\\/request_latency_ms_average\":3,\"client\\/request_latency_ms_count\":85,\"client\\/request_latency_ms_maximum\":105,\"client\\/request_latency_ms_minimum\":1,\"client\\/request_latency_ms_p50\":2,\"client\\/request_latency_ms_p90\":4,\"client\\/request_latency_ms_p95\":4,\"client\\/request_latency_ms_p99\":105,\"client\\/request_latency_ms_p999\":105,\"client\\/request_latency_ms_p9999\":105,\"client\\/request_latency_ms_sum\":276,\"client\\/requests\":85,\"client\\/sent_bytes\":11919,\"client\\/socket_unwritable_ms\":0,\"client\\/socket_writable_ms\":207,\"client\\/success\":84,\"clock_error\":0,\"jvm_buffer_direct_count\":4,\"jvm_buffer_direct_max\":133120,\"jvm_buffer_direct_used\":133120,\"jvm_buffer_mapped_count\":0,\"jvm_buffer_mapped_max\":0,\"jvm_buffer_mapped_used\":0,\"jvm_current_mem_CMS_Old_Gen_max\":3657433088,\"jvm_current_mem_CMS_Old_Gen_used\":12173984,\"jvm_current_mem_CMS_Perm_Gen_max\":85983232,\"jvm_current_mem_CMS_Perm_Gen_used\":44355376,\"jvm_current_mem_Code_Cache_max\":50331648,\"jvm_current_mem_Code_Cache_used\":2425792,\"jvm_current_mem_Eden_Space_max\":429522944,\"jvm_current_mem_Eden_Space_used\":169518376,\"jvm_current_mem_Survivor_Space_max\":53673984,\"jvm_current_mem_Survivor_Space_used\":53673984,\"jvm_current_mem_used\":282147512,\"jvm_fd_count\":142,\"jvm_fd_limit\":4096,\"jvm_gc_ConcurrentMarkSweep_cycles\":0,\"jvm_gc_ConcurrentMarkSweep_msec\":0,\"jvm_gc_Copy_cycles\":0,\"jvm_gc_Copy_msec\":0,\"jvm_gc_cycles\":0,\"jvm_gc_msec\":0,\"jvm_heap_committed\":4140630016,\"jvm_heap_max\":4140630016,\"jvm_heap_used\":235366344,\"jvm_nonheap_committed\":47120384,\"jvm_nonheap_max\":136314880,\"jvm_nonheap_used\":46777704,\"jvm_num_cpus\":1,\"jvm_post_gc_CMS_Old_Gen_max\":3657433088,\"jvm_post_gc_CMS_Old_Gen_used\":0,\"jvm_post_gc_CMS_Perm_Gen_max\":85983232,\"jvm_post_gc_CMS_Perm_Gen_used\":0,\"jvm_post_gc_Eden_Space_max\":429522944,\"jvm_post_gc_Eden_Space_used\":0,\"jvm_post_gc_Survivor_Space_max\":53673984,\"jvm_post_gc_Survivor_Space_used\":53673984,\"jvm_post_gc_used\":53673984,\"jvm_start_time\":1402536778818,\"jvm_thread_count\":18,\"jvm_thread_daemon_count\":12,\"jvm_thread_peak_count\":18,\"jvm_uptime\":62216,\"queue_depth\":41,\"records-read\":126,\"requests_sent\":85,\"service\":\"parrot_web\",\"source\":\"jonatstr-dt-oneconnector\",\"timestamp\":1402536841,\"unexpected_error\":1,\"unexpected_error\\/com.twitter.finagle.ChannelClosedException\":1}\n     */\n    protected HttpSample getSample(String line, String key) throws ParseException, IllegalArgumentException {\n\n        HttpSample sample = new HttpSample();\n        Pattern pattern = Pattern.compile(\"^INF \\\\[(.+)\\\\] stats: (\\\\{.+\\\\})$\");\n        Matcher matcher = pattern.matcher(line);\n\n        //Should have group count of 2, the date and the stats json\n        if (!matcher.find()) {\n            throw new ParseException(\"Invalid line \" + line, 0);\n        }\n\n        String dateString = matcher.group(1);\n        String statsString = matcher.group(2);\n\n        //Get date object\n        SimpleDateFormat dateFormat = new SimpleDateFormat(STATS_DATE_FORMAT);\n        Date dateObject = dateFormat.parse(dateString);\n\n        //Now we need to parse the stats json\n        GsonBuilder gsonBuilder = new GsonBuilder();\n        StatsDeserializer deserializer = new StatsDeserializer();\n        gsonBuilder.registerTypeAdapter(Stats.class, deserializer);\n        Gson gson = gsonBuilder.create();\n\n        Stats statsObject = null;\n        try {\n            statsObject = gson.fromJson(statsString, Stats.class);\n        } catch (JsonParseException e) {\n            throw new IllegalArgumentException(\"Invalid stat data \" + statsString + \":\" + e.getLocalizedMessage());\n        }\n\n        //Set the sample data\n        sample.setDate(dateObject);\n        sample.setSummarizer(true);\n        sample.setSummarizerSamples(statsObject.getClientRequests()); // set SamplesCount\n        sample.setDuration(statsObject.getClientRequestLatencyMsAverage());\n        sample.setSuccessful(true);\n        sample.setSummarizerMin(statsObject.getClientRequestLatencyMsMinimum());\n        sample.setSummarizerMax(statsObject.getClientRequestLatencyMsMaximum());\n        sample.setSummarizerErrors((statsObject.getClientRequests() - statsObject.getClientSuccess()) \n                + statsObject.getSumValidationErrors());\n        sample.setUri(key);\n\n        return sample;\n    }\n\n    protected static class Stats {\n\n        @SerializedName(\"client/request_latency_ms_minimum\")\n        private long clientRequestLatencyMsMinimum = 0;\n        @SerializedName(\"client/request_latency_ms_maximum\")\n        private long clientRequestLatencyMsMaximum = 0;\n        @SerializedName(\"client/request_latency_ms_average\")\n        private long clientRequestLatencyMsAverage = 0;\n        @SerializedName(\"client/sent_bytes\")\n        private long clientSendBytes = 0;\n        @SerializedName(\"client/requests\")\n        private long clientRequests = 0;\n        @SerializedName(\"client/success\")\n        private long clientSuccess = 0;\n\n        //User defined validation errors\n        private Map<String, Long> validationErrors = new HashMap<>();\n\n        public Stats() {\n            super();\n        }\n\n        public long getClientRequestLatencyMsMinimum() {\n            return clientRequestLatencyMsMinimum;\n        }\n\n        public void setClientRequestLatencyMsMinimum(\n                long clientRequestLatencyMsMinimum) {\n            this.clientRequestLatencyMsMinimum = clientRequestLatencyMsMinimum;\n        }\n\n        public long getClientRequestLatencyMsMaximum() {\n            return clientRequestLatencyMsMaximum;\n        }\n\n        public void setClientRequestLatencyMsMaximum(\n                long clientRequestLatencyMsMaximum) {\n            this.clientRequestLatencyMsMaximum = clientRequestLatencyMsMaximum;\n        }\n\n        public long getClientRequestLatencyMsAverage() {\n            return clientRequestLatencyMsAverage;\n        }\n\n        public void setClientRequestLatencyMsAverage(\n                long clientRequestLatencyMsAverage) {\n            this.clientRequestLatencyMsAverage = clientRequestLatencyMsAverage;\n        }\n\n        public long getClientSendBytes() {\n            return clientSendBytes;\n        }\n\n        public void setClientSendBytes(long clientSendBytes) {\n            this.clientSendBytes = clientSendBytes;\n        }\n\n        public long getClientRequests() {\n            return clientRequests;\n        }\n\n        public void setClientRequests(long clientRequests) {\n            this.clientRequests = clientRequests;\n        }\n\n        public long getClientSuccess() {\n            return clientSuccess;\n        }\n\n        public void setClientSuccess(long clientSuccess) {\n            this.clientSuccess = clientSuccess;\n        }\n\n        public void addValidationError(String name, long value) {\n            synchronized (validationErrors) {\n                this.validationErrors.put(name, Long.valueOf(value));\n            }\n        }\n\n        public long getSumValidationErrors() {\n            long sumValidationErrors = 0;\n            synchronized (validationErrors) {\n                for (Long value : validationErrors.values()) {\n                    sumValidationErrors += value;\n                }\n            }\n            return sumValidationErrors;\n        }\n    }\n\n\n    /**\n     * A Stats Deserializer to verify during deserialization that\n     * all needed stats are available for the IagoParser and handle\n     * any special error fields that a user specified\n     *\n     * @author jwstric2\n     */\n    private static class StatsDeserializer implements JsonDeserializer<Stats> {\n\n        private static final String[] requiredFields = new String[]{\n                \"client/request_latency_ms_minimum\",\n                \"client/request_latency_ms_maximum\",\n                \"client/request_latency_ms_average\",\n                \"client/sent_bytes\",\n                \"client/requests\",\n                \"client/success\"};\n\n        public Stats deserialize(JsonElement json, Type typeOfT,\n                                 JsonDeserializationContext context) {\n            JsonObject jsonObject = (JsonObject) json;\n\n            //First, check we have all our required fields ..\n            for (String fieldName : requiredFields) {\n                if (jsonObject.get(fieldName) == null) {\n                    throw new JsonParseException(\"Required Field Not Found: \" + fieldName);\n                }\n            }\n\n            return new Gson().fromJson(json, Stats.class);\n        }\n\n    }\n}"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/parsers/JMeterCsvParser.java",
    "content": "package hudson.plugins.performance.parsers;\n\nimport java.io.*;\nimport java.nio.charset.StandardCharsets;\n\nimport edu.umd.cs.findbugs.annotations.SuppressFBWarnings;\nimport org.apache.commons.csv.CSVFormat;\nimport org.apache.commons.csv.CSVRecord;\nimport org.kohsuke.stapler.DataBoundConstructor;\n\nimport hudson.Extension;\nimport hudson.plugins.performance.data.HttpSample;\nimport hudson.plugins.performance.descriptors.PerformanceReportParserDescriptor;\nimport hudson.plugins.performance.reports.PerformanceReport;\n\npublic class JMeterCsvParser extends AbstractParser {\n\n    @SuppressFBWarnings(\"PA_PUBLIC_PRIMITIVE_ATTRIBUTE\")\n    public char delimiter;\n    @SuppressFBWarnings(\"PA_PUBLIC_PRIMITIVE_ATTRIBUTE\")\n    public int timestampIdx = -1;\n    @SuppressFBWarnings(\"PA_PUBLIC_PRIMITIVE_ATTRIBUTE\")\n    public int elapsedIdx = -1;\n    @SuppressFBWarnings(\"PA_PUBLIC_PRIMITIVE_ATTRIBUTE\")\n    public int responseCodeIdx = -1;\n    @SuppressFBWarnings(\"PA_PUBLIC_PRIMITIVE_ATTRIBUTE\")\n    public int successIdx = -1;\n    @SuppressFBWarnings(\"PA_PUBLIC_PRIMITIVE_ATTRIBUTE\")\n    public int urlIdx = -1;\n    @SuppressFBWarnings(\"PA_PUBLIC_PRIMITIVE_ATTRIBUTE\")\n    public int bytesIdx = -1;\n    @SuppressFBWarnings(\"PA_PUBLIC_PRIMITIVE_ATTRIBUTE\")\n    public int sentBytesIdx = -1;\n\n    public JMeterCsvParser(String glob, String percentiles) {\n        this(glob, percentiles, PerformanceReport.INCLUDE_ALL);\n    }\n\n    @DataBoundConstructor\n    public JMeterCsvParser(String glob, String percentiles, String filterRegex) {\n        super(glob, percentiles, filterRegex);\n    }\n\n    @Extension\n    public static class DescriptorImpl extends PerformanceReportParserDescriptor {\n        @Override\n        public String getDisplayName() {\n            return \"JMeterCSV\";\n        }\n    }\n\n    @Override\n    public String getDefaultGlobPattern() {\n        return \"**/*.csv\";\n    }\n\n    @Override\n    PerformanceReport parse(File reportFile) throws Exception {\n        clearDateFormat();\n\n        final PerformanceReport report = createPerformanceReport();\n        report.setExcludeResponseTime(excludeResponseTime);\n        report.setShowTrendGraphs(showTrendGraphs);\n        report.setReportFileName(reportFile.getName());\n\n        String[] header = null;\n        try (FileReader fr = new FileReader(reportFile, StandardCharsets.UTF_8);\n                BufferedReader reader = new BufferedReader(fr)) {\n            String line = reader.readLine();\n            if (line != null) {\n                header = readCSVHeader(line);\n            }\n        }\n        try (Reader fileReader = new InputStreamReader(new FileInputStream(reportFile), StandardCharsets.UTF_8)) {\n            parseCSV(fileReader, header, report);\n        }\n\n        return report;\n    }\n\n    protected void parseCSV(Reader in, String[] header, PerformanceReport report) throws IOException {\n        CSVFormat csvFormat = CSVFormat.Builder.create().setDelimiter(delimiter).setHeader(header).setQuote('\"')\n                .setSkipHeaderRecord(true).build();\n        Iterable<CSVRecord> records = csvFormat.parse(in);\n        for (CSVRecord record : records) {\n            final HttpSample sample = getSample(record);\n            report.addSample(sample);\n        }\n    }\n\n    protected String[] readCSVHeader(String line) {\n        this.delimiter = lookingForDelimiter(line);\n        final String[] header = line.split(String.valueOf(delimiter));\n        for (int i = 0; i < header.length; i++) {\n            String field = header[i];\n            if (\"timestamp\".equalsIgnoreCase(field)) {\n                timestampIdx = i;\n            } else if (\"elapsed\".equalsIgnoreCase(field)) {\n                elapsedIdx = i;\n            } else if (\"responseCode\".equalsIgnoreCase(field)) {\n                responseCodeIdx = i;\n            } else if (\"success\".equalsIgnoreCase(field)) {\n                successIdx = i;\n            } else if (\"bytes\".equalsIgnoreCase(field)) {\n                bytesIdx = i;\n            } else if (\"sentBytes\".equalsIgnoreCase(field)) {\n                sentBytesIdx = i;\n            } else if (\"URL\".equalsIgnoreCase(field) && urlIdx < 0) {\n                urlIdx = i;\n            } else if (\"label\".equalsIgnoreCase(field) && urlIdx < 0) {\n                urlIdx = i;\n            }\n        }\n\n        if (timestampIdx < 0 || elapsedIdx < 0 || responseCodeIdx < 0\n                || successIdx < 0 || urlIdx < 0 || bytesIdx < 0\n        // || sentBytesIdx < 0 // sentBytes was introduced in 3.1\n        ) {\n            throw new IllegalStateException(\"Missing required column\");\n        }\n\n        return header;\n    }\n\n    protected static char lookingForDelimiter(String line) {\n        for (char ch : line.toCharArray()) {\n            if (!Character.isLetter(ch)) {\n                return ch;\n            }\n        }\n        throw new IllegalStateException(\"Cannot find delimiter in header \" + line);\n    }\n\n    /**\n     * Parses a single HttpSample instance from a single CSV Record.\n     *\n     * @param record csv record from report file (cannot be null).\n     * @return An sample instance (never null).\n     */\n    private HttpSample getSample(CSVRecord record) {\n        final HttpSample sample = new HttpSample();\n        sample.setDate(parseTimestamp(record.get(timestampIdx)));\n        sample.setDuration(Long.parseLong(record.get(elapsedIdx)));\n        sample.setHttpCode(record.get(responseCodeIdx));\n        sample.setSuccessful(Boolean.parseBoolean(record.get(successIdx)));\n        long bytes = Long.parseLong(record.get(bytesIdx));\n        if (sentBytesIdx != -1) {\n            bytes += Long.parseLong(record.get(sentBytesIdx));\n        }\n        sample.setSizeInKb((double) bytes / 1024d);\n        sample.setUri(record.get(urlIdx));\n        return sample;\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/parsers/JMeterParser.java",
    "content": "package hudson.plugins.performance.parsers;\n\nimport java.io.BufferedReader;\nimport java.io.File;\nimport java.io.FileReader;\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Date;\n\nimport javax.xml.parsers.SAXParserFactory;\n\nimport org.kohsuke.stapler.DataBoundConstructor;\nimport org.xml.sax.Attributes;\nimport org.xml.sax.SAXException;\nimport org.xml.sax.helpers.DefaultHandler;\n\nimport hudson.Extension;\nimport hudson.plugins.performance.data.HttpSample;\nimport hudson.plugins.performance.descriptors.PerformanceReportParserDescriptor;\nimport hudson.plugins.performance.reports.PerformanceReport;\n\n/**\n * Parser for JMeter.\n *\n * @author Kohsuke Kawaguchi\n */\npublic class JMeterParser extends AbstractParser {\n\n    @Extension\n    public static class DescriptorImpl extends PerformanceReportParserDescriptor {\n        @Override\n        public String getDisplayName() {\n            return \"JMeter\";\n        }\n    }\n\n\n    public JMeterParser(String glob, String percentiles) {\n        super(glob, percentiles, PerformanceReport.INCLUDE_ALL);\n    }\n    \n    @DataBoundConstructor\n    public JMeterParser(String glob, String percentiles, String filterRegex) {\n        super(glob, percentiles, filterRegex);\n    }\n\n    @Override\n    public String getDefaultGlobPattern() {\n        return \"**/*.jtl\";\n    }\n\n    PerformanceReport parse(File reportFile) throws Exception {\n        // JMeter stores either CSV or XML in .JTL files.\n        final boolean isXml = isXmlFile(reportFile);\n\n        if (isXml) {\n            return parseXml(reportFile);\n        } else {\n            return parseCsv(reportFile);\n        }\n    }\n\n    /**\n     * Utility method that checks if the provided file has XML content.\n     * <p>\n     * This implementation looks for the first non-empty file. If an XML prolog appears there, this method returns <code>true</code>, otherwise <code>false</code> is returned.\n     *\n     * @param file File from which the content is to e analyzed. Cannot be null.\n     * @return <code>true</code> if the file content has been determined to be XML, otherwise <code>false</code>.\n     */\n    public static boolean isXmlFile(File file) throws IOException {\n        try (FileReader fr = new FileReader(file, StandardCharsets.UTF_8);\n                BufferedReader reader = new BufferedReader(fr)) {\n            String line;\n            boolean isXml = false;\n            while ((line = reader.readLine()) != null) {\n                if (line.trim().length() == 0) {\n                    continue; // skip empty lines.\n                } \n                if (line.toLowerCase().trim().startsWith(\"<?xml \")) {\n                    isXml = true;\n                }\n                break;\n            }\n            return isXml;\n        }\n    }\n\n    /**\n     * A delegate for {@link #parse(File)} that can process XML data.\n     */\n    PerformanceReport parseXml(File reportFile) throws Exception {\n        final SAXParserFactory factory = SAXParserFactory.newInstance();\n        factory.setFeature(\"http://apache.org/xml/features/disallow-doctype-decl\", true);\n        factory.setValidating(false);\n        factory.setNamespaceAware(false);\n\n        final PerformanceReport report = createPerformanceReport();\n        report.setExcludeResponseTime(excludeResponseTime);\n        report.setShowTrendGraphs(showTrendGraphs);\n        report.setReportFileName(reportFile.getName());\n\n        factory.newSAXParser().parse(reportFile, new DefaultHandler() {\n            HttpSample currentSample;\n            int counter = 0;\n\n            /**\n             * Performance XML log format is in http://jakarta.apache.org/jmeter/usermanual/listeners.html\n             *\n             * There are two different tags which delimit jmeter samples:\n             * - httpSample for http samples\n             * - sample for non http samples\n             *\n             * There are also two different XML formats which we have to handle:\n             * v2.0 = \"label\", \"timeStamp\", \"time\", \"success\"\n             * v2.1 = \"lb\", \"ts\", \"t\", \"s\"\n             */\n            @Override\n            public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {\n                if (!\"httpSample\".equalsIgnoreCase(qName) && !\"sample\".equalsIgnoreCase(qName)) {\n                    return;\n                }\n\n                final HttpSample sample = new HttpSample();\n\n                final String dateValue;\n                if (attributes.getValue(\"ts\") != null) {\n                    dateValue = attributes.getValue(\"ts\");\n                } else {\n                    dateValue = attributes.getValue(\"timeStamp\");\n                }\n                sample.setDate(new Date(Long.parseLong(dateValue)));\n\n                final String durationValue;\n                if (attributes.getValue(\"t\") != null) {\n                    durationValue = attributes.getValue(\"t\");\n                } else {\n                    durationValue = attributes.getValue(\"time\");\n                }\n                sample.setDuration(Long.parseLong(durationValue));\n\n                final String successfulValue;\n                if (attributes.getValue(\"s\") != null) {\n                    successfulValue = attributes.getValue(\"s\");\n                } else {\n                    successfulValue = attributes.getValue(\"success\");\n                }\n                sample.setSuccessful(Boolean.parseBoolean(successfulValue));\n\n                final String uriValue;\n                if (attributes.getValue(\"lb\") != null) {\n                    uriValue = attributes.getValue(\"lb\");\n                } else {\n                    uriValue = attributes.getValue(\"label\");\n                }\n                sample.setUri(uriValue);\n\n                final String httpCodeValue;\n                if (attributes.getValue(\"rc\") != null && attributes.getValue(\"rc\").length() <= 3) {\n                    httpCodeValue = attributes.getValue(\"rc\");\n                } else {\n                    httpCodeValue = \"0\";\n                }\n                sample.setHttpCode(httpCodeValue);\n\n                final String sizeInKbValue;\n                if (attributes.getValue(\"by\") != null) {\n                    sizeInKbValue = attributes.getValue(\"by\");\n                } else {\n                    sizeInKbValue = \"0\";\n                }\n                sample.setSizeInKb(Double.parseDouble(sizeInKbValue) / 1024d);\n\n                if (counter == 0) {\n                    currentSample = sample;\n                }\n                counter++;\n            }\n\n            @Override\n            public void endElement(String uri, String localName, String qName) {\n                if (\"httpSample\".equalsIgnoreCase(qName) || \"sample\".equalsIgnoreCase(qName)) {\n                    if (counter == 1) {\n                        report.addSample(currentSample);\n                    }\n                    counter--;\n                }\n            }\n        });\n\n        return report;\n    }\n\n    /**\n     * A delegate for {@link #parse(File)} that can process CSV data.\n     */\n    PerformanceReport parseCsv(File reportFile) throws Exception {\n        final JMeterCsvParser delegate = new JMeterCsvParser(this.glob, this.percentiles, this.filterRegex);\n        return delegate.parse(reportFile);\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/parsers/JUnitParser.java",
    "content": "package hudson.plugins.performance.parsers;\n\nimport hudson.Extension;\nimport hudson.plugins.performance.data.HttpSample;\nimport hudson.plugins.performance.descriptors.PerformanceReportParserDescriptor;\nimport hudson.plugins.performance.reports.PerformanceReport;\n\nimport org.kohsuke.stapler.DataBoundConstructor;\nimport org.xml.sax.Attributes;\nimport org.xml.sax.SAXException;\nimport org.xml.sax.helpers.DefaultHandler;\n\nimport javax.xml.parsers.SAXParser;\nimport javax.xml.parsers.SAXParserFactory;\nimport java.io.File;\nimport java.util.Date;\nimport java.text.SimpleDateFormat;\n\n/**\n * Parser for JUnit.\n *\n * @author Manuel Carrasco\n */\npublic class JUnitParser extends AbstractParser {\n\n    public static final String ISO8601_DATETIME_PATTERN = \"yyyy-MM-dd'T'HH:mm:ss\";\n    \n    @Extension\n    public static class DescriptorImpl extends PerformanceReportParserDescriptor {\n        @Override\n        public String getDisplayName() {\n            return \"JUnit\";\n        }\n    }\n\n    public JUnitParser(String glob, String percentiles) {\n        super(glob, percentiles, PerformanceReport.INCLUDE_ALL);\n    }\n    \n    @DataBoundConstructor\n    public JUnitParser(String glob, String percentiles, String filterRegex) {\n        super(glob, percentiles, filterRegex);\n    }\n\n    @Override\n    public String getDefaultGlobPattern() {\n        return \"**/TEST-*.xml\";\n    }\n\n    @Override\n    PerformanceReport parse(File reportFile) throws Exception {\n\n        final SAXParserFactory factory = SAXParserFactory.newInstance();\n        factory.setFeature(\"http://apache.org/xml/features/disallow-doctype-decl\", true);\n        factory.setValidating(false);\n        factory.setNamespaceAware(false);\n\n        final SAXParser parser = factory.newSAXParser();\n        final PerformanceReport report = createPerformanceReport();\n        report.setExcludeResponseTime(excludeResponseTime);\n        report.setShowTrendGraphs(showTrendGraphs);\n        report.setReportFileName(reportFile.getName());\n        parser.parse(reportFile, new DefaultHandler() {\n            private HttpSample currentSample;\n            private int status;\n\n            @Override\n            public void endElement(String uri, String localName, String qName) throws SAXException {\n                if ((\"testsuite\".equalsIgnoreCase(qName) || \"testcase\".equalsIgnoreCase(qName)) && status != 0) {\n                    report.addSample(currentSample);\n                    status = 0;\n                }\n            }\n\n            /**\n             * JUnit XML format is: tag \"testcase\" with attributes: \"name\" and\n             * \"time\". If there is one error, there is an other tag, \"failure\"\n             * inside testcase tag. SOAPUI uses JUnit format\n             */\n            @Override\n            public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {\n                if (\"testcase\".equalsIgnoreCase(qName)) {\n                    if (status != 0) {\n                        report.addSample(currentSample);\n                    }\n                    status = 1;\n                    currentSample = new HttpSample();\n                    try {\n                    \tString timestamp = attributes.getValue(\"timestamp\");\n\t\t\tcurrentSample.setDate(new SimpleDateFormat(ISO8601_DATETIME_PATTERN).parse(timestamp));\n\t\t    } catch (Exception e) {\n\t\t\tcurrentSample.setDate(new Date(0));\n\t\t    }\n                    String time = attributes.getValue(\"time\");\n                    currentSample.setDuration(parseDuration(time));\n                    currentSample.setSuccessful(true);\n                    currentSample.setUri(attributes.getValue(\"classname\") + \".\" + attributes.getValue(\"name\"));\n                    currentSample.setErrorObtained(false);\n                } else if (\"failure\".equalsIgnoreCase(qName) && status != 0) {\n                    currentSample.setErrorObtained(false);\n                    currentSample.setSuccessful(false);\n                    report.addSample(currentSample);\n                    status = 0;\n                } else if (\"error\".equalsIgnoreCase(qName) && status != 0) {\n                    currentSample.setErrorObtained(true);\n                    currentSample.setSuccessful(false);\n                    report.addSample(currentSample);\n                    status = 0;\n                }\n            }\n        });\n        return report;\n    }\n\n    /**\n     * Strips any commas from <code>time</code>, then parses it into a long.\n     */\n    static long parseDuration(final String time) {\n        if (time == null || time.isEmpty()) {\n            return 0;\n        } else {\n            // don't want commas or else will break on parse.\n            final double duration = Double.parseDouble(time.replaceAll(\",\", \"\"));\n            return (long) (duration * 1000);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/parsers/JmeterSummarizerParser.java",
    "content": "package hudson.plugins.performance.parsers;\n\nimport java.io.File;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Scanner;\nimport java.util.regex.Pattern;\n\nimport org.kohsuke.stapler.DataBoundConstructor;\n\nimport hudson.Extension;\nimport hudson.plugins.performance.data.HttpSample;\nimport hudson.plugins.performance.descriptors.PerformanceReportParserDescriptor;\nimport hudson.plugins.performance.reports.PerformanceReport;\n\n/**\n * Parses JMeter Summarized results\n *\n * @author Agoley\n */\npublic class JmeterSummarizerParser extends AbstractParser {\n\n    @Extension\n    public static class DescriptorImpl extends PerformanceReportParserDescriptor {\n        @Override\n        public String getDisplayName() {\n            return \"JmeterSummarizer\";\n        }\n    }\n\n\n    public JmeterSummarizerParser(String glob, String percentiles) {\n        super(glob, percentiles, PerformanceReport.INCLUDE_ALL);\n    }\n    \n    @DataBoundConstructor\n    public JmeterSummarizerParser(String glob, String percentiles, String filterRegex) {\n        super(glob, percentiles, filterRegex);\n    }\n\n    @Override\n    public String getDefaultGlobPattern() {\n        return \"**/*.log\";\n    }\n\n    @Override\n    PerformanceReport parse(File reportFile) throws Exception {\n        clearDateFormat();\n\n        final PerformanceReport report = createPerformanceReport();\n        report.setExcludeResponseTime(excludeResponseTime);\n        report.setShowTrendGraphs(showTrendGraphs);\n        report.setReportFileName(reportFile.getName());\n        try (Scanner fileScanner = new Scanner(reportFile, StandardCharsets.UTF_8)){\n            String line;\n            String lastEqualsLine = null;\n            while (fileScanner.hasNextLine()) {\n                line = fileScanner.nextLine();\n                if (line.contains(\"=\") && line.contains(\"Summariser:\")) {\n                    lastEqualsLine = line;\n                }\n            }\n\n            long reportSamples = Long.MIN_VALUE;\n            long reportAvg = Long.MIN_VALUE;\n            long reportMin = Long.MAX_VALUE;\n            long reportMax = Long.MIN_VALUE;\n            String reportErrorPercent = \"\";\n            if (lastEqualsLine != null) {\n                try (Scanner lineScanner = new Scanner(lastEqualsLine)) {\n                    final Pattern delimiter = lineScanner.delimiter();\n                    lineScanner.useDelimiter(\"INFO\"); // as jmeter logs INFO mode\n                    final HttpSample sample = new HttpSample();\n                    final String dateString = lineScanner.next();\n                    sample.setDate(parseTimestamp(dateString));\n                    lineScanner.findInLine(\"Summariser:\");\n                    lineScanner.useDelimiter(\"\\\\=\");\n                    String key = lineScanner.next().trim();\n                    lineScanner.useDelimiter(delimiter);\n                    lineScanner.next();\n                    reportSamples = lineScanner.nextLong();\n                    sample.setSummarizerSamples(reportSamples); // set SamplesCount\n                    sample.setSummarizer(true);\n                    lineScanner.findInLine(\"Avg:\"); // set response time\n                    sample.setDuration(lineScanner.nextLong());\n                    reportAvg = sample.getDuration();\n                    sample.setSuccessful(true);\n\n                    lineScanner.findInLine(\"Min:\"); // set MIN\n                    long sampleMin = lineScanner.nextLong();\n                    sample.setSummarizerMin(sampleMin);\n                    reportMin = Math.min(reportMin, sampleMin);\n\n                    lineScanner.findInLine(\"Max:\"); // set MAX\n                    long sampleMax = lineScanner.nextLong();\n                    sample.setSummarizerMax(sampleMax);\n                    reportMax = Math.max(reportMax, sampleMax);\n\n                    lineScanner.findInLine(\"Err:\"); // set errors count\n                    lineScanner.findInLine(\"\\\\(\"); // set errors count\n                    lineScanner.useDelimiter(\"%\");\n                    reportErrorPercent = lineScanner.next();\n                    sample.setSummarizerErrors(Float.parseFloat(reportErrorPercent));\n                    // sample.setSummarizerErrors(\n                    // Float.valueOf(scanner.next().replaceAll(\"[()%]\",\"\")));\n                    sample.setUri(key);\n                    report.addSample(sample);\n                }\n            }\n\n            report.setSummarizerSize(reportSamples);\n            report.setSummarizerAvg(reportAvg);\n            report.setSummarizerMin(reportMin);\n            report.setSummarizerMax(reportMax);\n            report.setSummarizerErrors(reportErrorPercent);\n\n            return report;\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/parsers/LoadRunnerParser.java",
    "content": "package hudson.plugins.performance.parsers;\n\nimport hudson.Extension;\nimport hudson.plugins.performance.data.HttpSample;\nimport hudson.plugins.performance.descriptors.PerformanceReportParserDescriptor;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport org.kohsuke.stapler.DataBoundConstructor;\n\nimport java.io.File;\nimport java.sql.Connection;\nimport java.sql.DriverManager;\nimport java.sql.ResultSet;\nimport java.sql.SQLException;\nimport java.sql.Statement;\nimport java.util.Date;\nimport java.util.TimeZone;\n\n/** Parser for LoadRunner Analysis results stored in an MS Access database (*.mdb file).\n * \n * Reference https://community.saas.hpe.com/t5/Performance-Center-Practitioners/Regarding-Event-meter-table-in-LoadRunner-session-MS-ACCESS/td-p/566738\n */\npublic class LoadRunnerParser extends AbstractParser {\n\n    private String resultQuery = \n        \"select \"+\n        \"    cast(([Start Time] + e.[End Time] - e.Value)*1000 as decimal) as timeStamp, \"+\n        \"    cast(e.Value*1000 as decimal) as elapsed, \"+\n        \"    [Event Name] as label, \"+\n        \"    case [Transaction End Status] when 'Pass' then 'true' end as success \"+\n        \"from Event_meter e \"+\n        \"join Event_map on Event_map.[Event ID] = e.[Event ID] \"+\n        \"join TransactionEndStatus on TransactionEndStatus.Status1 = e.Status1 \"+\n        \"join Result on Result.[Result ID] = e.[Result ID]\"+\n        \"where [Event Type] = 'Transaction'\";\n\n    public LoadRunnerParser(String glob, String percentiles) {\n        super(glob, percentiles, PerformanceReport.INCLUDE_ALL);\n    }\n    \n    @DataBoundConstructor\n    public LoadRunnerParser(String glob, String percentiles, String filterRegex) {\n        super(glob, percentiles, filterRegex);\n    }\n\n    @Extension\n    public static class DescriptorImpl extends PerformanceReportParserDescriptor {\n        @Override\n        public String getDisplayName() {\n            return \"LoadRunner\";\n        }\n    }\n\n    @Override\n    public String getDefaultGlobPattern() {\n        return \"**/*.mdb\";\n    }\n\n    protected String jdbcUrlForFile(File reportFile) throws ClassNotFoundException {\n        Class.forName(\"net.ucanaccess.jdbc.UcanaccessDriver\");\n        return String.format(\"jdbc:ucanaccess://%s;mirrorFolder=java.io.tmpdir;immediatelyReleaseResources=true\", reportFile.getAbsolutePath());\n    }\n\n    protected HttpSample getSample(ResultSet res) throws SQLException {\n        HttpSample sample = new HttpSample();\n        Date sampleTime = new Date(res.getLong(1));\n        // Fix LoadRunner times that are off by 1 hour when in DST:\n        if (TimeZone.getTimeZone(System.getProperty(\"user.timezone\")).inDaylightTime(sampleTime)) {\n            sampleTime = new Date(res.getLong(1)-3600000L);\n        }\n        sample.setDate(sampleTime);\n        sample.setDuration(res.getLong(2));\n        sample.setUri(res.getString(3));\n        sample.setSuccessful(Boolean.parseBoolean(res.getString(4)));\n        return sample;\n    }\n\n    @Override\n    PerformanceReport parse(File reportFile) throws Exception {\n        final PerformanceReport report = createPerformanceReport();\n        report.setExcludeResponseTime(excludeResponseTime);\n        report.setShowTrendGraphs(showTrendGraphs);\n        report.setReportFileName(reportFile.getName());\n\n        try (Connection con = DriverManager.getConnection(jdbcUrlForFile(reportFile));\n            Statement stmt = con.createStatement(); \n            ResultSet res = stmt.executeQuery(getResultQuery())) {\n\n            while (res.next()) {\n                report.addSample(getSample(res));\n            }\n        }\n        return report;\n    }\n\n    protected String getResultQuery() {\n        return resultQuery;\n    }\n\n    protected void setResultQuery(String resultQuery) {\n        this.resultQuery = resultQuery;\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/parsers/LocustParser.java",
    "content": "package hudson.plugins.performance.parsers;\n\nimport hudson.Extension;\nimport hudson.plugins.performance.data.HttpSample;\nimport hudson.plugins.performance.descriptors.PerformanceReportParserDescriptor;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport org.apache.commons.csv.CSVFormat;\nimport org.apache.commons.csv.CSVParser;\nimport org.apache.commons.csv.CSVRecord;\n\nimport java.io.*;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Date;\nimport java.util.List;\nimport org.kohsuke.stapler.DataBoundConstructor;\n\npublic class LocustParser extends AbstractParser {\n    enum ReportColumns {\n        Type(0), Name(1), Requests(2), Failures(3), Median(4),\n        Average(5), Min(6), Max(7), AvgContentSize(8), Rps(9);\n\n        int column;\n\n        ReportColumns(final int order) {\n            this.column = order;\n        }\n\n        int getColumn() {\n            return column;\n        }\n    }\n\n    public LocustParser(String glob, String percentiles) {\n        super(glob, percentiles, PerformanceReport.INCLUDE_ALL);\n    }\n\n    @DataBoundConstructor\n    public LocustParser(String glob, String percentiles, String filterRegex) {\n        super(glob, percentiles, filterRegex);\n    }\n\n    @Extension\n    public static class DescriptorImpl extends PerformanceReportParserDescriptor {\n        @Override\n        public String getDisplayName() {\n            return \"Locust\";\n        }\n    }\n\n    @Override\n    PerformanceReport parse(final File reportFile) throws Exception {\n        PerformanceReport report = createPerformanceReport();\n        report.setReportFileName(reportFile.getName());\n        report.setExcludeResponseTime(excludeResponseTime);\n        report.setShowTrendGraphs(showTrendGraphs);\n        List<CSVRecord> reportData = getCsvData(reportFile);\n        final Date now = new Date();\n\n        for (CSVRecord record : reportData) {\n            String name = record.get(ReportColumns.Name.getColumn());\n            long average = Double.valueOf(record.get(ReportColumns.Average.getColumn())).longValue();\n            long min = Double.valueOf(record.get(ReportColumns.Min.getColumn())).longValue();\n            long max = Double.valueOf(record.get(ReportColumns.Max.getColumn())).longValue();\n            long failures = Double.valueOf(record.get(ReportColumns.Failures.getColumn())).longValue();\n            long success = Double.valueOf(record.get(ReportColumns.Requests.getColumn())).longValue();\n            long errors = (long) ((double) failures / success);\n            long avgContentSize = Double.valueOf(record.get(ReportColumns.AvgContentSize.getColumn())).longValue();\n\n            if (name.equals(\"Aggregated\")) {\n                report.setSummarizerSize(reportData.size() - 1);\n                report.setSummarizerAvg(average);\n                report.setSummarizerMin(min);\n                report.setSummarizerMax(max);\n                report.setSummarizerErrors(Float.toString(errors));\n            } else {\n                HttpSample sample = new HttpSample();\n                sample.setSuccessful(failures == 0);\n                sample.setSummarizer(true);\n                sample.setUri(name);\n                sample.setSummarizerMax(max);\n                sample.setSummarizerMin(min);\n                sample.setDuration(average);\n                sample.setSummarizerSamples(success);\n                sample.setSummarizerErrors(errors);\n                sample.setSizeInKb(avgContentSize * success);\n                sample.setDate(now);\n                report.addSample(sample);\n            }\n        }\n\n        return report;\n    }\n\n    List<CSVRecord> getCsvData(final File reportFile) {\n        List<CSVRecord> records = null;\n        try (Reader reader = new BufferedReader(new InputStreamReader(new FileInputStream(reportFile), StandardCharsets.UTF_8));\n             CSVParser csvParser = new CSVParser(reader, CSVFormat.Builder.create(CSVFormat.DEFAULT).setHeader().build())) {\n            records = csvParser.getRecords();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n        return records;\n    }\n\n    @Override\n    public String getDefaultGlobPattern() {\n        return \"**/*_stats.csv\";\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/parsers/ParserDetector.java",
    "content": "package hudson.plugins.performance.parsers;\n\nimport java.io.*;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Arrays;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\nimport javax.xml.stream.XMLEventReader;\nimport javax.xml.stream.XMLInputFactory;\nimport javax.xml.stream.XMLStreamException;\nimport javax.xml.stream.events.StartElement;\nimport javax.xml.stream.events.XMLEvent;\n\nimport com.google.common.annotations.VisibleForTesting;\n\n/**\n * Auto-detect parser for file\n */\npublic class ParserDetector {\n\n    private ParserDetector() {\n        super();\n    }\n    /**\n     * Detect report file type using file content.\n     * @return report file type.\n     */\n    public static String detect(String reportPath) throws IOException {\n        try (final BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(new File(reportPath)), StandardCharsets.UTF_8))) {\n            String line = reader.readLine();\n            if (line == null) {\n                throw new IllegalArgumentException(\"File \" + reportPath + \" is empty\");\n            }\n\n            if (line.startsWith(\"<?xml\")) {\n                return detectXMLFileType(reportPath);\n            } else if (isIagoFileType(line)) {\n                return IagoParser.class.getSimpleName();\n            } else if (isWRKFileType(line)) {\n                return WrkSummarizerParser.class.getSimpleName();\n            } else if (isJMeterCSVFileType(line)) {\n                return JMeterCsvParser.class.getSimpleName();\n            } else if (isJMeterSummarizerFileType(line, reader)) {\n                return JmeterSummarizerParser.class.getSimpleName();\n            } else if (isLoadRunnerFileType(line)) {\n                return LoadRunnerParser.class.getSimpleName();\n            } else if (isLocustFileType(line)) {\n                return LocustParser.class.getSimpleName();\n            } else {\n                try {\n                    return detectXMLFileType(reportPath);\n                } catch (IllegalArgumentException | IllegalStateException ex) {\n                    throw new IllegalArgumentException(\"Can not detect file type: \" + reportPath, ex);\n                }\n            }\n        }\n    }\n\n    /**\n     * Detect Iago report type using pattern \"INF \\[.*\\] stats:.*\n     */\n    private static boolean isIagoFileType(String line) {\n        String patternString = \"INF \\\\[.*\\\\] stats:.*\";\n\n        Pattern pattern = Pattern.compile(patternString);\n\n        Matcher matcher = pattern.matcher(line);\n        return matcher.matches();\n    }\n\n    /**\n     * Detect WRK report type using pattern \"Running .*s test @.*\"\n     */\n    private static boolean isWRKFileType(String line) {\n        String patternString = \"Running .*s test @.*\";\n\n        Pattern pattern = Pattern.compile(patternString);\n\n        Matcher matcher = pattern.matcher(line);\n        return matcher.matches();\n    }\n\n    /**\n     * Detect JMeterCSV report type using the search of main columns in CSV header,\n     *  such as timestamp, elapsed and url/label\n     */\n    private static boolean isJMeterCSVFileType(String header) {\n        String line = header.toLowerCase();\n        return (line.contains(\"timestamp\") && line.contains(\"elapsed\") &&\n                (line.contains(\"url\") || line.contains(\"label\")));\n    }\n\n    /**\n     * Detect JMeterSummarizer report type.\n     * Read file, until It find a string \"jmeter.reporters.Summariser: Generate Summary Results\"\n     */\n    private static boolean isJMeterSummarizerFileType(String firstLine, final BufferedReader reader) throws IOException {\n        String pattern = \"Summariser: Generate Summary Results\";\n        String line = firstLine;\n        if (line.contains(pattern)) {\n            return true;\n        }\n\n        line = reader.readLine();\n        while (line != null) {\n            if (line.contains(pattern)) {\n                return true;\n            }\n            line = reader.readLine();\n        }\n        return false;\n    }\n\n    /**\n     * Detect LoadRunner MDB file using MS Access magic pattern.\n     * http://www.garykessler.net/library/file_sigs.html\n     */\n    private static boolean isLoadRunnerFileType(String line) {\n        String pattern = new String(new char[]{0x00, 0x01, 0x00, 0x00})+\"Standard Jet DB\";\n\n        return line.length() > pattern.length() &&\n            pattern.equals(line.substring(0, pattern.length()));\n    }\n\n    /**\n     * Detect XML report type using the search of the first opening xml-tag.\n     *  <testResults> - JMETER;\n     *  <testsuite> - JUNIT;\n     *  <FinalStatus> - TAURUS.\n     */\n    private static String detectXMLFileType(String reportPath) throws IOException {\n        try (InputStream in = new FileInputStream(reportPath)) {\n            return detectXMLFileType(in);\n        } catch (Exception ex) {\n            throw new IllegalStateException(\"XML parsing error: \", ex);\n        }\n    }\n\n    @VisibleForTesting\n    protected static String detectXMLFileType(final InputStream in) throws XMLStreamException {\n        XMLInputFactory inputFactory = XMLInputFactory.newInstance();\n        inputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false);\n        XMLEventReader eventReader = inputFactory.createXMLEventReader(in);\n\n        while (eventReader.hasNext()) {\n            XMLEvent event = eventReader.nextEvent();\n            if (event.isStartElement()) {\n                StartElement startElement = event.asStartElement();\n                String name = startElement.getName().getLocalPart();\n\n                switch (name) {\n                case \"testResults\":\n                    return JMeterParser.class.getSimpleName();\n                case \"testsuite\":\n                case \"testsuites\":\n                    return JUnitParser.class.getSimpleName();\n                case \"FinalStatus\":\n                    return TaurusParser.class.getSimpleName();\n                default:\n                    throw new IllegalArgumentException(\"Unknown xml file format\");\n                }\n            }\n        }\n        throw new IllegalStateException(\"XML parsing error: no start element\");\n    }\n\n    /**\n     * Detect Locust report type using verification of csv header. Header names and order is asserted.\n     * @param line - single report file line\n     * @return true if Locust expected header found\n     */\n    private static boolean isLocustFileType(String line) {\n        String[] fileLineHeader = line.replaceAll(\"\\\"\", \"\").split(\",\");\n        String[] expectedHeaderFields = new String[]{\"Type\", \"Name\", \"Request Count\", \"Failure Count\",\n                \"Median Response Time\", \"Average Response Time\", \"Min Response Time\", \"Max Response Time\",\n                \"Average Content Size\", \"Requests/s\"};\n        return (Arrays.asList(fileLineHeader).containsAll(Arrays.asList(expectedHeaderFields)));\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/parsers/ParserFactory.java",
    "content": "package hudson.plugins.performance.parsers;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.PrintStream;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\nimport hudson.EnvVars;\nimport hudson.FilePath;\nimport hudson.model.Run;\n\npublic class ParserFactory {\n    private static final Logger LOGGER = Logger.getLogger(ParserFactory.class.getName());\n\n    protected static final Map<String, String> defaultGlobPatterns = Collections.synchronizedMap(new HashMap<String, String>());\n    private static final String TEMP_FOLDER = \"/temp/\";\n    static {\n        defaultGlobPatterns.put(\"parrot-server-stats.log\", IagoParser.class.getSimpleName());\n        defaultGlobPatterns.put(\"**/*.csv\", JMeterCsvParser.class.getSimpleName());\n        defaultGlobPatterns.put(\"**/*.jtl\", JMeterParser.class.getSimpleName());\n        defaultGlobPatterns.put(\"**/*.log\", JmeterSummarizerParser.class.getSimpleName());\n        defaultGlobPatterns.put(\"**/TEST-*.xml\", JUnitParser.class.getSimpleName());\n        defaultGlobPatterns.put(\"**/*.xml\", TaurusParser.class.getSimpleName());\n        defaultGlobPatterns.put(\"**/*.wrk\", WrkSummarizerParser.class.getSimpleName());\n        defaultGlobPatterns.put(\"**/*.mdb\", LoadRunnerParser.class.getSimpleName());\n        defaultGlobPatterns.put(\"**/*_stats.csv\", LocustParser.class.getSimpleName());\n    }\n\n    public static List<PerformanceReportParser> getParser(Run<?, ?> build, FilePath workspace, PrintStream logger, String glob, \n            EnvVars env, String percentiles, String filterRegex) throws IOException, InterruptedException {\n        String expandGlob = env.expand(glob);\n        if (defaultGlobPatterns.containsKey(expandGlob)) {\n            return Collections.singletonList(getParser(defaultGlobPatterns.get(expandGlob), expandGlob, percentiles, filterRegex));\n        }\n\n        File path = new File(expandGlob);\n        return path.isAbsolute() ? getParserWithAbsolutePath(build, workspace, logger, path, percentiles, filterRegex) : \n            getParserWithRelativePath(build, workspace, logger, expandGlob, percentiles, filterRegex);\n    }\n\n    private static List<PerformanceReportParser> getParserWithRelativePath(Run<?, ?> build, FilePath workspace, PrintStream logger, String glob, String percentiles, String filterRegex) throws IOException, InterruptedException {\n        List<PerformanceReportParser> result = getParserUsingAntPatternRelativePath(build, workspace, logger, glob, percentiles, filterRegex);\n        if (result != null && !result.isEmpty()) {\n            return result;\n        }\n\n        File report = new File(workspace.getRemote() + '/' + glob);\n        if (!report.exists()) {\n            // if report on remote slave\n            FilePath localReport = new FilePath(new File(build.getRootDir(), TEMP_FOLDER + glob));\n            localReport.copyFrom(new FilePath(workspace, glob));\n            return Collections.singletonList(getParser(ParserDetector.detect(localReport.getRemote()), glob, percentiles, filterRegex));\n        }\n\n        return Collections.singletonList(getParser(ParserDetector.detect(workspace.getRemote() + '/' + glob), workspace.getRemote() + '/' + glob, percentiles, filterRegex));\n    }\n\n    private static List<PerformanceReportParser> getParserUsingAntPatternRelativePath(Run<?, ?> build, FilePath workspace, PrintStream logger, \n            String glob, String percentiles, String filterRegex) throws InterruptedException {\n        try {\n            FilePath[] pathList = workspace.list(glob);\n            List<PerformanceReportParser> result = new ArrayList<>();\n            for (FilePath src : pathList) {\n                // copy file (it can be on remote slave) to \"../build/../temp/\" folder\n                final File localReport = new File(build.getRootDir(), TEMP_FOLDER + src.getName());\n                if (src.isDirectory()) {\n                    logger.println(\"Performance: File '\" + src.getName() + \"' is a directory, not a Performance Report\");\n                    continue;\n                }\n                src.copyTo(new FilePath(localReport));\n                result.add(getParser(ParserDetector.detect(localReport.getPath()), glob, percentiles, filterRegex));\n            }\n            return result;\n        } catch (IOException ignored) {\n            LOGGER.log(Level.FINE, \"Cannot find report file using Ant pattern\", ignored);\n        }\n        return Collections.emptyList();\n    }\n\n\n    private static List<PerformanceReportParser> getParserWithAbsolutePath(Run<?, ?> build, FilePath workspace, PrintStream logger, File path, String percentiles, String filterRegex) throws IOException, InterruptedException {\n        List<PerformanceReportParser> result = getParserUsingAntPatternAbsolutePath(build, workspace, logger, path, percentiles, filterRegex);\n        if (result != null && !result.isEmpty()) {\n            return result;\n        }\n\n        if (!path.exists()) {\n            // if report on remote slave\n            FilePath localReport = new FilePath(new File(build.getRootDir(), TEMP_FOLDER + path.getName()));\n            localReport.copyFrom(new FilePath(workspace.getChannel(), path.getAbsolutePath()));\n            return Collections.singletonList(getParser(ParserDetector.detect(localReport.getRemote()), path.getName(), percentiles, filterRegex));\n        }\n\n\n        return Collections.singletonList(getParser(ParserDetector.detect(path.getAbsolutePath()), path.getAbsolutePath(), percentiles, filterRegex));\n    }\n\n    private static List<PerformanceReportParser> getParserUsingAntPatternAbsolutePath(Run<?, ?> build, FilePath wsp, PrintStream logger, File path, String percentiles, String filterRegex) throws InterruptedException {\n        try {\n            File parent = path.getParentFile();\n            FilePath workspace = new FilePath(wsp.getChannel(), parent.getAbsolutePath());\n            while (!workspace.exists()) {\n                parent = parent.getParentFile();\n                if (parent != null) {\n                    workspace = new FilePath(wsp.getChannel(), parent.getAbsolutePath());\n                } else {\n                    return Collections.emptyList();\n                }\n            }\n\n            String glob = path.getAbsolutePath().substring(parent.getAbsolutePath().length() + 1);\n            FilePath[] pathList = workspace.list(glob);\n            List<PerformanceReportParser> parsers = new ArrayList<>();\n            for (FilePath src : pathList) {\n                // copy file (it can be on remote slave) to \"../build/../temp/\" folder\n                final File localReport = new File(build.getRootDir(), TEMP_FOLDER + src.getName());\n                if (src.isDirectory()) {\n                    logger.println(\"Performance: File '\" + src.getName() + \"' is a directory, not a Performance Report\");\n                    continue;\n                }\n                src.copyTo(new FilePath(localReport));\n\n                parsers.add(getParser(ParserDetector.detect(localReport.getPath()), localReport.getPath(), percentiles, filterRegex));\n            }\n            return parsers;\n        } catch (IOException ignored) {\n            LOGGER.log(Level.FINE, \"Cannot find report file using Ant pattern\", ignored);\n        }\n        return Collections.emptyList();\n    }\n\n\n    private static PerformanceReportParser getParser(String parserName, String glob, String percentiles, String filterRegex) {\n        if (parserName.equals(JMeterParser.class.getSimpleName())) {\n            return new JMeterParser(glob, percentiles, filterRegex);\n        } else if (parserName.equals(JMeterCsvParser.class.getSimpleName())) {\n            return new JMeterCsvParser(glob, percentiles, filterRegex);\n        } else if (parserName.equals(JUnitParser.class.getSimpleName())) {\n            return new JUnitParser(glob, percentiles, filterRegex);\n        } else if (parserName.equals(TaurusParser.class.getSimpleName())) {\n            return new TaurusParser(glob, percentiles, filterRegex);\n        } else if (parserName.equals(WrkSummarizerParser.class.getSimpleName())) {\n            return new WrkSummarizerParser(glob, percentiles, filterRegex);\n        } else if (parserName.equals(JmeterSummarizerParser.class.getSimpleName())) {\n            return new JmeterSummarizerParser(glob, percentiles, filterRegex);\n        } else if (parserName.equals(IagoParser.class.getSimpleName())) {\n            return new IagoParser(glob, percentiles, filterRegex);\n        } else if (parserName.equals(LoadRunnerParser.class.getSimpleName())) {\n            return new LoadRunnerParser(glob, percentiles, filterRegex);\n        } else if (parserName.equals(LocustParser.class.getSimpleName())) {\n            return new LocustParser(glob, percentiles, filterRegex);\n        } else {\n            throw new IllegalArgumentException(\"Unknown parser type: \" + parserName);\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/parsers/PerformanceReportParser.java",
    "content": "package hudson.plugins.performance.parsers;\n\nimport hudson.ExtensionList;\nimport hudson.ExtensionPoint;\nimport hudson.model.Describable;\nimport hudson.model.Run;\nimport hudson.model.TaskListener;\nimport hudson.plugins.performance.PerformancePublisher;\nimport hudson.plugins.performance.descriptors.PerformanceReportParserDescriptor;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport jenkins.model.Jenkins;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.Collection;\n\n/**\n * Parses performance result files into {@link PerformanceReport}s. This object\n * is persisted with {@link PerformancePublisher} into the project\n * configuration.\n * <p>\n * Subtypes can define additional parser-specific parameters as instance fields.\n *\n * @author Kohsuke Kawaguchi\n */\npublic abstract class PerformanceReportParser implements\n        Describable<PerformanceReportParser>, ExtensionPoint {\n    /**\n     * GLOB patterns that specify the performance report.\n     */\n    public final String glob;\n    public String reportURL;\n    /**\n     * Exclude response time of errored samples\n     */\n    protected boolean excludeResponseTime;\n    protected boolean showTrendGraphs;\n    protected int baselineBuild;\n\n    protected PerformanceReportParser(String glob) {\n        this.glob = (glob == null || glob.length() == 0) ? getDefaultGlobPattern()\n                : glob;\n    }\n\n    public PerformanceReportParserDescriptor getDescriptor() {\n        return (PerformanceReportParserDescriptor) Jenkins.get()\n                .getDescriptorOrDie(getClass());\n    }\n\n    /**\n     * Parses the specified reports into {@link PerformanceReport}s.\n     */\n    public abstract Collection<PerformanceReport> parse(\n            Run<?, ?> build, Collection<File> reports, TaskListener listener)\n            throws IOException;\n\n    public abstract String getDefaultGlobPattern();\n\n    /**\n     * All registered implementations.\n     */\n    public static ExtensionList<PerformanceReportParser> all() {\n        return Jenkins.get().getExtensionList(PerformanceReportParser.class);\n    }\n\n    public String getReportName() {\n        return this.getClass().getName().replaceAll(\"^.*\\\\.(\\\\w+)Parser.*$\", \"$1\");\n    }\n\n    public boolean isExcludeResponseTime() {\n        return excludeResponseTime;\n    }\n\n    public void setExcludeResponseTime(boolean excludeResponseTime) {\n        this.excludeResponseTime = excludeResponseTime;\n    }\n\n    public boolean isShowTrendGraphs() {\n        return showTrendGraphs;\n    }\n\n    public void setShowTrendGraphs(boolean showTrendGraphs) {\n        this.showTrendGraphs = showTrendGraphs;\n    }\n\n    public void setBaselineBuild(int baselineBuild) {\n        this.baselineBuild = baselineBuild;\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/parsers/TaurusParser.java",
    "content": "package hudson.plugins.performance.parsers;\n\nimport edu.umd.cs.findbugs.annotations.SuppressFBWarnings;\nimport hudson.Extension;\nimport hudson.plugins.performance.data.TaurusFinalStats;\nimport hudson.plugins.performance.descriptors.PerformanceReportParserDescriptor;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport org.kohsuke.stapler.DataBoundConstructor;\nimport org.w3c.dom.Document;\nimport org.w3c.dom.Element;\nimport org.w3c.dom.Node;\nimport org.w3c.dom.NodeList;\n\nimport javax.xml.parsers.DocumentBuilder;\nimport javax.xml.parsers.DocumentBuilderFactory;\nimport java.io.File;\n\n/**\n * Parser for Taurus\n */\npublic class TaurusParser extends AbstractParser {\n\n    @Extension\n    public static class DescriptorImpl extends PerformanceReportParserDescriptor {\n        @Override\n        public String getDisplayName() {\n            return \"Taurus\";\n        }\n    }\n\n    public TaurusParser(String glob, String percentiles) {\n        super(glob, percentiles, PerformanceReport.INCLUDE_ALL);\n    }\n\n    @DataBoundConstructor\n    public TaurusParser(String glob, String percentiles, String filterRegex) {\n        super(glob, percentiles, filterRegex);\n    }\n\n    @Override\n    public String getDefaultGlobPattern() {\n        return \"**/*.xml\";\n    }\n\n    @Override\n    protected PerformanceReport parse(File reportFile) throws Exception {\n        return readFromXML(reportFile);\n    }\n\n    private PerformanceReport readFromXML(File reportFile) throws Exception {\n        final PerformanceReport report = createPerformanceReport();\n        report.setExcludeResponseTime(excludeResponseTime);\n        report.setShowTrendGraphs(showTrendGraphs);\n        report.setReportFileName(reportFile.getName());\n\n        DocumentBuilderFactory dbFactory\n                = DocumentBuilderFactory.newInstance();\n        dbFactory.setFeature(\"http://apache.org/xml/features/disallow-doctype-decl\", true);\n        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();\n        Document doc = dBuilder.parse(reportFile);\n        doc.getDocumentElement().normalize();\n\n        Node urlNode = doc.getElementsByTagName(\"ReportURL\").item(0);\n        if (urlNode != null) {\n            reportURL = urlNode.getTextContent();\n        }\n\n        Node testDurationNode = doc.getElementsByTagName(\"TestDuration\").item(0);\n        Double testDuration = null;\n        if (testDurationNode != null) {\n            testDuration = Double.parseDouble(testDurationNode.getTextContent()) * 1000; // to ms\n        }\n\n        NodeList nList = doc.getElementsByTagName(\"Group\");\n        for (int temp = 0; temp < nList.getLength(); temp++) {\n            Node nNode = nList.item(temp);\n\n            TaurusFinalStats statusReport = getTaurusFinalStats((Element) nNode);\n            statusReport.setTestDuration(testDuration);\n            if (!((Element) nNode).getAttribute(\"label\").isEmpty()) {\n                statusReport.setLabel(((Element) nNode).getAttribute(\"label\"));\n                report.addSample(statusReport, false);\n            } else {\n                statusReport.setLabel(TaurusFinalStats.DEFAULT_TAURUS_LABEL);\n                report.addSample(statusReport, true);\n            }\n        }\n\n        return report;\n    }\n\n    @SuppressFBWarnings(\"DM_BOXED_PRIMITIVE_FOR_PARSING\")\n    private TaurusFinalStats getTaurusFinalStats(Element group) {\n        final TaurusFinalStats report = new TaurusFinalStats();\n\n        report.setBytes(Long.parseLong(getValueAttribute(\"bytes\", group)));\n        report.setFail(Integer.parseInt(getValueAttribute(\"fail\", group)));\n        report.setSucc(Integer.parseInt(getValueAttribute(\"succ\", group)));\n        if (group.getElementsByTagName(\"throughput\").getLength() > 0) {\n            report.setThroughput(Long.parseLong(getValueAttribute(\"throughput\", group)));\n        }\n        report.setAverageResponseTime(Double.parseDouble(getValueAttribute(\"avg_rt\", group)) * 1000); // to ms\n\n        NodeList perc = group.getElementsByTagName(\"perc\");\n        for (int i = 0; i < perc.getLength(); i++) {\n            Node nNode = perc.item(i);\n            String attributeParam = ((Element) nNode).getAttribute(\"param\");\n            Double valueInMs = Double.valueOf(((Element) nNode).getAttribute(\"value\")) * 1000;\n\n            if (\"50.0\".equals(attributeParam)) {\n                report.setPerc50(valueInMs); // to ms\n            } else if (\"90.0\".equals(attributeParam)) {\n                report.setPerc90(valueInMs); // to ms\n            } else if (\"95.0\".equals(attributeParam)) {\n                report.setPerc95(valueInMs); // to ms\n            } else if (\"0.0\".equals(attributeParam)) {\n                report.setPerc0(valueInMs); // to ms\n            } else if (\"100.0\".equals(attributeParam)) {\n                report.setPerc100(valueInMs); // to ms\n            }\n        }\n        return report;\n    }\n\n    private String getValueAttribute(String elementName, Element group) {\n        return ((Element) group.getElementsByTagName(elementName).item(0)).getAttribute(\"value\");\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/parsers/WrkSummarizerParser.java",
    "content": "package hudson.plugins.performance.parsers;\n\nimport hudson.Extension;\nimport hudson.plugins.performance.data.HttpSample;\nimport hudson.plugins.performance.descriptors.PerformanceReportParserDescriptor;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.tools.SafeMaths;\n\nimport org.kohsuke.stapler.DataBoundConstructor;\n\nimport java.io.File;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Date;\nimport java.util.Scanner;\n\n/**\n * Parser for wrk (https://github.com/wg/wrk)\n * <p>\n * Note that Wrk does not produce request-level data, and can only be processed\n * in it's summarized form (unless extended to do otherwise).\n *\n * @author John Murray me@johnmurray.io\n */\npublic class WrkSummarizerParser extends AbstractParser {\n\n    private enum LineType {\n        RUNNING,\n        THREAD_CONN_COUNT,\n        OUTPUT_HEADER,\n        LATENCY_DIST,\n        LATENCY_DIST_BUCKET_HEADER,\n        LATENCY_DIST_BUCKET,\n        REQ_SEC_DIST,\n        SUMMARY,\n        REQ_SEC,\n        TRANSFER_SEC,\n        ERROR_COUNT,\n        UNKNOWN\n    }\n\n    public enum TimeUnit {\n        MILLISECOND(1),\n        SECOND(1000),\n        MINUTE(1000 * 60),\n        HOUR(1000 * 60 * 60);\n\n        private final int factor;\n\n        TimeUnit(int factor) {\n            this.factor = factor;\n        }\n\n        public int getFactor() {\n            return this.factor;\n        }\n    }\n\n    @Extension\n    public static class DescriptorImpl extends PerformanceReportParserDescriptor {\n        @Override\n        public String getDisplayName() {\n            return \"wrk\";\n        }\n    }\n\n    public WrkSummarizerParser(String glob, String percentiles) {\n        super(glob, percentiles, PerformanceReport.INCLUDE_ALL);\n    }\n    \n    @DataBoundConstructor\n    public WrkSummarizerParser(String glob, String percentiles, String filterRegex) {\n        super(glob, percentiles, filterRegex);\n    }\n\n    @Override\n    public String getDefaultGlobPattern() {\n        return \"**/*.wrk\";\n    }\n\n    @Override\n    PerformanceReport parse(File reportFile) throws Exception {\n        final PerformanceReport r = createPerformanceReport();\n        r.setExcludeResponseTime(excludeResponseTime);\n        r.setShowTrendGraphs(showTrendGraphs);\n        r.setReportFileName(reportFile.getName());\n\n        Scanner s = null;\n        try {\n            s = new Scanner(reportFile, StandardCharsets.UTF_8);\n            HttpSample sample = new HttpSample();\n\n            while (s.hasNextLine()) {\n                Scanner scanner = null;\n                try {\n                    String line = s.nextLine();\n                    scanner = new Scanner(line.toLowerCase().replaceAll(\n                            \"(\\\\d)s|ms|%|mb|kb(\\\\b)\", \"$1$2\"));\n\n                    String firstToken = scanner.next();\n                    String secondToken = scanner.next();\n\n                    switch (determineLineType(firstToken, secondToken)) {\n                        case RUNNING:\n                            // extract URI\n                            scanner.next();\n                            scanner.next();\n                            String uri = scanner.next();\n\n                            sample.setUri(uri);\n                            break;\n                        case LATENCY_DIST:\n                            Scanner latencyScanner = new Scanner(line.toLowerCase());\n                            latencyScanner.next(); // header (skip)\n                            long latencyAvg = getTime(latencyScanner.next(),\n                                    TimeUnit.MILLISECOND);\n                            latencyScanner.next(); // stdDev (skipping)\n                            long latencyMax = getTime(latencyScanner.next(),\n                                    TimeUnit.MILLISECOND);\n\n                            sample.setDuration(latencyAvg);\n                            sample.setSummarizerMax(latencyMax);\n                            break;\n                        case REQ_SEC_DIST:\n                            // float reqSecAvg = Float.parseFloat(secondToken);\n                            // float reqSecStdDev = scanner.nextFloat();\n                            // float reqSecMax = scanner.nextFloat();\n                            // float reqSecPercentInOneStdDev = scanner.nextFloat();\n                            break;\n                        case SUMMARY:\n                            long totalReq = Long.parseLong(firstToken);\n                            Scanner summaryScanner = new Scanner(line.toLowerCase());\n                            summaryScanner.next();\n                            summaryScanner.next();\n                            summaryScanner.next();\n                            // long totalTime = getTime(summaryScanner.next(), logger,\n                            // TimeUnit.SECOND);\n                            sample.setSummarizer(true);\n                            sample.setSummarizerSamples(totalReq);\n                            summaryScanner.close();\n                            break;\n                        case ERROR_COUNT:\n                            scanner.next();\n                            scanner.next();\n                            int numErrors = scanner.nextInt();\n\n                            sample.setSummarizerErrors(numErrors);\n                            break;\n                        case REQ_SEC:\n                        case TRANSFER_SEC:\n                            // not currently used by performance-plugin\n                            break;\n                        case THREAD_CONN_COUNT:\n                        case OUTPUT_HEADER:\n                        case LATENCY_DIST_BUCKET_HEADER:\n                        case LATENCY_DIST_BUCKET:\n                        case UNKNOWN:\n                            // do nothing, don't need output\n                            break;\n                    }\n                } finally {\n                    if (scanner != null)\n                        scanner.close();\n                }\n            }\n\n            sample.setSuccessful(true);\n            sample.setDate(new Date());\n            r.addSample(sample);\n        } finally {\n            if (s != null)\n                s.close();\n        }\n\n        return r;\n    }\n\n    /**\n     * Given a time string (eg: 0ms, 1m, 2s, 3h, etc.) parse and yield the time in\n     * a specified time unit (millisecond, second, minute, hour)\n     * <p>\n     * If no result can be returned, a 0 value will result and any errors\n     * encountered will be logged.\n     *\n     * @param timeString String representation from `wrk` command-output\n     * @param tu         Time unit to return time string in\n     * @return Time in seconds, as parsed from input\n     */\n    public long getTime(String timeString, TimeUnit tu) {\n        double factor = 0;\n\n        timeString = timeString.trim().replaceAll(\"[^\\\\d\\\\.smh]\", \"\");\n        String timeUnitString = timeString.replaceAll(\"[\\\\d\\\\.]\", \"\");\n        String timeValueString = timeString.replaceAll(\"[smh]\", \"\");\n\n    /*\n     * Calculate 'factor' so that we can get the input time in ms (eg: 5m =\n     * 300000, 3s = 3000)\n     */\n        if (\"ms\".equals(timeUnitString)) {\n            factor = 1;\n        } else if (\"s\".equals(timeUnitString)) {\n            factor = 1000;\n        } else if (\"m\".equals(timeUnitString)) {\n            factor = 1000 * 60d;\n        } else if (\"h\".equals(timeUnitString)) {\n            factor = 1000 * 60 * 60d;\n        }\n\n        double timeValue = Double.parseDouble(timeValueString);\n        double timeInMilliSeconds = timeValue * factor;\n        double timeInReturnFormat = SafeMaths.safeDivide(timeInMilliSeconds, tu.getFactor());\n\n        return (int) Math.floor(timeInReturnFormat);\n    }\n\n    /**\n     * Given the first couple of tokens from a line, determine what type of line\n     * it is (by returning a LineType) so that is can be processed accordingly.\n     *\n     * @param t1 First token in the processed line\n     * @param t2 Second token in the processed line\n     * @return LineType indicating how the rest of the line should be processed\n     */\n    public LineType determineLineType(String t1, String t2) {\n        if (\"running\".equals(t1)) {\n            return LineType.RUNNING;\n        } else if (\"thread\".equals(t1)) {\n            return LineType.OUTPUT_HEADER;\n        } else if (\"latency\".equals(t1)) {\n            if (\"distribution\".equals(t2))\n                return LineType.LATENCY_DIST_BUCKET_HEADER;\n            else\n                return LineType.LATENCY_DIST;\n        } else if (\"req/sec\".equals(t1)) {\n            return LineType.REQ_SEC_DIST;\n        } else if (\"requests/sec:\".equals(t1)) {\n            return LineType.REQ_SEC;\n        } else if (\"transfer/sec:\".equals(t1)) {\n            return LineType.TRANSFER_SEC;\n        } else if (\"non-2xx\".equals(t1)) {\n            return LineType.ERROR_COUNT;\n        } else {\n            try {\n                Long.parseLong(t1);\n                if (\"threads\".equals(t2)) {\n                    return LineType.THREAD_CONN_COUNT;\n                } else if (\"requests\".equals(t2)) {\n                    return LineType.SUMMARY;\n                } else {\n                    try {\n                        Float.parseFloat(t2);\n                        return LineType.LATENCY_DIST_BUCKET;\n                    } catch (NumberFormatException e) {\n                        return LineType.UNKNOWN;\n                    }\n                }\n            } catch (NumberFormatException e) {\n                return LineType.UNKNOWN;\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/reports/AbstractReport.java",
    "content": "package hudson.plugins.performance.reports;\n\nimport hudson.plugins.performance.data.HttpSample;\n\nimport org.kohsuke.stapler.Stapler;\n\nimport java.text.DecimalFormat;\nimport java.text.DecimalFormatSymbols;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Locale;\nimport java.util.Map;\nimport java.util.TreeMap;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\n/**\n * Abstract class for classes with samplesCount, error, mean, average, 90 line, 95 line, min and max attributes\n */\npublic abstract class AbstractReport {\n    public static final Logger LOGGER = Logger.getLogger(AbstractReport.class.getName());\n    public static final double ZERO_PERCENT = 0;\n    public static final double ONE_HUNDRED_PERCENT = 100;\n    public static final double NINETY_PERCENT = 90;\n    public static final double NINETY_FIVE_PERCENT = 95;\n    public static final double FIFTY_PERCENT = 50;\n    public static final String DEFAULT_PERCENTILES = \"0,50,90,95,100\";\n\n    protected final ThreadLocal<DecimalFormat> percentFormat;\n    protected final ThreadLocal<DecimalFormat> dataFormat; // three decimals\n\n    protected Map<Double, Long> percentilesValues = new TreeMap<>();\n    protected Map<Double, Long> percentilesDiffValues = new TreeMap<>();\n    protected boolean isCalculatedPercentilesValues = false;\n\n    /**\n     * Exclude response time of errored samples\n     */\n    protected boolean excludeResponseTime;\n\n    protected boolean showTrendGraphs;\n\n    public abstract int countErrors();\n\n    public abstract double errorPercent();\n\n    public abstract void calculatePercentiles();\n\n    public abstract void calculateDiffPercentiles();\n\n    public AbstractReport() {\n        final Locale useThisLocale = (Stapler.getCurrentRequest() != null) ? Stapler.getCurrentRequest().getLocale() : Locale.getDefault();\n\n        percentFormat = new ThreadLocal<DecimalFormat>() {\n\n            @Override\n            protected DecimalFormat initialValue() {\n                return new DecimalFormat(\"0.0\", DecimalFormatSymbols.getInstance(useThisLocale));\n            }\n        };\n\n        dataFormat = new ThreadLocal<DecimalFormat>() {\n\n            @Override\n            protected DecimalFormat initialValue() {\n                return new DecimalFormat(\"#,###\", DecimalFormatSymbols.getInstance(useThisLocale));\n            }\n        };\n    }\n\n    public String errorPercentFormated() {\n        Stapler.getCurrentRequest().getLocale();\n        return percentFormat.get().format(errorPercent());\n    }\n\n    protected void checkPercentileAndSet(Double key, Long value) {\n        if (value != null) {\n            percentilesValues.put(key, value);\n            isCalculatedPercentilesValues = true;\n        }\n    }\n\n    protected List<Double> parsePercentiles(String percentiles) {\n        final List<Double> res = new ArrayList<>();\n        if (percentiles != null && !percentiles.isBlank()) {\n            String[] percs = percentiles.split(\",\");\n            for (String perc : percs) {\n                try {\n                    res.add(Double.parseDouble(perc));\n                } catch (NumberFormatException ex) {\n                    LOGGER.log(Level.WARNING, \"Cannot parse percentile value \" + perc);\n                }\n            }\n        }\n        return res;\n    }\n\n    public abstract long getAverage();\n\n    public String getAverageFormated() {\n        return dataFormat.get().format(getAverage());\n    }\n\n    public abstract long getMedian();\n\n    public String getMeanFormated() {\n        return dataFormat.get().format(getMedian());\n    }\n\n    public abstract long get90Line();\n\n    public String get90LineFormated() {\n        return dataFormat.get().format(get90Line());\n    }\n\n    public abstract long get95Line();\n\n    public String get95LineFormated() {\n        return dataFormat.get().format(get95Line());\n    }\n\n    public abstract long getMax();\n\n    public String getMaxFormated() {\n        return dataFormat.get().format(getMax());\n    }\n\n    public abstract long getMin();\n\n    public abstract int samplesCount();\n\n    public abstract String getHttpCode();\n\n    public abstract long getAverageDiff();\n\n    public abstract long getMedianDiff();\n\n    public abstract long get90LineDiff();\n\n    public abstract long get95LineDiff();\n\n    public abstract double getErrorPercentDiff();\n\n    public abstract String getLastBuildHttpCodeIfChanged();\n\n    public abstract int getSamplesCountDiff();\n\n    public boolean isExcludeResponseTime() {\n        return excludeResponseTime;\n    }\n\n    public void setExcludeResponseTime(boolean excludeResponseTime) {\n        this.excludeResponseTime = excludeResponseTime;\n    }\n\n    public boolean isShowTrendGraphs() {\n        return showTrendGraphs;\n    }\n\n    public void setShowTrendGraphs(boolean showTrendGraphs) {\n        this.showTrendGraphs = showTrendGraphs;\n    }\n\n    protected boolean isIncludeResponseTime(HttpSample sample) {\n        return !(sample.isFailed() && excludeResponseTime && !sample.isSummarizer());\n    }\n\n    public Map<Double, Long> getPercentilesValues() {\n        if (!isCalculatedPercentilesValues) {\n            calculatePercentiles();\n            calculateDiffPercentiles();\n        }\n        return percentilesValues;\n    }\n\n    public Map<Double, Long> getPercentilesDiffValues() {\n        if (!isCalculatedPercentilesValues) {\n            calculatePercentiles();\n            calculateDiffPercentiles();\n        }\n        return percentilesDiffValues;\n    }\n\n    public String getPercentileLabel(Double perc) {\n        if (perc == 0.0) {\n            return \"Min(ms)\";\n        } else if (perc == 50.0) {\n            return \"Median(ms)\";\n        } else if (perc == 100.0) {\n            return \"Max(ms)\";\n        } else {\n            return \"Line \" + perc + \"(ms)\";\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/reports/ConstraintReport.java",
    "content": "package hudson.plugins.performance.reports;\n\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\nimport java.util.ArrayList;\nimport java.util.Calendar;\nimport java.util.List;\n\nimport hudson.model.ParameterValue;\nimport hudson.model.ParametersAction;\nimport hudson.model.Result;\nimport hudson.model.Run;\nimport hudson.model.StringParameterValue;\nimport hudson.plugins.performance.constraints.AbsoluteConstraint;\nimport hudson.plugins.performance.constraints.AbstractConstraint;\nimport hudson.plugins.performance.constraints.ConstraintEvaluation;\nimport hudson.plugins.performance.constraints.RelativeConstraint;\nimport jenkins.model.Jenkins;\n\n/**\n * Creates a report of the constraint evaluation and stores it into a consecutive log file, a build\n * environment variable and prints it to the Jenkins console output.\n *\n * @author Rene Kugel\n */\npublic class ConstraintReport {\n\n    /**\n     * Log file that is created and the log is printed to\n     */\n    private File performanceLog;\n    /**\n     * Newly created build object. Used to determine build number and build date\n     */\n    private Run<?, ?> newBuild;\n\n    /**\n     * Number of the build\n     */\n    private int buildNumber;\n    /**\n     * Date when the build was started\n     */\n    private Calendar buildDate;\n    /**\n     * Result of the build\n     */\n    private Result buildResult;\n    /**\n     * Link to the build with the build number\n     */\n    private String linkToBuild;\n    /**\n     * Number of all constraints in this build\n     */\n    private short allConstraints = 0;\n    /**\n     * Number of all relative constraints in this build\n     */\n    private short relativeConstraints = 0;\n    /**\n     * Number of all absolute constraints in this build\n     */\n    private short absoluteConstraints = 0;\n    /**\n     * Number of all successful constraints in this build\n     */\n    private short successfulConstraints = 0;\n    /**\n     * Number of all violated constraints in this build\n     */\n    private short violatedConstraints = 0;\n    /**\n     * Number of all violated constraints with the escalation level INFORMATION in this build\n     */\n    private short violatedInformation = 0;\n    /**\n     * Number of all violated constraints with the escalation level WARNING in this build\n     */\n    private short violatedUnstable = 0;\n    /**\n     * Number of all violated constraints with the escalation level ERROR in this build\n     */\n    private short violatedError = 0;\n    /**\n     * Logger message for console output\n     */\n    private String loggerMsg;\n    /**\n     * Logger message for log file and environment variable\n     */\n    private String loggerMsgAdv;\n    /**\n     * Buld result in JUnit report format\n     */\n    private String junitReport;\n\n    public ConstraintReport(ArrayList<ConstraintEvaluation> ceList, Run<?, ?> globBuild, boolean persistConstraintLog) throws IOException {\n        this.newBuild = globBuild;\n        this.createMetaData(ceList, newBuild);\n        this.createLoggerMsg(ceList);\n        this.createLoggerMsgAdv();\n        this.writeResultsToEnvVar();\n        if (persistConstraintLog) {\n            this.writeResultsToFile();\n        }\n        this.junitReport = this.createJunitReport(ceList);\n    }\n\n    /**\n     * Creates the head data for the report\n     *\n     * @param ceList   ArrayList of evaluated constraints\n     * @param newBuild Newly created build\n     */\n    private void createMetaData(ArrayList<ConstraintEvaluation> ceList, Run<?, ?> newBuild) {\n        this.buildNumber = newBuild.getNumber();\n        this.buildDate = newBuild.getTimestamp();\n        this.buildResult = determineBuildResult(ceList);\n\n\t\t/*\n         * Jenkins cannot reliable resolve it's own root URL unless it is set in the Jenkins System\n\t\t * Configuration. This will cause that getRootUrl() returns null\n\t\t */\n        if (Jenkins.get().getRootUrl() == null) {\n            this.linkToBuild = \"Could not resolve URL - Please set the root URL in the Jenkins System Configuration\";\n        } else {\n            this.linkToBuild = Jenkins.get().getRootUrl() + newBuild.getUrl();\n        }\n\n        for (ConstraintEvaluation ce : ceList) {\n            if (ce.getAbstractConstraint() instanceof AbsoluteConstraint) {\n                this.allConstraints++;\n                this.absoluteConstraints++;\n                if (ce.getAbstractConstraint().getSuccess()) {\n                    this.successfulConstraints++;\n                } else {\n                    this.violatedConstraints++;\n                    switch (ce.getAbstractConstraint().getEscalationLevel().ordinal()) {\n                        case 0:\n                            this.violatedInformation++;\n                            break;\n                        case 1:\n                            this.violatedUnstable++;\n                            break;\n                        case 2:\n                            this.violatedError++;\n                            break;\n                        default:\n                            break;\n                    }\n                }\n            } else if (ce.getAbstractConstraint() instanceof RelativeConstraint) {\n                this.allConstraints++;\n                this.relativeConstraints++;\n                if (ce.getAbstractConstraint().getSuccess()) {\n                    this.successfulConstraints++;\n                } else {\n                    this.violatedConstraints++;\n                    switch (ce.getAbstractConstraint().getEscalationLevel().ordinal()) {\n                        case 0:\n                            this.violatedInformation++;\n                            break;\n                        case 1:\n                            this.violatedUnstable++;\n                            break;\n                        case 2:\n                            this.violatedError++;\n                            break;\n                        default:\n                            break;\n                    }\n                }\n            }\n        }\n    }\n\n    /**\n     * Determines the build result based on the violated constraint with the highest escalation\n     * level\n     *\n     * @param ceList ArrayList of evaluated constraints\n     * @return The determined build result. The build will be marked based on this result: SUCCESS,\n     * UNSTABLE, FAILURE\n     */\n    private Result determineBuildResult(ArrayList<ConstraintEvaluation> ceList) {\n        int highestViolatedEscalation = 0;\n        for (ConstraintEvaluation ce : ceList) {\n            if (ce.getAbstractConstraint().getEscalationLevel().ordinal() > highestViolatedEscalation && !ce.getAbstractConstraint().getSuccess()) {\n                highestViolatedEscalation = ce.getAbstractConstraint().getEscalationLevel().ordinal();\n            }\n        }\n        switch (highestViolatedEscalation) {\n            case 0:\n                return Result.SUCCESS;\n            case 1:\n                return Result.UNSTABLE;\n            case 2:\n                return Result.FAILURE;\n            default:\n                return Result.FAILURE;\n        }\n    }\n\n    /**\n     * Creates the body data for the report.\n     *\n     * @param ceList ArrayList of evaluated constraints\n     */\n    private void createLoggerMsg(ArrayList<ConstraintEvaluation> ceList) {\n        loggerMsg = \"----------------------------------------------------------- \\n\";\n        if (relativeConstraints == 0) {\n            loggerMsg += \"There are no relative constraints to evaluate! \\n-------------- \\n\";\n        } else {\n            loggerMsg += \"Evaluating all relative constraints! \\n-------------- \\n\";\n            for (ConstraintEvaluation ce : ceList) {\n                if (ce.getAbstractConstraint() instanceof RelativeConstraint) {\n                    loggerMsg += ce.getAbstractConstraint().getResultMessage() + \"\\n-------------- \\n\";\n                }\n            }\n        }\n\n        if (absoluteConstraints == 0) {\n            loggerMsg += \"There are no absolute constraints to evaluate! \\n-------------- \\n\";\n        } else {\n            loggerMsg += \"Evaluating all absolute constraints! \\n-------------- \\n\";\n            for (ConstraintEvaluation ce : ceList) {\n                if (ce.getAbstractConstraint() instanceof AbsoluteConstraint) {\n                    loggerMsg += ce.getAbstractConstraint().getResultMessage() + \"\\n-------------- \\n\";\n                }\n            }\n        }\n\n        if (violatedConstraints == 0) {\n            loggerMsg += \"There were no failing Constraints! The build will be marked as SUCCESS\";\n        } else if (buildResult.equals(Result.SUCCESS)) {\n            loggerMsg += \"The highest escalation: Information! The build will be marked as SUCCESS\";\n        } else if (buildResult.equals(Result.UNSTABLE)) {\n            loggerMsg += \"The highest escalation: Warning! The build will be marked as UNSTABLE\";\n        } else if (buildResult.equals(Result.FAILURE)) {\n            loggerMsg += \"The highest escalation: Error! The build will be marked as FAILURE\";\n        }\n\n        loggerMsg += \"\\n\";\n\n        if (violatedConstraints == 0)\n            return;\n\n        int maxUriColumnWidth = 8; // header column widths\n        int maxReportColumnWidth = 6;\n\n        for (ConstraintEvaluation ce : ceList) {\n            AbstractConstraint c = ce.getAbstractConstraint();\n            maxUriColumnWidth = Math.max(c.isSpecifiedTestCase() ? c.getTestCaseBlock().getTestCase().length() : 0, maxUriColumnWidth);\n            maxReportColumnWidth = Math.max(c.getRelatedPerfReport().length(), maxReportColumnWidth);\n        }\n        String logFormat = \"%1$-\"+maxReportColumnWidth+\"s %2$-\"+maxUriColumnWidth+\"s %3$-10s %4$-20s %5$10s %6$-20s\\n\";\n\n        loggerMsg += \"\\nSummary of failed constraints:\\n\"+\n            String.format(logFormat, \"Report\", \"Testcase\", \"Metric\", \"Operator\", \"Value\", \"Level\");\n\n        for (ConstraintEvaluation ce : ceList) {\n            AbstractConstraint c = ce.getAbstractConstraint();\n            if (!c.getSuccess()) {\n                loggerMsg += String.format(logFormat,\n                    c.getRelatedPerfReport(),\n                    c.isSpecifiedTestCase() ? c.getTestCaseBlock().getTestCase() : AbstractConstraint.ANY,\n                    c.getMeteredValue().toString(),\n                    c.getOperator().toString(),\n                    c instanceof RelativeConstraint ? String.format(\"%9.3f%%\", ((RelativeConstraint)c).getTolerance()) \n                        : String.format(\"%10d\", ((AbsoluteConstraint)c).getValue()),\n                    c.getEscalationLevel().toString());\n            }\n        }\n        loggerMsg += \"\\n\";\n    }\n\n    /**\n     * Concatenates the body and the head of the message\n     */\n    private void createLoggerMsgAdv() {\n        loggerMsgAdv = \"----------------------------------------------------------- \\n\" + \"Build Number: #\" + this.getBuildNumber() + \"\\n\" + \"Build Date: \" + this.getBuildDate().getTime() + \"\\n\"\n                + \"Build State: \" + this.getBuildResult().toString() + \"\\n\" + \"Link to build: \" + this.linkToBuild + \"\\n\" + \"-------------- \\n\" + \"Number of all constraints: \"\n                + this.getAllConstraints() + \"\\n\" + \"Relative constraints: \" + this.getRelativeConstraints() + \"\\n\" + \"Absolute constraints: \" + this.getAbsoluteConstraints() + \"\\n\"\n                + \"Successful constraints: \" + this.getSuccessfulConstraints() + \"\\n\" + \"Violated constraints: \" + this.getViolatedConstraints() + \"\\n\" + \"->INFORMATION: \"\n                + this.getViolatedInformation() + \"\\n\" + \"->UNSTABLE: \" + this.getViolatedUnstable() + \"\\n\" + \"->ERROR: \" + this.getViolatedError() + \"\\n\" + \"-------------- \\n\" + loggerMsg + \"\\n\";\n    }\n\n    /**\n     * Generate JUnit XML output format for all evaluated constraints. \n     * Depends on results from previous createMetaData call.\n     */\n    private String createJunitReport(ArrayList<ConstraintEvaluation> ceList) {\n        StringBuilder sb = new StringBuilder();\n        sb.append(\"<testsuite tests=\\\"\"+getAllConstraints()+\"\\\" failures=\\\"\"+getViolatedConstraints()+\"\\\" >\\n\");\n        for (ConstraintEvaluation ce : ceList) {\n            AbstractConstraint c = ce.getAbstractConstraint();\n            sb.append(c.getJunitResult());\n        }\n        sb.append(\"</testsuite>\"); \n        return sb.toString();\n    }\n\n    /**\n     * Creates the log file if not present and writes the report to the log file. Only executed if\n     * persistConstraintLog == true\n     *\n     * @throws IOException\n     */\n    public void writeResultsToFile() throws IOException {\n        performanceLog = new File(newBuild.getRootDir() + File.separator + \"performance-results\" + File.separator + \"performance.log\");\n        if (!performanceLog.exists()) {\n            boolean dirsCreated = performanceLog.getParentFile().mkdirs();\n            if (!dirsCreated && !performanceLog.getParentFile().exists()) {\n                throw new IOException(\"Failed to create directory \" + performanceLog.getParentFile());\n            }\n            if (!performanceLog.createNewFile()) {\n                throw new IOException(\"Cannot create new file \"+performanceLog.getAbsolutePath());\n            }\n        }\n        try (FileOutputStream outWriter = new FileOutputStream(performanceLog, true)){\n            outWriter.write(getLoggerMsgAdv().getBytes(StandardCharsets.UTF_8));\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n    }\n\n    /**\n     * Writes the complete report to the environment variable: BUILD_CONSTRAINT_LOG\n     */\n    public void writeResultsToEnvVar() {\n        List<ParameterValue> params = new ArrayList<>();\n        params.add(new StringParameterValue(\"BUILD_CONSTRAINT_LOG\", getLoggerMsgAdv()));\n        newBuild.addAction(new ParametersAction(params));\n    }\n\n    public int getBuildNumber() {\n        return buildNumber;\n    }\n\n    public Calendar getBuildDate() {\n        return buildDate;\n    }\n\n    public Result getBuildResult() {\n        return buildResult;\n    }\n\n    public String getLinkToBuild() {\n        return linkToBuild;\n    }\n\n    public short getAllConstraints() {\n        return allConstraints;\n    }\n\n    public short getRelativeConstraints() {\n        return relativeConstraints;\n    }\n\n    public short getAbsoluteConstraints() {\n        return absoluteConstraints;\n    }\n\n    public short getSuccessfulConstraints() {\n        return successfulConstraints;\n    }\n\n    public short getViolatedConstraints() {\n        return violatedConstraints;\n    }\n\n    public short getViolatedInformation() {\n        return violatedInformation;\n    }\n\n    public short getViolatedUnstable() {\n        return violatedUnstable;\n    }\n\n    public short getViolatedError() {\n        return violatedError;\n    }\n\n    public String getLoggerMsg() {\n        return loggerMsg;\n    }\n\n    public String getLoggerMsgAdv() {\n        return loggerMsgAdv;\n    }\n\n    public String getJunitReport() {\n        return junitReport;\n    }\n\n    public File getPerformanceLog() {\n        return performanceLog;\n    }\n\n    public void setPerformanceLog(File performanceLog) {\n        this.performanceLog = performanceLog;\n    }\n}"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/reports/PerformanceReport.java",
    "content": "package hudson.plugins.performance.reports;\n\nimport hudson.model.Run;\nimport hudson.plugins.performance.Messages;\nimport hudson.plugins.performance.PerformanceReportMap;\nimport hudson.plugins.performance.actions.PerformanceBuildAction;\nimport hudson.plugins.performance.data.HttpSample;\nimport hudson.plugins.performance.data.TaurusFinalStats;\nimport hudson.plugins.performance.parsers.PerformanceReportParser;\nimport hudson.plugins.performance.tools.SafeMaths;\n\n\nimport java.io.IOException;\nimport java.io.Serializable;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.logging.Level;\nimport java.util.regex.Pattern;\n\n/**\n * Represents a single performance report, which consists of multiple\n * {@link UriReport}s for different URLs that was tested.\n * <p>\n * This object belongs under {@link PerformanceReportMap}.\n */\npublic class PerformanceReport extends AbstractReport implements Serializable,\n        Comparable<PerformanceReport> {\n    private static final long serialVersionUID = 675698410989941826L;\n\n\n    public static final String INCLUDE_ALL = null;\n\n\n    private transient PerformanceBuildAction buildAction;\n\n\n    private String reportFileName = null;\n\n    /**\n     * {@link UriReport}s keyed by their {@link UriReport#getStaplerUri()}.\n     */\n    private final Map<String, UriReport> uriReportMap = new LinkedHashMap<>();\n\n    private PerformanceReport lastBuildReport;\n\n    /**\n     * A lazy cache of all duration values of all HTTP samples in all UriReports, ordered by duration.\n     */\n    private transient List<Long> durationsSortedBySize = null;\n\n    /**\n     * A lazy cache of all UriReports, reverse-ordered.\n     */\n    private transient List<UriReport> uriReportsOrdered = null;\n\n    /**\n     * The amount of http samples that are not successful.\n     */\n    private int nbError = 0;\n\n    /**\n     * The sum of summarizerErrors values from all samples;\n     */\n    private float summarizerErrors = 0;\n\n    /**\n     * The amount of samples in all uriReports combined.\n     */\n    private int size;\n    private int samplesCount;\n\n    /**\n     * The duration of all samples combined, in milliseconds.\n     */\n    private long totalDuration = 0;\n\n    /**\n     * The size of all samples combined, in kilobytes.\n     */\n    private double totalSizeInKB = 0;\n    private long summarizerMin;\n    private long summarizerMax;\n    private long summarizerAvg;\n    private String summarizerErrorPercent = null;\n    private long summarizerSize;\n\n    private Long average;\n    private Long perc0;\n    private Long perc50;\n    private Long perc90;\n    private Long perc95;\n    private Long perc100;\n\n    private Long throughput;\n    protected String percentiles;\n    protected int baselineBuild = 0;\n\n    private transient Pattern filterRegexPattern;\n\n    private String filterRegex;\n\n    public PerformanceReport() {\n        this(DEFAULT_PERCENTILES);\n    }\n\n    public PerformanceReport(String percentiles, String filterRegex) {\n        this.percentiles = percentiles;\n        this.filterRegex = filterRegex;\n        if (filterRegex != null && filterRegex.trim().length() > 0) {\n            this.filterRegexPattern = Pattern.compile(filterRegex);\n        }\n    }\n\n    public PerformanceReport(String defaultPercentiles) {\n        this(defaultPercentiles, INCLUDE_ALL);\n    }\n\n    public Object readResolve() {\n        if (size != 0) {\n            samplesCount = size;\n        }\n\n        if (throughput == null) {\n            for (UriReport uriReport : getUriListOrdered()) {\n                Long uriThroughput = uriReport.getThroughput();\n                if (uriThroughput != null) {\n                    throughput = (throughput == null) ? uriThroughput : (uriThroughput + throughput);\n                }\n            }\n        }\n        checkPercentileAndSet(0.0, perc0);\n        checkPercentileAndSet(50.0, perc50);\n        checkPercentileAndSet(90.0, perc90);\n        checkPercentileAndSet(95.0, perc95);\n        checkPercentileAndSet(100.0, perc100);\n        if (percentiles == null || percentiles.isBlank()) {\n            this.percentiles = DEFAULT_PERCENTILES;\n        }\n        return this;\n    }\n\n    public static String asStaplerURI(String uri) {\n        return uri.replace(\"http:\", \"\").replace(\"https:\", \"\").replaceAll(\"/\", \"_\").replaceAll(\":\", \"_\");\n    }\n\n    public void addSample(HttpSample pHttpSample) {\n        String uri = pHttpSample.getUri();\n        if (uri == null) {\n            buildAction\n                    .getHudsonConsoleWriter()\n                    .println(\"label cannot be empty, please ensure your jmx file specifies \"\n                            + \"name properly for each http sample: skipping sample\");\n            return;\n        }\n        if (!isIncluded(uri)) {\n            return;\n        }\n        String staplerUri = PerformanceReport.asStaplerURI(uri);\n        synchronized (uriReportMap) {\n            UriReport uriReport = uriReportMap.get(staplerUri);\n            if (uriReport == null) {\n                uriReport = new UriReport(this, staplerUri, uri);\n                uriReport.setExcludeResponseTime(excludeResponseTime);\n                uriReport.setShowTrendGraphs(showTrendGraphs);\n                uriReportMap.put(staplerUri, uriReport);\n            }\n            uriReport.addHttpSample(pHttpSample);\n\n            // reset the lazy loaded caches.\n            durationsSortedBySize = null;\n            uriReportsOrdered = null;\n        }\n\n        if (!pHttpSample.isSuccessful()) {\n            nbError++;\n        }\n        summarizerErrors += pHttpSample.getSummarizerErrors();\n        samplesCount++;\n        if (isIncludeResponseTime(pHttpSample)) {\n            totalDuration += pHttpSample.getDuration();\n        }\n        totalSizeInKB += pHttpSample.getSizeInKb();\n    }\n\n    private boolean isIncluded(String name) {\n        if (filterRegexPattern != null) {\n            return filterRegexPattern.matcher(name).matches();\n        } else {\n            return true;\n        }\n    }\n\n    public void addSample(TaurusFinalStats sample, boolean isSummaryReport) {\n        String uri = sample.getLabel();\n        if (uri == null) {\n            buildAction\n                    .getHudsonConsoleWriter()\n                    .println(\"label cannot be empty, please ensure your jmx file specifies \"\n                            + \"name properly for each http sample: skipping sample\");\n            return;\n        }\n\n        if (!isIncluded(uri)) {\n            return;\n        }\n\n\n        if (isSummaryReport) {\n            summarizerErrors = nbError = sample.getFail();\n            int sampleCount = sample.getFail() + sample.getSucc();\n            samplesCount = sampleCount;\n            Double testDuration = sample.getTestDuration();\n            totalDuration = (testDuration == null) ? ((long) sample.getAverageResponseTime() * sampleCount) : (testDuration.longValue());\n            totalSizeInKB = sample.getBytes();\n\n            average = (long) sample.getAverageResponseTime();\n            perc50 = (long) sample.getPerc50();\n            perc90 = (long) sample.getPerc90();\n            perc95 = (long) sample.getPerc95();\n            perc0 = (long) sample.getPerc0();\n            perc100 = (long) sample.getPerc100();\n            this.percentilesValues.put(0.0, (long) sample.getPerc0());\n            this.percentilesValues.put(50.0, (long) sample.getPerc50());\n            this.percentilesValues.put(90.0, (long) sample.getPerc90());\n            this.percentilesValues.put(95.0, (long) sample.getPerc95());\n            this.percentilesValues.put(100.0, (long) sample.getPerc100());\n            calculateDiffPercentiles();\n            isCalculatedPercentilesValues = true;\n\n            long durationSec = (long) Math.ceil((float) totalDuration / 1000);\n            if (durationSec < 1) {\n                LOGGER.log(Level.INFO, String.format(\"Performance test had a duration of only %d second(s), please check your configuration.\", durationSec));\n            }\n            throughput = (testDuration == null) ?\n                    sample.getThroughput() :\n                    (long) SafeMaths.safeDivide(sampleCount, durationSec);\n        } else {\n            String staplerUri = PerformanceReport.asStaplerURI(uri);\n            synchronized (uriReportMap) {\n                UriReport uriReport = uriReportMap.get(staplerUri);\n                if (uriReport == null) {\n                    uriReport = new UriReport(this, staplerUri, uri);\n                    uriReportMap.put(staplerUri, uriReport);\n                }\n                uriReport.setFromTaurusFinalStats(sample);\n\n                // reset the lazy loaded caches.\n                durationsSortedBySize = null;\n                uriReportsOrdered = null;\n            }\n        }\n    }\n\n    public int compareTo(PerformanceReport jmReport) {\n        if (this == jmReport) {\n            return 0;\n        }\n        return getReportFileName().compareTo(jmReport.getReportFileName());\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (this == obj) return true;\n        if (obj == null || getClass() != obj.getClass()) return false;\n        PerformanceReport that = (PerformanceReport) obj;\n        return getReportFileName() != null ? getReportFileName().equals(that.getReportFileName()) : that.getReportFileName() == null;\n    }\n\n    @Override\n    public int hashCode() {\n        return getReportFileName() != null ? getReportFileName().hashCode() : 0;\n    }\n\n    public int countErrors() {\n        return nbError;\n    }\n\n    public double errorPercent() {\n        if (ifSummarizerParserUsed(reportFileName)) {\n            if (uriReportMap.size() == 0) return 0;\n            return Math.round((summarizerErrors / uriReportMap.size()) * 1000.0) / 1000.0;\n        } else {\n            return Math.round((samplesCount() == 0 ? 0 : SafeMaths.safeDivide((double) countErrors(), samplesCount()) * 100) * 1000.0) / 1000.0;\n        }\n    }\n\n    public long getAverage() {\n        if (average == null) {\n            average = (samplesCount == 0) ? 0 : (long) SafeMaths.safeDivide(totalDuration, samplesCount);\n        }\n        return average;\n    }\n\n    public double getAverageSizeInKb() {\n        if (samplesCount == 0) {\n            return 0;\n        }\n        return SafeMaths.roundTwoDecimals(SafeMaths.safeDivide(totalSizeInKB, samplesCount));\n    }\n\n    /**\n     * 0 percent will give the first value from ordered list of durations\n     * 100 percent will give the last value from ordered list of durations\n     *\n     * @param percentage must be a value between 0 and 100 (inclusive)\n     * @return value at the percentage specified.\n     */\n    public long getDurationAt(double percentage) {\n        if (percentage < ZERO_PERCENT || percentage > ONE_HUNDRED_PERCENT) {\n            throw new IllegalArgumentException(\"Argument 'percentage' must be a value between 0 and 100 (inclusive)\");\n        }\n\n        if (samplesCount == 0) {\n            return 0;\n        }\n\n        synchronized (uriReportMap) {\n            if (durationsSortedBySize == null) {\n                durationsSortedBySize = new ArrayList<>();\n                for (UriReport currentReport : uriReportMap.values()) {\n                    durationsSortedBySize.addAll(currentReport.getDurations());\n                }\n                Collections.sort(durationsSortedBySize);\n            }\n\n            if (durationsSortedBySize.isEmpty()) {\n                return 0;\n            }\n\n            final double percentInDecimals = percentage / 100;\n            int indexToReturn = ((int) (durationsSortedBySize.size() * percentInDecimals)) - 1;\n\n            // Make sure a valid index is used.\n            if (indexToReturn < 0) {\n                indexToReturn = 0;\n            } else if (indexToReturn >= durationsSortedBySize.size()) {\n                indexToReturn = durationsSortedBySize.size() - 1;\n            }\n            return durationsSortedBySize.get(indexToReturn);\n        }\n    }\n\n    @Override\n    public void calculatePercentiles() {\n        List<Double> percs = super.parsePercentiles(percentiles);\n        for (Double perc : percs) {\n            super.percentilesValues.put(perc, getDurationAt(perc));\n        }\n        super.isCalculatedPercentilesValues = true;\n    }\n\n    @Override\n    public void calculateDiffPercentiles() {\n        List<Double> percs = super.parsePercentiles(percentiles);\n        for (Double perc : percs) {\n            Long diff = 0L;\n            if (lastBuildReport != null) {\n                Long previousValue = lastBuildReport.getPercentilesValues().get(perc);\n                Long currentValue = getPercentilesValues().get(perc);\n                if (previousValue != null && currentValue != null) {\n                    diff = currentValue - previousValue;\n                }\n            }\n            super.percentilesDiffValues.put(perc, diff);\n        }\n    }\n\n    public long get90Line() {\n        if (perc90 == null) {\n            perc90 = getDurationAt(NINETY_PERCENT);\n        }\n        return perc90;\n    }\n\n    public long get95Line() {\n        if (perc95 == null) {\n            perc95 = getDurationAt(NINETY_FIVE_PERCENT);\n        }\n        return perc95;\n    }\n\n    public long getMedian() {\n        if (perc50 == null) {\n            perc50 = getDurationAt(FIFTY_PERCENT);\n        }\n        return perc50;\n    }\n\n    public String getHttpCode() {\n        return \"\";\n    }\n\n    public Run<?, ?> getBuild() {\n        return buildAction.getBuild();\n    }\n\n    PerformanceBuildAction getBuildAction() {\n        return buildAction;\n    }\n\n    public String getDisplayName() {\n        return Messages.Report_DisplayName();\n    }\n\n    public UriReport getDynamic(String token) throws IOException {\n        return getUriReportMap().get(token);\n    }\n\n    public long getMax() {\n        if (perc100 == null) {\n            perc100 = getDurationAt(ONE_HUNDRED_PERCENT);\n        }\n        return perc100;\n    }\n\n    public double getTotalTrafficInKb() {\n        return SafeMaths.roundTwoDecimals(totalSizeInKB);\n    }\n\n    public long getMin() {\n        if (perc0 == null) {\n            perc0 = getDurationAt(ZERO_PERCENT);\n        }\n        return perc0;\n    }\n\n    public String getReportFileName() {\n        return reportFileName;\n    }\n\n    public List<UriReport> getUriListOrdered() {\n        synchronized (uriReportMap) {\n            if (uriReportsOrdered == null) {\n                uriReportsOrdered = new ArrayList<>(uriReportMap.values());\n                Collections.sort(uriReportsOrdered, Collections.reverseOrder());\n            }\n            return uriReportsOrdered;\n        }\n    }\n\n    public Map<String, UriReport> getUriReportMap() {\n        return uriReportMap;\n    }\n\n    public void setBuildAction(PerformanceBuildAction buildAction) {\n        this.buildAction = buildAction;\n    }\n\n    public void setReportFileName(String reportFileName) {\n        this.reportFileName = reportFileName;\n    }\n\n    public int samplesCount() {\n        return samplesCount;\n    }\n\n    public void setLastBuildReport(PerformanceReport lastBuildReport) {\n        Map<String, UriReport> lastBuildUriReportMap = lastBuildReport\n                .getUriReportMap();\n        for (Map.Entry<String, UriReport> item : uriReportMap.entrySet()) {\n            UriReport lastBuildUri = lastBuildUriReportMap.get(item.getKey());\n            if (lastBuildUri != null) {\n                item.getValue().addLastBuildUriReport(lastBuildUri);\n            }\n        }\n        this.lastBuildReport = lastBuildReport;\n        calculateDiffPercentiles();\n    }\n\n    public long getAverageDiff() {\n        if (lastBuildReport == null) {\n            return 0;\n        }\n        return getAverage() - lastBuildReport.getAverage();\n    }\n\n    public long getMedianDiff() {\n        if (lastBuildReport == null) {\n            return 0;\n        }\n        return getMedian() - lastBuildReport.getMedian();\n    }\n\n    public long get90LineDiff() {\n        if (lastBuildReport == null) {\n            return 0;\n        }\n        return get90Line() - lastBuildReport.get90Line();\n    }\n\n    public long get95LineDiff() {\n        if (lastBuildReport == null) {\n            return 0;\n        }\n        return get95Line() - lastBuildReport.get95Line();\n    }\n\n    public double getErrorPercentDiff() {\n        if (lastBuildReport == null) {\n            return 0;\n        }\n        return Math.round((errorPercent() - lastBuildReport.errorPercent()) * 1000.0) / 1000.0;\n    }\n\n    public String getLastBuildHttpCodeIfChanged() {\n        return \"\";\n    }\n\n    public int getSamplesCountDiff() {\n        if (lastBuildReport == null) {\n            return 0;\n        }\n        return samplesCount() - lastBuildReport.samplesCount();\n    }\n\n    /**\n     * Check if the filename of the file being parsed is being parsed by a\n     * summarized parser (JMeterSummarizer).\n     *\n     * @param filename name of the file being parsed\n     * @return boolean indicating usage of summarized parser\n     */\n    public boolean ifSummarizerParserUsed(String filename) {\n        PerformanceReportParser parser = buildAction.getParserByDisplayName(\"JmeterSummarizer\");\n        if (parser != null) {\n            String fileExt = parser.glob;\n            String[] parts = fileExt.split(\"\\\\s*[;:,]+\\\\s*\");\n            for (String path : parts) {\n                if (filename.endsWith(path.substring(5))) {\n                    return true;\n                }\n            }\n        }\n        parser = buildAction.getParserByDisplayName(\"Iago\");\n        return parser != null;\n    }\n\n    public void setSummarizerSize(long summarizerSize) {\n        this.summarizerSize = summarizerSize;\n    }\n\n    public long getSummarizerSize() {\n        return summarizerSize;\n    }\n\n    public void setSummarizerMin(long summarizerMin) {\n        this.summarizerMin = summarizerMin;\n    }\n\n    public long getSummarizerMin() {\n        return summarizerMin;\n    }\n\n    public void setSummarizerMax(long summarizerMax) {\n        this.summarizerMax = summarizerMax;\n    }\n\n    public long getSummarizerMax() {\n        return summarizerMax;\n    }\n\n    public void setSummarizerAvg(long summarizerAvg) {\n        this.summarizerAvg = summarizerAvg;\n    }\n\n    public long getSummarizerAvg() {\n        return summarizerAvg;\n    }\n\n    public void setSummarizerErrors(String summarizerErrorPercent) {\n        this.summarizerErrorPercent = summarizerErrorPercent;\n    }\n\n    public String getSummarizerErrors() {\n        return summarizerErrorPercent;\n    }\n\n    public Long getThroughput() {\n        return throughput;\n    }\n\n    public int getBaselineBuild() {\n        return baselineBuild;\n    }\n\n    public void setBaselineBuild(int baselineBuild) {\n        this.baselineBuild = baselineBuild;\n    }\n\n    /**\n     * @return the filterRegex\n     */\n    public String getFilterRegex() {\n        return filterRegex;\n    }\n\n    /**\n     * @param filterRegex the filterRegex to set\n     */\n    public void setFilterRegex(String filterRegex) {\n        this.filterRegex = filterRegex;\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/reports/ThroughputReport.java",
    "content": "package hudson.plugins.performance.reports;\n\nimport java.util.List;\n\n/**\n * @author Artem Stasiuk (artem.stasuk@gmail.com)\n */\npublic class ThroughputReport {\n\n    private static final int MILLISECONDS_IN_SECOND = 1000;\n\n    private final PerformanceReport performanceReport;\n\n    public ThroughputReport(final PerformanceReport performanceReport) {\n        this.performanceReport = performanceReport;\n    }\n\n    public double get() {\n        Long throughput = performanceReport.getThroughput();\n        if (throughput != null) {\n            return throughput;\n        } else {\n            final List<UriReport> uriReports = performanceReport.getUriListOrdered();\n            if (uriReports.isEmpty()) {\n                return 0;\n            }\n\n\n            long sumSamplesCount = 0;\n            long startTime = Long.MAX_VALUE;\n            long endTime = 0;\n            for (UriReport uriReport : uriReports) {\n                sumSamplesCount += uriReport.samplesCount();\n\n                if (startTime > uriReport.getStart().getTime()) {\n                    startTime = uriReport.getStart().getTime();\n                }\n\n                if (endTime < uriReport.getEnd().getTime()) {\n                    endTime = uriReport.getEnd().getTime();\n                }\n            }\n\n            final long duration = endTime - startTime;\n\n            if (duration == 0) {\n                return sumSamplesCount; // more than zero requests should always take at least some time. If that didn't get logged, this is the most suitable alternative.\n            }\n\n            return (sumSamplesCount / ((double) duration / MILLISECONDS_IN_SECOND));\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/reports/UriReport.java",
    "content": "package hudson.plugins.performance.reports;\n\nimport java.io.IOException;\nimport java.io.Serializable;\nimport java.io.UnsupportedEncodingException;\nimport java.net.URLEncoder;\nimport java.nio.charset.StandardCharsets;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.ConcurrentSkipListMap;\n\n\nimport org.jfree.chart.JFreeChart;\nimport org.jfree.data.time.FixedMillisecond;\nimport org.jfree.data.time.Minute;\nimport org.jfree.data.time.TimeSeries;\nimport org.jfree.data.time.TimeSeriesCollection;\nimport org.jfree.data.xy.XYDataset;\nimport org.jfree.data.xy.XYSeries;\nimport org.jfree.data.xy.XYSeriesCollection;\nimport org.kohsuke.stapler.StaplerRequest;\nimport org.kohsuke.stapler.StaplerResponse;\n\nimport hudson.model.ModelObject;\nimport hudson.model.Run;\nimport hudson.plugins.performance.Messages;\nimport hudson.plugins.performance.actions.PerformanceProjectAction;\nimport hudson.plugins.performance.data.HttpSample;\nimport hudson.plugins.performance.data.TaurusFinalStats;\nimport hudson.plugins.performance.details.GraphConfigurationDetail;\nimport hudson.plugins.performance.tools.SafeMaths;\nimport hudson.util.Graph;\n\n/**\n * A report about a particular tested URI.\n * <p>\n * This object belongs under {@link PerformanceReport}.\n */\npublic class UriReport extends AbstractReport implements Serializable, ModelObject,\n        Comparable<UriReport> {\n\n    private static final long serialVersionUID = -5269155428479638524L;\n\n    public final static String END_PERFORMANCE_PARAMETER = \".endperformanceparameter\";\n\n    /**\n     * Escaped {@link #uri} that doesn't contain any letters that cannot be used\n     * as a token in URL.\n     */\n    private final String staplerUri;\n\n    private UriReport lastBuildUriReport;\n\n    /**\n     * The parent object to which this object belongs.\n     */\n    private final PerformanceReport performanceReport;\n\n    private String uri;\n\n    /**\n     * The amount of http samples that are not successful.\n     */\n    private int nbError = 0;\n\n    /**\n     * A list that contains the date and duration (in milliseconds) of all individual samples.\n     */\n    private final List<Sample> samples = new ArrayList<>(); // retain insertion order.\n\n    /**\n     * A lazy cache of all duration values in {@link #samples}, insertion order (same as {@link #samples}\n     */\n    private transient List<Long> durationsIO = new ArrayList<>();\n\n    /**\n     * A lazy cache of all duration values in {@link #samples}, ordered by duration.\n     */\n    private transient List<Long> durationsSortedBySize = new ArrayList<>();\n\n    /**\n     * Indicates if the collection {@link #durationsSortedBySize} is in a sorted state.\n     */\n    private transient boolean isSorted = false;\n\n    /**\n     * The duration of all samples combined, in milliseconds.\n     */\n    private long totalDuration = 0; // note that this is the sum of all elements in #durations, but need not be recalculated every time.\n\n    /**\n     * The set of (unique) HTTP status codes from all samples.\n     */\n    private Set<String> httpCodes = new HashSet<>();\n\n    /**\n     * The sum of summarizerSample values from all samples;\n     */\n    private long summarizerSize = 0;\n\n    /**\n     * The sum of summarizerErrors values from all samples;\n     */\n    private float summarizerErrors = 0;\n\n    /**\n     * The point in time of the start of the oldest sample.\n     */\n    private Date start = null;\n\n    /**\n     * The point in time of the end of the youngest sample.\n     */\n    private Date end = null;\n\n\n    private Long average;\n    private Long perc0;\n    private Long perc50;\n    private Long perc90;\n    private Long perc95;\n    private Long perc100;\n    @Deprecated\n    private Long throughput;\n\n    private int samplesCount;\n    protected String percentiles;\n\n    private double sizeInKb;\n\n    public Object readResolve() {\n        checkPercentileAndSet(0.0, perc0);\n        checkPercentileAndSet(50.0, perc50);\n        checkPercentileAndSet(90.0, perc90);\n        checkPercentileAndSet(95.0, perc95);\n        checkPercentileAndSet(100.0, perc100);\n        if (percentiles == null || percentiles.isBlank()) {\n            this.percentiles = DEFAULT_PERCENTILES;\n        }\n        return this;\n    }\n\n    public UriReport(PerformanceReport performanceReport, String staplerUri, String uri) {\n        this.performanceReport = performanceReport;\n        this.staplerUri = staplerUri;\n        this.uri = uri;\n        this.percentiles = performanceReport.percentiles;\n    }\n\n    public void addHttpSample(HttpSample sample) {\n        if (!sample.isSuccessful()) {\n            nbError++;\n        }\n        synchronized (samples) {\n            if (samples.add(Sample.convertFromHttpSample(sample))) {\n                isSorted = false;\n                samplesCount++;\n            }\n        }\n        if (isIncludeResponseTime(sample)) {\n            totalDuration += sample.getDuration();\n        }\n        httpCodes.add(sample.getHttpCode()); // The Set implementation will ensure that no duplicates will be saved.\n        summarizerSize += sample.getSummarizerSamples();\n        summarizerErrors += sample.getSummarizerErrors();\n        sizeInKb += sample.getSizeInKb();\n\n        if (start == null || sample.getDate().before(start)) {\n            start = sample.getDate();\n        }\n        Date finish = new Date(sample.getDate().getTime() + sample.getDuration());\n        if (end == null || finish.after(end)) {\n            end = finish;\n        }\n    }\n\n\n    public void setFromTaurusFinalStats(TaurusFinalStats report) {\n        average = (long) report.getAverageResponseTime();\n        perc0 = (long) report.getPerc0();\n        perc50 = (long) report.getPerc50();\n        perc90 = (long) report.getPerc90();\n        perc95 = (long) report.getPerc95();\n        perc100 = (long) report.getPerc100();\n\n        this.percentilesValues.put(0.0, (long) report.getPerc0());\n        this.percentilesValues.put(50.0, (long) report.getPerc50());\n        this.percentilesValues.put(90.0, (long) report.getPerc90());\n        this.percentilesValues.put(95.0, (long) report.getPerc95());\n        this.percentilesValues.put(100.0, (long) report.getPerc100());\n        calculateDiffPercentiles();\n        isCalculatedPercentilesValues = true;\n\n        summarizerSize = report.getBytes();\n        summarizerErrors = report.getFail();\n        nbError = report.getFail();\n\n        synchronized (samples) {\n            samplesCount = report.getSucc() + report.getFail();\n        }\n    }\n\n    public int compareTo(UriReport uriReport) {\n        if (uriReport == this) {\n            return 0;\n        }\n        return uriReport.getUri().compareTo(this.getUri());\n    }\n    @Override\n    public boolean equals(Object obj) {\n        if (this == obj) return true;\n        if (obj == null || getClass() != obj.getClass()) return false;\n        UriReport uriReport = (UriReport) obj;\n        return getUri() != null ? getUri().equals(uriReport.getUri()) : uriReport.getUri() == null;\n    }\n\n    @Override\n    public int hashCode() {\n        return getUri() != null ? getUri().hashCode() : 0;\n    }\n\n    public int countErrors() {\n        return nbError;\n    }\n\n    public double errorPercent() {\n        return Math.round((SafeMaths.safeDivide((double) countErrors(), samplesCount()) * 100) * 1000.0) / 1000.0;\n    }\n\n    public long getAverage() {\n        if (average == null) {\n            int samplesCount = samplesCount();\n            average = (samplesCount == 0) ? 0 : (long) SafeMaths.safeDivide(totalDuration, samplesCount);\n        }\n        return average;\n    }\n\n    private long getDurationAt(double percentage) {\n        if (percentage < ZERO_PERCENT || percentage > ONE_HUNDRED_PERCENT) {\n            throw new IllegalArgumentException(\"Argument 'percentage' must be a value between 0 and 100 (inclusive)\");\n        }\n\n        synchronized (samples) {\n            final List<Long> durations = getSortedDuration();\n\n            if (durations.isEmpty()) {\n                return 0;\n            }\n\n            final double percentInDecimals = percentage / 100;\n            int indexToReturn = ((int) (durationsSortedBySize.size() * percentInDecimals)) - 1;\n\n            // Make sure a valid index is used.\n            if (indexToReturn < 0) {\n                indexToReturn = 0;\n            } else if (indexToReturn >= durationsSortedBySize.size()) {\n                indexToReturn = durationsSortedBySize.size() - 1;\n            }\n\n            return durations.get(indexToReturn);\n        }\n    }\n\n    @Override\n    public void calculatePercentiles() {\n        List<Double> percs = super.parsePercentiles(percentiles);\n        for (Double perc : percs) {\n            super.percentilesValues.put(perc, getDurationAt(perc));\n        }\n        super.isCalculatedPercentilesValues = true;\n    }\n\n    @Override\n    public void calculateDiffPercentiles() {\n        List<Double> percs = super.parsePercentiles(percentiles);\n        for (Double perc : percs) {\n            Long diff = 0L;\n            if (lastBuildUriReport != null) {\n                Long previousValue = lastBuildUriReport.getPercentilesValues().get(perc);\n                Long currentValue = getPercentilesValues().get(perc);\n                if (previousValue != null && currentValue != null) {\n                    diff = currentValue - previousValue;\n                }\n            }\n            super.percentilesDiffValues.put(perc, diff);\n        }\n    }\n\n    public long get90Line() {\n        if (perc90 == null) {\n            perc90 = getDurationAt(NINETY_PERCENT);\n        }\n        return perc90;\n    }\n\n    public long get95Line() {\n        if (perc95 == null) {\n            perc95 = getDurationAt(NINETY_FIVE_PERCENT);\n        }\n        return perc95;\n    }\n\n    public String getHttpCode() {\n        return String.join(\",\", httpCodes);\n    }\n\n    public long getMedian() {\n        if (perc50 == null) {\n            perc50 = getDurationAt(FIFTY_PERCENT);\n        }\n        return perc50;\n    }\n\n    public Run<?, ?> getBuild() {\n        return performanceReport.getBuild();\n    }\n\n    public String getDisplayName() {\n        return getUri();\n    }\n\n    public List<Sample> getHttpSampleList() {\n        return samples;\n    }\n\n    public PerformanceReport getPerformanceReport() {\n        return performanceReport;\n    }\n\n    protected List<Long> getSortedDuration() {\n        synchronized (samples) {\n            if (!isSorted || durationsSortedBySize == null || durationsSortedBySize.size() != samples.size()) {\n\n                durationsSortedBySize = new ArrayList<>(samplesCount());\n                for (Sample sample : samples) {\n                    if (isIncludeResponseTime(sample)) {\n                        durationsSortedBySize.add(sample.duration);\n                    }\n                }\n                Collections.sort(durationsSortedBySize);\n                isSorted = true;\n            }\n\n            return durationsSortedBySize;\n        }\n    }\n\n    public List<Long> getDurations() {\n        synchronized (samples) {\n            if (durationsIO == null || durationsIO.size() != samples.size()) {\n                durationsIO = new ArrayList<>(samples.size());\n                for (Sample sample : samples) {\n                    if (isIncludeResponseTime(sample)) {\n                        durationsIO.add(sample.duration);\n                    }\n                }\n            }\n            return durationsIO;\n        }\n    }\n\n    public long getMax() {\n        if (perc100 == null) {\n            perc100 = getDurationAt(ONE_HUNDRED_PERCENT);\n        }\n        return perc100;\n    }\n\n    public long getMin() {\n        if (perc0 == null) {\n            perc0 = getDurationAt(ZERO_PERCENT);\n        }\n        return perc0;\n    }\n\n    public String getStaplerUri() {\n        return staplerUri;\n    }\n\n    public String getUri() {\n        return uri;\n    }\n\n    public String getShortUri() {\n        if (uri.length() > 130) {\n            return uri.substring(0, 129);\n        }\n        return uri;\n    }\n\n    public boolean isFailed() {\n        return countErrors() != 0;\n    }\n\n    public int samplesCount() {\n        synchronized (samples) {\n            return samplesCount;\n        }\n    }\n\n    public String encodeUriReport() throws UnsupportedEncodingException {\n        StringBuilder sb = new StringBuilder(120);\n        sb.append(performanceReport.getReportFileName()).append(\n                GraphConfigurationDetail.SEPARATOR).append(getStaplerUri()).append(\n                END_PERFORMANCE_PARAMETER);\n        return URLEncoder.encode(sb.toString(), StandardCharsets.UTF_8.name());\n    }\n\n    public void addLastBuildUriReport(UriReport lastBuildUriReport) {\n        this.lastBuildUriReport = lastBuildUriReport;\n        calculateDiffPercentiles();\n    }\n\n    public long getAverageDiff() {\n        if (lastBuildUriReport == null) {\n            return 0;\n        }\n        return getAverage() - lastBuildUriReport.getAverage();\n    }\n\n    public long getMedianDiff() {\n        if (lastBuildUriReport == null) {\n            return 0;\n        }\n        return getMedian() - lastBuildUriReport.getMedian();\n    }\n\n    public long get90LineDiff() {\n        if (lastBuildUriReport == null) {\n            return 0;\n        }\n        return get90Line() - lastBuildUriReport.get90Line();\n    }\n\n    public long get95LineDiff() {\n        if (lastBuildUriReport == null) {\n            return 0;\n        }\n        return get95Line() - lastBuildUriReport.get95Line();\n    }\n\n    public double getErrorPercentDiff() {\n        if (lastBuildUriReport == null) {\n            return 0;\n        }\n        return Math.round((errorPercent() - lastBuildUriReport.errorPercent()) * 1000.0) / 1000.0;\n    }\n\n    public String getLastBuildHttpCodeIfChanged() {\n        if (lastBuildUriReport == null) {\n            return \"\";\n        }\n\n        if (lastBuildUriReport.getHttpCode().equals(getHttpCode())) {\n            return \"\";\n        }\n\n        return lastBuildUriReport.getHttpCode();\n    }\n\n    public int getSamplesCountDiff() {\n        if (lastBuildUriReport == null) {\n            return 0;\n        }\n        return samplesCount() - lastBuildUriReport.samplesCount();\n    }\n\n    public float getSummarizerErrors() {\n        return summarizerErrors / summarizerSize * 100;\n    }\n\n    public void doSummarizerTrendGraph(StaplerRequest request, StaplerResponse response) throws IOException {\n        TimeSeries responseTimes = new TimeSeries(Messages.ProjectAction_RespondingTime());\n        synchronized (samples) {\n            for (Sample sample : samples) {\n                if (isIncludeResponseTime(sample)) {\n                    responseTimes.addOrUpdate(new FixedMillisecond(sample.date), sample.duration);\n                }\n            }\n        }\n\n        TimeSeriesCollection resp = new TimeSeriesCollection();\n        resp.addSeries(responseTimes);\n\n        ArrayList<XYDataset> dataset = new ArrayList<>();\n        dataset.add(resp);\n\n        new Graph(-1, 400, 200) {\n            @Override\n            protected JFreeChart createGraph() {\n                return PerformanceProjectAction.createSummarizerTrend(dataset, uri);\n            }\n        }.doPng(request, response);\n    }\n\n    public void doErrorGraph(StaplerRequest request, StaplerResponse response) throws IOException {\n        TimeSeries errors = new TimeSeries(Messages.ProjectAction_Errors());\n        synchronized (samples) {\n            for (Sample sample : samples) {\n                if (sample.isFailed() && !sample.isSummarizer()) {\n                    errors.addOrUpdate(new FixedMillisecond(sample.date), sample.duration);\n                }\n            }\n        }\n        ArrayList<XYDataset> dataset = new ArrayList<>();\n        dataset.add(new TimeSeriesCollection(errors));\n\n        // Re-use the same scatter plotter for error response times:\n        new Graph(-1, 400, 200) {\n            @Override\n            protected JFreeChart createGraph() {\n                return PerformanceProjectAction.createSummarizerTrend(dataset, uri);\n            }\n        }.doPng(request, response);\n    }\n\n    public void doPercentileGraph(StaplerRequest request, StaplerResponse response) throws IOException {\n        final ConcurrentSkipListMap<Long, Long> responseTimesHistogram = new ConcurrentSkipListMap<>(); // we want keys in sorted order\n        long totalNoOfSamples = 0L;\n        synchronized (samples) {\n            for (Sample sample : samples) {\n                if (isIncludeResponseTime(sample)) {\n                    totalNoOfSamples++;\n                    // count number of sample occurrences with the same response time value:\n                    responseTimesHistogram.put(sample.duration,\n                            responseTimesHistogram.containsKey(sample.duration) ? responseTimesHistogram.get(sample.duration) + 1 : 1);\n                }\n            }\n        }\n        XYSeries percentiles = new XYSeries(Messages.TrendReportDetail_ResponseTimePercentiles());\n        long cumulativeTotal = 0; // adds up the running total number of samples for percentile calculation\n        percentiles.add(0, responseTimesHistogram.firstKey()); // add 0th percentile (minimum response time)\n\n        for (Map.Entry<Long, Long> responseTimeOccurrence : responseTimesHistogram.entrySet()) {\n            cumulativeTotal += responseTimeOccurrence.getValue();\n            percentiles.addOrUpdate((double) 100.0 * cumulativeTotal / totalNoOfSamples, (double) responseTimeOccurrence.getKey()); // float value will result in smoother curve\n        }\n\n        new Graph(-1, 400, 200) {\n            @Override\n            protected JFreeChart createGraph() {\n                return PerformanceProjectAction.createUriPercentileChart(new XYSeriesCollection(percentiles), uri);\n            }\n        }.doPng(request, response);\n    }\n\n    public void doThroughputGraph(StaplerRequest request, StaplerResponse response) throws IOException {\n        final Map<Minute, Long> throughputIntervals = new HashMap<>();\n        synchronized (samples) {\n            for (Sample sample : samples) {\n                if (isIncludeResponseTime(sample)) {\n                    Minute timeBucket = new Minute(sample.date);\n                    // count number of samples in the same time bucket\n                    throughputIntervals.put(timeBucket,\n                            throughputIntervals.containsKey(timeBucket) ? throughputIntervals.get(timeBucket) + 1 : 1);\n                }\n            }\n        }\n        TimeSeries throughput = new TimeSeries(Messages.TrendReportDetail_RequestThroughput());\n        for (Map.Entry<Minute, Long> timeBucket : throughputIntervals.entrySet()) {\n            throughput.add(timeBucket.getKey(), timeBucket.getValue());\n        }\n\n        new Graph(-1, 400, 200) {\n            @Override\n            protected JFreeChart createGraph() {\n                return PerformanceProjectAction.createUriThroughputChart(new TimeSeriesCollection(throughput), uri);\n            }\n        }.doPng(request, response);\n    }\n\n    public Date getStart() {\n        return start;\n    }\n\n    public Date getEnd() {\n        return end;\n    }\n\n\n    protected boolean isIncludeResponseTime(Sample sample) {\n        return !(sample.isFailed() && excludeResponseTime && !sample.isSummarizer());\n    }\n\n    public static class Sample implements Serializable, Comparable<Sample> {\n\n        private static final long serialVersionUID = 4458431861223813407L;\n\n        protected final Date date;\n        protected final long duration;\n        protected final String httpCode;\n        protected final boolean isSuccessful;\n        protected final boolean isSummarizer;\n\n        public Sample(Date date, long duration, String httpCode, boolean isSuccessful, boolean isSummarizer) {\n            this.date = date;\n            this.duration = duration;\n            this.httpCode = httpCode;\n            this.isSuccessful = isSuccessful;\n            this.isSummarizer = isSummarizer;\n        }\n\n        public static Sample convertFromHttpSample(HttpSample httpSample) {\n            return new Sample(httpSample.getDate(), httpSample.getDuration(), httpSample.getHttpCode(),\n                    httpSample.isSuccessful(), httpSample.isSummarizer());\n        }\n\n        public String getHttpCode() {\n            return httpCode;\n        }\n\n        public Date getDate() {\n            return date;\n        }\n\n        public long getDuration() {\n            return duration;\n        }\n\n        public boolean isSuccessful() {\n            return isSuccessful;\n        }\n\n        public boolean isFailed() {\n            return !isSuccessful();\n        }\n\n        public boolean isSummarizer() {\n            return isSummarizer;\n        }\n\n        /**\n         * Compare first based on duration, next on date.\n         */\n        public int compareTo(Sample other) {\n            if (this == other) return 0;\n            if (this.duration < other.duration) return -1;\n            if (this.duration > other.duration) return 1;\n            if (this.date == null || other.date == null) return 0;\n            if (this.date.before(other.date)) return -1;\n            if (this.date.after(other.date)) return 1;\n            return 0;\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            if (this == obj) return true;\n            if (obj == null || getClass() != obj.getClass()) return false;\n            Sample other = (Sample) obj;\n            if (duration != other.duration) return false;\n            return date != null ? date.equals(other.date) : other.date == null;\n        }\n\n        @Override\n        public int hashCode() {\n            int result = (int) (duration ^ (duration >>> 32));\n            result = 31 * result + (date != null ? date.hashCode() : 0);\n            return result;\n        }\n    }\n\n    @Deprecated\n    public void setThroughput(Long throughput) {\n        this.throughput = throughput;\n    }\n\n    @Deprecated\n    public Long getThroughput() {\n        return throughput;\n    }\n\n    public boolean hasSamples() {\n        return !samples.isEmpty();\n    }\n\n    public double getAverageSizeInKb() {\n        return SafeMaths.roundTwoDecimals(SafeMaths.safeDivide(sizeInKb, samplesCount()));\n    }\n\n    public double getTotalTrafficInKb() {\n        return SafeMaths.roundTwoDecimals(sizeInKb);\n    }\n\n    public double getAverageSizeInKbDiff() {\n        if (lastBuildUriReport == null) {\n            return 0;\n        }\n        return SafeMaths.roundTwoDecimals(getAverageSizeInKb() - lastBuildUriReport.getAverageSizeInKb());\n    }\n\n    public double getTotalTrafficInKbDiff() {\n        if (lastBuildUriReport == null) {\n            return 0;\n        }\n        return SafeMaths.roundTwoDecimals(getTotalTrafficInKb() - lastBuildUriReport.getTotalTrafficInKb());\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/tools/SafeMaths.java",
    "content": "package hudson.plugins.performance.tools;\n\nimport java.math.BigDecimal;\nimport java.math.RoundingMode;\n\npublic class SafeMaths {\n\tpublic static double safeDivide(double dividend, double divisor) {\n\t\tif (Double.compare(divisor, Double.NaN) == 0) {\n\t\t\treturn Double.NaN;\n\t\t}\n\t\tif (Double.compare(dividend, Double.NaN) == 0) {\n\t\t\treturn Double.NaN;\n\t\t}\n\t\tif (Double.compare(divisor, 0.0) == 0) {\n\t\t\tif (Double.compare(dividend, 0.0) == -1) {\n\t\t\t\treturn Double.NEGATIVE_INFINITY;\n\t\t\t}\n\t\t\treturn Double.POSITIVE_INFINITY;\n\t\t}\n\t\tif (Double.compare(divisor, -0.0) == 0) {\n\t\t\tif (Double.compare(dividend, -0.0) == 1) {\n\t\t\t\treturn Double.NEGATIVE_INFINITY;\n\t\t\t}\n\t\t\treturn Double.POSITIVE_INFINITY;\n\t\t}\n\t\treturn dividend / divisor;\n\t}\n\t\n\tpublic static double roundTwoDecimals(double d) {\n        BigDecimal bd = BigDecimal.valueOf(d);\n        bd = bd.setScale(2, RoundingMode.HALF_UP);\n        return bd.doubleValue();\n    }\n}\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/workflow/WorkflowActionsFactory.java",
    "content": "package hudson.plugins.performance.workflow;\n\n\nimport hudson.Extension;\nimport hudson.model.Action;\nimport hudson.model.Job;\nimport hudson.model.Run;\nimport hudson.plugins.performance.actions.PerformanceBuildAction;\nimport hudson.plugins.performance.actions.PerformanceProjectAction;\nimport jenkins.model.TransientActionFactory;\n\nimport edu.umd.cs.findbugs.annotations.NonNull;\nimport java.util.Collection;\nimport java.util.Collections;\n\n@Extension\npublic class WorkflowActionsFactory extends TransientActionFactory<Job> {\n\n    @Override\n    public Class<Job> type() {\n        return Job.class;\n    }\n\n    @NonNull\n    @Override\n    public Collection<? extends Action> createFor(@NonNull Job job) {\n        if (job.getClass().getCanonicalName().startsWith(\"org.jenkinsci.plugins.workflow\")) {\n            final Run<?, ?> r = job.getLastSuccessfulBuild();\n            if (r != null && !r.getActions(PerformanceBuildAction.class).isEmpty()) {\n                return Collections.singletonList(new PerformanceProjectAction(job));\n            }\n        }\n        return Collections.emptyList();\n    }\n}\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/Messages.properties",
    "content": "ProjectAction.PercentageOfErrors=Percentage of errors\nProjectAction.RespondingTime=Response time\nProjectAction.Throughput=Throughput\nProjectAction.RequestsPerSeconds=Requests Per Second\nProjectAction.Errors=errors\nProjectAction.Maximum=max\nProjectAction.Minimum=min\nProjectAction.TotalTrafficKB=total kb\nProjectAction.AverageKB=average kb\nProjectAction.Average=average\nProjectAction.Median=median\nProjectAction.Line90=90% line\nProjectAction.Line95=95% line\nProjectAction.PercentageOfFailedTests=Percentage of failed tests\nBuildAction.DisplayName=Performance Report\nProjectAction.DisplayName=Performance Trend\nPublisher.DisplayName=Publish Performance test result report\nReport.DisplayName=Performance\nCsvParser.validation.MissingFields=Missing required fields\nCsvParser.validation.delimiterEmpty=Delimiter can't be empty\nCsvParser.validation.patternEmpty=Pattern is required\nGraphConfigurationDetail.DisplayName=Configure\nTrendReportDetail.DisplayName=Trend report\nTrendReportDetail.ResponseTime=Response Time (ms)\nTrendReportDetail.Time=Time\nTrendReportDetail.Percent=Percent\nTrendReportDetail.RequestsPerMinute=Requests Per Minute\nTrendReportDetail.RequestThroughput=Request Throughput\nTrendReportDetail_ResponseTimePercentiles=Response Time Percentiles\nTestSuiteReportDetail.DisplayName=Test Suite report\nPerformanceTest.Name=Run Performance Test\nPerformanceTest.Config=Performance Test\n\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/Messages_es.properties",
    "content": "ProjectAction.PercentageOfErrors=Porcentaje de errores\nProjectAction.RespondingTime=Tiempo de respuesta\nProjectAction.Errors=errores\nProjectAction.Maximum=mx\nProjectAction.Minimum=mn\nProjectAction.Average=media\nProjectAction.Median=mediana\nProjectAction.Line90=Lnea 90%\nProjectAction.Line95=Lnea 95%\nProjectAction.TotalTrafficKB=total kb\nProjectAction.AverageKB=average kb\nBuildAction.DisplayName=Informe de Rendimiento\nProjectAction.DisplayName=Tendencia de Rendimiento\nPublisher.DisplayName=Publicar informes de tests de rendimiento\nReport.DisplayName=Rendimiento\nGraphConfigurationDetail.DisplayName=Configurar\nTrendReportDetail.DisplayName=Informe de tendencia\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformancePublisher/config.jelly",
    "content": "<?jelly escape-by-default='true'?>\n<j:jelly xmlns:j=\"jelly:core\" xmlns:f=\"/lib/form\" xmlns:p=\"/lib/performance\">\n\n  <f:entry title=\"${%Source files}\" field=\"sourceDataFiles\">\n    <f:textbox />\n  </f:entry>\n\n   <f:entry title=\"${%filterRegex}\" field=\"filterRegex\">\n      <f:textbox />\n   </f:entry>\n\n  <f:entry title=\"Show Trend Graphs\" field=\"showTrendGraphs\" >\n    <f:checkbox name=\"showTrendGraphs\" field=\"showTrendGraphs\" checked=\"true\"  />\n  </f:entry>\n\n  <f:entry title=\"Select evaluation mode\" field=\"modeEvaluation\">\n    <f:booleanRadio name=\"modeEvaluation\"  false=\"Standard Mode\" true=\"Expert Mode\" />\n  </f:entry>\n\n  <f:entry>\n    <p:blockWrapper style=\"border:1;border-style:solid;\" divStyle=\"margin-left:50px; padding-left:6px; padding-right:6px;\">\n      <p><b>Standard Mode</b></p>\n      <f:block>\n        <f:radioBlock name=\"_.modeOfThreshold\" field=\"modeOfThreshold\" value=\"false\" title=\"Error Threshold\" checked=\"${!instance.getModeOfThreshold()}\" inline=\"true\" help=\"${null}\">\n          <f:entry title=\"Use Error thresholds on single build:   \">\n            <p:blockWrapper>\n              <f:block>\n                <f:entry title=\"${%Unstable}\">\n                  <f:textbox field=\"errorUnstableThreshold\" default=\"-1\"/>\n                </f:entry>\n                <f:entry title=\"${%Failed}\">\n                  <f:textbox field=\"errorFailedThreshold\" default=\"-1\"/>\n                </f:entry>\n                <f:advanced>\n                  <f:entry title=\"${%Average response time threshold}\" field=\"errorUnstableResponseTimeThreshold\">\n                    <f:textarea style=\"height:100px;\"/>\n                  </f:entry>\n                </f:advanced>\n              </f:block>\n            </p:blockWrapper>\n          </f:entry>\n        </f:radioBlock>\n        <f:radioBlock name=\"_.modeOfThreshold\" field=\"modeOfThreshold\" value=\"true\" title=\"Relative Threshold\" checked=\"${instance.getModeOfThreshold()}\" inline=\"true\" help=\"${null}\">\n          <f:entry title=\"Use Relative thresholds for build comparison:   \">\n            <p:blockWrapper>\n              <f:block>\n                <table cellspacing=\"5\">\n                  <tr>\n                    <td width=\"25%\">\n                      <label> </label>\n                    </td>\n                    <td width=\"20%\" align=\"center\">\n                      <label>(-)</label>\n                    </td>\n                    <td width=\"20%\" align=\"center\">\n                      <label>(+)</label>\n                    </td>\n                  </tr>\n                  <tr>\n                    <td width=\"25%\">\n                      <label>Unstable % Range</label>\n                    </td>\n                    <td>\n                      <f:number field=\"relativeUnstableThresholdNegative\" default=\"-1.0\"/>\n                    </td>\n                    <td>\n                      <f:number field=\"relativeUnstableThresholdPositive\" default=\"-1.0\"/>\n                    </td>\n                  </tr>\n                  <tr>\n                    <td width=\"25%\">\n                      <label>Failed % Range</label>\n                    </td>\n                    <td>\n                      <f:number field=\"relativeFailedThresholdNegative\" default=\"-1.0\"/>\n                    </td>\n                    <td>\n                      <f:number field=\"relativeFailedThresholdPositive\" default=\"-1.0\"/>\n                    </td>\n                  </tr>\n                </table>\n                <f:radioBlock name=\"_.compareBuildPrevious\" field=\"compareBuildPrevious\" value=\"true\" title=\"Compare with previous Build\" checked=\"${instance.getCompareBuildPrevious()}\" inline=\"true\">\n                </f:radioBlock>\n                <f:radioBlock name=\"_.compareBuildPrevious\" field=\"compareBuildPrevious\" value=\"false\" title=\"Compare with Build number\" checked=\"${!instance.getCompareBuildPrevious()}\" inline=\"true\">\n                  <f:entry title=\"Build number\">\n                    <f:number field=\"nthBuildNumber\"/>\n                  </f:entry>\n                </f:radioBlock>\n                <f:entry title=\"${%Compare based on}\" field=\"configType\" name=\"configType\">\n                  <f:select name=\"configType\">\n                    <option value=\"ART\">Average Response Time</option>\n                    <option value=\"MRT\">Median Response Time</option>\n                    <option value=\"PRT\">90% ResponseTime</option>\n                  </f:select>\n                </f:entry>\n              </f:block>\n            </p:blockWrapper>\n          </f:entry>\n        </f:radioBlock>\n      </f:block>\n    </p:blockWrapper>\n  </f:entry>\n\n  <f:entry>\n    <p:blockWrapper style=\"border:1;border-style:solid;\" divStyle=\"margin-left:50px; padding-left:6px; padding-right:6px;\">\n      <p><b>Expert Mode</b></p>\n      <f:block>\n        <f:entry title=\"Constraint settings\">\n          <f:entry>\n            <f:checkbox name=\"ignoreFailedBuilds\" title=\"Ignore Failed Builds\"  checked=\"${instance.isIgnoreFailedBuilds()}\"/>\n          </f:entry>\n          <f:entry>\n            <f:checkbox name=\"ignoreUnstableBuilds\" title=\"Ignore Unstable Builds\" field=\"ignoreUnstableBuilds\" checked=\"${instance.isIgnoreUnstableBuilds()}\"/>\n          </f:entry>\n          <f:entry>\n            <f:checkbox name=\"persistConstraintLog\" title=\"Save constraint log to workspace\"  checked=\"${instance.isPersistConstraintLog()}\"/>\n          </f:entry>\n        </f:entry>\n\n        <f:entry title=\"${%JUnit output file}\">\n          <f:textbox name=\"junitOutput\" field=\"junitOutput\" default=\"\"/>\n        </f:entry>\n\n        <f:entry title=\"Constraints\" field=\"constraints\">\n          <f:hetero-list name=\"constraints\" hasHeader=\"true\"\n                     descriptors=\"${descriptor.getConstraintDescriptors()}\"\n                     items=\"${instance.constraints}\"\n                     addCaption=\"${%Add a new constraint}\"/>\n        </f:entry>\n      </f:block>\n    </p:blockWrapper>\n  </f:entry>\n\n  <f:advanced>\n    <f:entry field=\"graphType\" name=\"graphType\" title=\"Select graphed metric\">\n      <f:select name=\"graphType\">\n        <option value=\"ART\">Average Response Time</option>\n        <option value=\"MRT\">Median Response Time</option>\n        <option value=\"PRT\">90% Response Time</option>\n      </f:select>\n    </f:entry>\n\n    <f:entry title=\"Select display percentiles\">\n      <f:textbox name=\"percentiles\" field=\"percentiles\" default=\"0,50,90,95,100\"/>\n    </f:entry>\n\n    <f:entry title=\"${%Performance display}\">\n      <f:entry>\n        <f:checkbox name=\"modePerformancePerTestCase\" title=\"Display Performance Report Per Test Case\" field=\"modePerformancePerTestCase\">\n          Display Performance Report Per Test Case\n        </f:checkbox>\n      </f:entry>\n      <f:entry>\n        <f:checkbox name=\"modeThroughput\" title=\"Display Performance Report with Throughput (requests per second)\" field=\"modeThroughput\">\n          Display Performance Report with Throughput (requests per second)\n        </f:checkbox>\n      </f:entry>\n      <f:entry>\n        <f:checkbox name=\"excludeResponseTime\" title=\"Exclude response time of errored samples\" field=\"excludeResponseTime\">\n          Exclude response time of errored samples\n        </f:checkbox>\n      </f:entry>\n      <f:entry>\n        <f:checkbox name=\"failBuildIfNoResultFile\" title=\"Fail build when result files are not present\" default=\"true\" field=\"failBuildIfNoResultFile\">\n          Fail build when result files are not present\n        </f:checkbox>\n      </f:entry>\n    </f:entry>\n    <f:entry title=\"Baseline build number\">\n      <f:number name=\"baselineBuild\" field=\"baselineBuild\" />\n    </f:entry>\n  </f:advanced>\n\n</j:jelly>\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformancePublisher/config.properties",
    "content": "\n\nPerformance\\ report=Performance report\n\nPerformance\\ threshold=Performance threshold\nThreshold.Description=\\\n   Specify the error percentage threshold that set the build \\\n   unstable or failed (a negative value means: don't use this threshold).\nThresholds=Thresholds\n\nUnstable=Unstable\nFailed=Failed\nSource\\ files=Source data files (autodetects format):\nfilterRegex=Regex for included samplers\nJUnit\\ output\\ file=JUnit output file (optional)\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformancePublisher/config_es.properties",
    "content": "\n\nPerformance\\ report=Informes de Rendimiento\n\nPerformance\\ threshold=Umbrales de rendimiento.\nThreshold.Description=\\\n   Especifica el porcentaje de errores que har que la ejecucin se marque como inestable o fallida \\\n   (un valor de 0 significa no usar este umbral). \n\nThresholds=Umbrales\n\nUnstable=Inestable\nFailed=Fallido\nAdd\\ a\\ new\\ report=Aadir un nuevo informe\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformancePublisher/config_zh_TW.properties",
    "content": "# The MIT License\n#\n# Copyright (c) 2004-2010, Sun Microsystems, Inc.\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n# THE SOFTWARE.\n\nFailed=\\u5931\\u6557\nUnstable=\\u4E0D\\u7A69\\u5B9A\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformancePublisher/help-errorUnstableResponseTimeThreshold.html",
    "content": "\n<div>\nThe thresholds settings should be delimited by a new line character \"\\n\".\n</div>\n<div style=\"margin:0 0 20px 0;\">\nThe actual threshold number should be seperated from the test file name by a colon \":\"\n</div> \n<pre>\nExample:\n-------------------------------------\nJMeterResultsOrders.jtl:2000\nJMeterResultsGetCustomer.jtl:500\nJMeterResultsCreateCustomer.jtl:700\n-------------------------------------\n</pre>\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformancePublisher/help-filterRegex.html",
    "content": "<div>\n<p>\n  If this field is not empty, its content will be considered as a regular expression to only take into \n  account URI matching it.\n</p>\n<p>\n  Example : ^(HP|Scenario|Search)(-success|-failure)?$\n</p>\n</div>"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformancePublisher/help-modeEvaluation.html",
    "content": "<div>\n<p>\n  Standard Mode activates upper box and ignores lower box.\n</p>\n<p>\n  Expert Mode activates lower box and ignores upper box.\n</p>\n</div>"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformancePublisher/help-persistPerformanceChart.html",
    "content": "<div>\n<p>\n  Persists the ErrorGraph and the RespondingTimePerTestCaseGraph in the workspace.\n</p>\n<p>\n  Cannot be done if Jenkins root URL is not set in the Jenkins System Configuration.\n</p>\n<!-- This file does not automatically get integrated in the UI. Don't know why -->\n</div>"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformancePublisher/help-persistPerformanceCharts.html",
    "content": "<div>\n<p>\n  Persists the ErrorGraph and the RespondingTimePerTestCaseGraph in the workspace.\n</p>\n<p>\n  Cannot be done if Jenkins root URL is not set in the Jenkins System Configuration.\n</p>\n<!-- This file does not automatically get integrated in the UI. Don't know why -->\n</div>"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformancePublisher/help-sourceDataFiles.html",
    "content": "<div>\n    <p>\n        Specify the path to the Performance report files, relative to the <a href='ws/'>workspace root</a>.\n        Plugin will be automatically detect parser for each report file.\n    </p>\n\n    <ul>\n        <li>You can specify multiple files and directories separated by semicolon.\n        <li>You use an Ant 'fileset' pattern.\n    </ul>\n    <p>\n        Default Values are:\n    </p>\n    <ul>\n        <li>JMeter reports: \"**/*.jtl\"</li>\n        <li>JMeter csv reports: \"**/*.csv\"</li>\n        <li>JMeter Summariser reports: \"**/*.log\"</li>\n        <li>Taurus reports: \"**/*.xml\"</li>\n        <li>JUnit report:   \"**/TEST-*.xml\"</li>\n        <li>wrk report:  \"**/*.wrk\"</li>\n        <li>Locust report:  \"**/*_stats.csv\"</li>\n    </ul>\n\n    <p>\n        * By default jmeter writes summariser statistics to jmeter.log. To enable logging\n        summariser statistics to separate log file add the property to jmeter.properties file to #Logging Configuration block : \"log_file.jmeter.reporters.Summariser=filename.log\"\n    </p>\n    <p>\n        ** Default time format, that JMeter used for logging is \"yyyy/mm/dd HH:mm:ss\". See \"log_format\" property  in jmeter.properties file in #Logging Configuration block.\n    </p>\n    <p>\n        *** By default wrk does not write output files. You'll\n        need to redirect the STDOUT output for a file as in\n    </p>\n    <pre>wrk [options] [url] > results.wrk</pre>\n</div>\n\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformanceReportMap/CVS/Entries",
    "content": "/index.jelly/1.3/Wed Nov 18 16:14:45 2009//\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformanceReportMap/CVS/Repository",
    "content": "iceteaperf/hudson/plugins/jmeter/src/main/resources/hudson/plugins/jmeter/JMeterReportMap\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformanceReportMap/CVS/Root",
    "content": ":extssh:aespy@cvs.venezia.dev.impots:/cvsroot/ice\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformanceReportMap/index.jelly",
    "content": "<?jelly escape-by-default='true'?>\n<j:jelly xmlns:j=\"jelly:core\" xmlns:st=\"jelly:stapler\" xmlns:l=\"/lib/layout\" >\n  <l:layout xmlns:jm=\"/hudson/plugins/performance/tags\" css=\"/plugin/performance/css/style.css\">\n  <st:include it=\"${it.build}\" page=\"sidepanel.jelly\" />\n\n    <l:main-panel>\n      <j:forEach var=\"performanceReport\" items=\"${it.getPerformanceListOrdered()}\">\n        <h2>${%Performance Breakdown by URI}: ${performanceReport.getReportFileName()}</h2>\n\n          <j:if test=\"${it.ifShowTrendGraphsUsed()}\">\n            <j:if test=\"${it.ifModeThroughputUsed()}\">\n              <img class=\"trend\" src=\"./throughputGraph?width=600&amp;height=225&amp;performanceReportPosition=${performanceReport.getReportFileName()}\" width=\"600\" height=\"225\" />\n            </j:if>\n\n            <j:choose>\n              <j:when test=\"${performanceReport.ifSummarizerParserUsed(performanceReport.getReportFileName())}\">\n                <img class=\"trend\" src=\"./summarizerGraph?width=600&amp;height=325&amp;performanceReportPosition=${performanceReport.getReportFileName()}\" width=\"600\" height=\"325\" />\n              </j:when>\n              <j:otherwise>\n                <j:choose>\n                  <j:when test=\"${it.ifModePerformancePerTestCaseUsed()}\">\n                    <a href=\"./respondingTimeGraphPerTestCaseMode?width=900&amp;height=550&amp;performanceReportPosition=${performanceReport.getReportFileName()}\" title=\"${%Click for larger image}\">                                <img class=\"trend\" src=\"./respondingTimeGraphPerTestCaseMode?width=600&amp;height=225&amp;legendLimit=5&amp;performanceReportPosition=${performanceReport.getReportFileName()}\" width=\"600\" height=\"225\" />\n                    </a>\n                  </j:when>\n                  <j:otherwise>\n                    <a href=\"./respondingTimeGraph?width=900&amp;height=550&amp;performanceReportPosition=${performanceReport.getReportFileName()}\" title=\"${%Click for larger image}\">\n                      <img class=\"trend\" src=\"./respondingTimeGraph?width=600&amp;height=225&amp;legendLimit=5&amp;performanceReportPosition=${performanceReport.getReportFileName()}\" width=\"600\" height=\"225\" />\n                    </a>\n                  </j:otherwise>\n                </j:choose>\n              </j:otherwise>\n            </j:choose>\n\n            <img class=\"trend\" src=\"./errorsGraph?width=600&amp;height=225&amp;performanceReportPosition=${performanceReport.getReportFileName()}\" width=\"600\" height=\"225\" />\n          </j:if>\n        <p><a href=\"./trendReport?performanceReportPosition=${performanceReport.getReportFileName()}\">${% Response time trends for build: }\"${it.build}\" </a></p>\n\n        <j:choose>\n          <j:when test=\"${performanceReport.getBaselineBuild() != 0}\">\n            <h4>Comparison with build #${performanceReport.getBaselineBuild()}</h4>\n          </j:when>\n          <j:otherwise>\n            <h4>Comparison with previous build</h4>\n          </j:otherwise>\n        </j:choose>\n        <table class=\"sortable source\" border=\"1\">\n         <jm:captionLine it=\"${performanceReport}\"/>\n         <j:forEach var=\"uriReport\" items=\"${performanceReport.getUriListOrdered()}\">\n           <tr class=\"${h.ifThenElse(uriReport.failed,'red','')}\">\n             <td class=\"left\">\n               <a href=\"./uriReport/${uriReport.encodeUriReport()}\">\n                 <st:out value=\"${uriReport.getStaplerUri()}\" />\n               </a>\n             </td>\n           <j:choose>\n             <j:when test=\"${performanceReport.ifSummarizerParserUsed(performanceReport.getReportFileName())}\">\n               <jm:summaryTableSummarizer it=\"${performanceReport}\" />\n             </j:when>\n             <j:otherwise>\n               <jm:summaryTable it=\"${uriReport}\" />\n             </j:otherwise>\n           </j:choose>\n           </tr>\n         </j:forEach>\n          <j:choose>\n           <j:when test=\"${performanceReport.ifSummarizerParserUsed(performanceReport.getReportFileName())}\">\n           </j:when>\n           <j:otherwise>\n            <tr class=\"sortbottom bold\">\n              <td class=\"left bold\">${%All URIs}</td>\n              <jm:summaryTable it=\"${performanceReport}\" />\n            </tr>\n           </j:otherwise>\n          </j:choose>\n        </table>\n      </j:forEach>\n    </l:main-panel>\n  </l:layout>\n</j:jelly>"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformanceReportMap/index_es.properties",
    "content": "Performance\\ Breakdown\\ by\\ URI=Rendimiento por URI\nAll\\ URIs=Todas las URIs\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformanceReportMap/index_fr.properties",
    "content": "# The MIT License\n#\n# Copyright (c) 2004-2010, Sun Microsystems, Inc.\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n# THE SOFTWARE.\n\nAll\\ URIs=Toutes les URIs\nPerformance\\ Breakdown\\ by\\ URI=Test de charge par URI\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/TrendReportGraphs/index.jelly",
    "content": "<?jelly escape-by-default='true'?>\n<j:jelly xmlns:j=\"jelly:core\" xmlns:st=\"jelly:stapler\" xmlns:l=\"/lib/layout\">\n  <l:layout xmlns:jm=\"/hudson/plugins/performance/tags\"  css=\"/plugin/performance/css/style.css\">\n    <l:main-panel>\n      <h1>${%Trend report}: ${it.filename}</h1>\n      <j:forEach var=\"URI\" items=\"${it.getUris()}\">\n        <h1>${%URI}: ${URI}</h1>\n          <j:if test=\"${it.hasSamples(URI)}\">\n            <a href=\"./respondingTimeGraph?width=1500&amp;height=650&amp;performanceReportPosition=${it.filename}&amp;summarizerTrendUri=${URI}\" title=\"${%Click for larger image}\">\n                <img class=\"trend\" src=\"./respondingTimeGraph?width=600&amp;height=325&amp;performanceReportPosition=${it.filename}&amp;summarizerTrendUri=${URI}\" width=\"600\" height=\"325\" />\n            </a>\n          </j:if>\n        <br></br>\n        <table border=\"1\" class=\"source\">\n          <jm:captionLine it=\"${it.getPerformanceReport()}\"/>\n          <strong class=\"uri\">${%URI}: ${URI}</strong>\n         <tr>\n          <td class=\"left\">\n              <st:out value=\"${it.getUriReport(URI).getStaplerUri()}\" />\n          </td>\n          <j:choose>\n            <j:when test=\"${it.getUriReport(URI).getPerformanceReport().ifSummarizerParserUsed(it.getPerformanceReport().getReportFileName())}\">\n              <jm:summaryTableSummarizer it=\"${it.getUriReport(URI)}\" />\n            </j:when>\n            <j:otherwise>\n              <jm:summaryTable it=\"${it.getUriReport(URI)}\" />\n            </j:otherwise>\n          </j:choose>\n         </tr>\n        </table>\n      </j:forEach>\n    </l:main-panel>\n  </l:layout>\n</j:jelly>\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/TrendReportGraphs/index_es.properties",
    "content": "# The MIT License\n#\n# Copyright (c) 2004-2010, Sun Microsystems, Inc.\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n# THE SOFTWARE.\n\nTrend\\ report=Informe de tendencia\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/actions/PerformanceProjectAction/floatingBox.jelly",
    "content": "<?jelly escape-by-default='true'?>\r\n<j:jelly xmlns:j=\"jelly:core\">\r\n  <j:if test=\"${from.isTrendVisibleOnProjectDashboard()}\">\r\n    <div class=\"test-trend-caption\">\r\n      ${%Performance Trend}\r\n      <br/>\r\n      <div>\r\n      </div>\r\n      <br/>\r\n\r\n      <j:if test=\"${from.ifModeThroughputUsed()}\">\r\n        <a href=\"performance/\"><img src=\"performance/throughputGraph\"/></a>\r\n        <br/>\r\n      </j:if>\r\n\r\n      <a href=\"performance/\"><img src=\"performance/respondingTimeGraph\"/></a>\r\n      <br/>\r\n      <a href=\"performance/\"><img src=\"performance/errorsGraph\"/></a>\r\n    </div>\r\n  </j:if>\r\n</j:jelly>\r\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/actions/PerformanceProjectAction/floatingBox_es.properties",
    "content": "Performance\\ Trend=Tendencia de rendimiento\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/actions/PerformanceProjectAction/index.jelly",
    "content": "<?jelly escape-by-default='true'?>\r\n<j:jelly xmlns:j=\"jelly:core\" xmlns:st=\"jelly:stapler\" xmlns:l=\"/lib/layout\">\r\n  <l:layout css=\"/plugin/performance/css/style.css\">\r\n    <st:include it=\"${it.job}\" page=\"sidepanel.jelly\" />\r\n    <l:main-panel>\r\n      <h1>${%Performance Trend}</h1>\r\n      <div>\r\n        <a href=\"../lastBuild/performance/\">${%Last Report}</a><br/>\r\n        <a href=\"${from.urlName}configure\">${%Filter trend data}</a>\r\n      </div>\r\n      <div>\r\n        <j:forEach var=\"performanceReport\" items=\"${it.performanceReportList}\">\r\n          <div class=\"title\"><h1><center>${%Test file}: ${performanceReport}</center></h1></div>\r\n          <center>\r\n            <j:if test=\"${it.ifModeThroughputUsed()}\">\r\n              <a href=\"./throughputGraph?width=900&amp;height=550&amp;performanceReportPosition=${performanceReport}\" title=\"${%Click for larger image}\">\r\n                <img class=\"trend\" src=\"./throughputGraph?width=300&amp;height=225&amp;performanceReportPosition=${performanceReport}\" width=\"300\" height=\"225\" />\r\n              </a>\r\n            </j:if>\r\n\r\n            <j:choose>\r\n              <j:when test=\"${it.ifModePerformancePerTestCaseUsed()}\">\r\n                <a href=\"./respondingTimeGraphPerTestCaseMode?width=900&amp;height=550&amp;performanceReportPosition=${performanceReport}\" title=\"${%Click for larger image}\">\r\n                  <img class=\"trend\" src=\"./respondingTimeGraphPerTestCaseMode?width=500&amp;height=225&amp;legendLimit=5&amp;performanceReportPosition=${performanceReport}\" width=\"300\" height=\"225\" />\r\n                </a>\r\n                <a href=\"./errorsGraph?width=900&amp;height=550&amp;performanceReportPosition=${performanceReport}\"  title=\"${%Click for larger image}\">\r\n                  <img class=\"trend\" src=\"./errorsGraph?width=300&amp;height=225&amp;performanceReportPosition=${performanceReport}\" width=\"300\" height=\"225\" />\r\n                </a>\r\n                <center>\r\n                  <a href=\"${from.urlName}testsuiteReport?performanceReportPosition=${performanceReport}\">${%Testcase Trend}</a>\r\n                </center>\r\n              </j:when>\r\n\r\n              <j:otherwise>\r\n                <j:choose>\r\n                  <j:when test=\"${it.ifSummarizerParserUsed(performanceReport)}\">\r\n                    <a href=\"./summarizerGraph?width=1500&amp;height=650&amp;performanceReportPosition=${performanceReport}\"  title=\"${%Click for larger image}\">\r\n                      <img class=\"trend\" src=\"./summarizerGraph?width=600&amp;height=325&amp;performanceReportPosition=${performanceReport}\" width=\"600\" height=\"325\" />\r\n                      <br></br>\r\n                    </a>\r\n                    <a href=\"./summarizerGraph?width=1500&amp;height=650&amp;summarizerReportType=${%error}&amp;performanceReportPosition=${performanceReport}\"  title=\"${%Click for larger image}\">\r\n                      <img class=\"trend\" src=\"./summarizerGraph?width=600&amp;height=325&amp;summarizerReportType=${%error}&amp;performanceReportPosition=${performanceReport}\" width=\"600\" height=\"325\" />\r\n                    </a>\r\n                  </j:when>\r\n                  <j:otherwise>\r\n                    <a href=\"./respondingTimeGraph?width=900&amp;height=550&amp;performanceReportPosition=${performanceReport}\" title=\"${%Click for larger image}\">\r\n                      <img class=\"trend\" src=\"./respondingTimeGraph?width=300&amp;height=225&amp;legendLimit=5&amp;performanceReportPosition=${performanceReport}\" width=\"300\" height=\"225\" />\r\n                    </a>\r\n                    <a href=\"./errorsGraph?width=900&amp;height=550&amp;performanceReportPosition=${performanceReport}\"  title=\"${%Click for larger image}\">\r\n                      <img class=\"trend\" src=\"./errorsGraph?width=300&amp;height=225&amp;performanceReportPosition=${performanceReport}\" width=\"300\" height=\"225\" />\r\n                    </a>\r\n                    <center>\r\n                      <a href=\"${from.urlName}trendReport?performanceReportPosition=${performanceReport}\">${%Trend report}</a>\r\n                    </center>\r\n                  </j:otherwise>\r\n                </j:choose>\r\n              </j:otherwise>\r\n            </j:choose>\r\n          </center>\r\n        </j:forEach>\r\n      </div>\r\n    </l:main-panel>\r\n  </l:layout>\r\n</j:jelly>\r\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/actions/PerformanceProjectAction/index_es.properties",
    "content": "Filter\\ trend\\ data=Filtrar los datos a mostrar en los grficos\nLast\\ Report=Visualizar el ltimo informe de rendimiento\nPerformance\\ Trend=Tendencia de rendimiento\nTest\\ file=Archivo de test\nTrend\\ report=Informe de tendencia\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/actions/PerformanceProjectAction/index_fr.properties",
    "content": "# The MIT License\n#\n# Copyright (c) 2004-2010, Sun Microsystems, Inc.\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n# THE SOFTWARE.\n\nFilter\\ trend\\ data=Filtres des tendances\nLast\\ Report=Dernier rapport\nPerformance\\ Trend=Tendance des performances\nTest\\ file=Fichier de test\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/build/PerformanceTestBuild/config.jelly",
    "content": "<?jelly escape-by-default='true'?>\n<j:jelly xmlns:j=\"jelly:core\" xmlns:f=\"/lib/form\">\n    <f:entry title=\"${%Test params}\" field=\"params\">\n        <f:textbox />\n    </f:entry>\n\n    <f:advanced>\n        <f:entry title=\"${%VEnv path}\" field=\"virtualEnvCommand\" >\n            <f:textbox />\n        </f:entry>\n        <f:entry title=\"${%Change workingDirectory}\" field=\"workingDirectory\" >\n            <f:textbox />\n        </f:entry>\n        <f:entry title=\"${%Bzt version}\" field=\"bztVersion\">\n            <f:textbox />\n        </f:entry>\n        <f:entry>\n            <f:entry>\n                <f:checkbox field=\"alwaysUseVirtualenv\" title=\"${%Use virtualenv}\" />\n            </f:entry>\n            <f:entry>\n                <f:checkbox field=\"generatePerformanceTrend\" checked=\"true\" title=\"${%Auto report}\" />\n            </f:entry>\n            <f:entry>\n                <f:checkbox field=\"useBztExitCode\" checked=\"true\" title=\"${%Use bzt code}\" />\n            </f:entry>\n            <f:entry>\n                <f:checkbox field=\"printDebugOutput\" title=\"${%Debug mode}\" />\n            </f:entry>\n            <f:entry>\n                <f:checkbox field=\"useSystemSitePackages\"  checked=\"true\" title=\"${%Virtualenv option}\" />\n            </f:entry>\n        </f:entry>\n    </f:advanced>\n</j:jelly>\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/build/PerformanceTestBuild/config.properties",
    "content": "Test\\ params=Taurus tool parameters:\nVEnv\\ path=Path to \\''virtualenv\\'' binary (if empty, it should be in $PATH):\nChange\\ workingDirectory=Change working directory:\nAuto\\ report=Automatically generate performance report\nUse\\ bzt\\ code=Mark build unstable/failed based on exit code\nDebug\\ mode=Print debug output from all commands\nVirtualenv\\ option=Use \\''--system-site-packages\\'' option for virtualenv\nBzt\\ version=Change \\''bzt\\'' version:\nUse\\ virtualenv=Always use virtualenv"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/build/PerformanceTestBuild/help.html",
    "content": "<div>\r\n\tExecute <a href=\"http://gettaurus.org/?utm_source=jenkins&utm_medium=link&utm_campaign=build_step_help\">Taurus</a>  with configuration files and options. You can simply specify JMX file to run, or give list of Taurus config files and options to execute.\r\n</div>\r\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/build/jenkins-report.yml",
    "content": "---\nreporting:\n- module: final-stats\n  dump-xml: aggregate-results.xml\n  summary: false\n  percentiles: false\n  failed-labels: false\n  test-duration: false"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/constraints/AbsoluteConstraint/config.jelly",
    "content": "<?jelly escape-by-default='true'?>\n<j:jelly xmlns:j=\"jelly:core\" xmlns:f=\"/lib/form\" xmlns:p=\"/lib/performance\">\n  <f:block>\n    <f:entry>\n      <p:blockWrapper tableStyle=\"width: 500px; cellspacing:0; border:0px;\">\n        <f:block>\n          <f:entry title=\"Related Report\" field=\"relatedPerfReport\">\n            <f:textbox name=\"relatedPerfReport\"/>\n          </f:entry>\n        </f:block>\n        <f:block>\n          <f:optionalBlock name=\"testCaseBlock\" title=\"Specify a test case\" checked=\"${instance.getTestCaseBlock() != null}\">\n            <f:entry field=\"testCase\">\n              <f:textbox name=\"testCase\"/>\n            </f:entry>\n          </f:optionalBlock>\n        </f:block>\n        <f:block>\n          <table>\n            <tr>\n              <td width=\"25%\" align=\"center\">\n                <label> Metric </label>\n              </td>\n              <td width=\"30%\" align=\"center\">\n                <label> Operator </label>\n              </td>\n              <td width=\"15%\" align=\"center\">\n                <label> Value </label>\n              </td>\n              <td width=\"30%\" align=\"center\">\n                <label> Escalation </label>\n              </td>\n            </tr>\n            <tr>\n              <td style=\"vertical-align: middle\">\n                <table>\n                  <tr>\n                    <f:entry field=\"meteredValue\" name=\"meteredValue\">\n                      <f:enum>${it}</f:enum>\n                    </f:entry>\n                  </tr>\n                </table>\n              </td>\n              <td style=\"vertical-align: middle\">\n                <table>\n                  <tr>\n                    <f:entry field=\"operator\" name=\"operator\">\n                      <f:enum>${it}</f:enum>\n                    </f:entry>\n                  </tr>\n                </table>\n              </td>\n              <td style=\"vertical-align: middle\">\n                <table>\n                  <tr>\n                    <f:entry field=\"value\" name=\"value\">\n                      <f:number field=\"value\" name=\"value\" default=\"0\" min=\"0\"/>\n                    </f:entry>\n                  </tr>\n                </table>\n              </td>\n              <td style=\"vertical-align: middle\">\n                <table>\n                  <tr>\n                    <f:entry field=\"escalationLevel\" name=\"escalationLevel\">\n                      <f:enum>${it}</f:enum>\n                    </f:entry>\n                  </tr>\n                </table>\n              </td>\n            </tr>\n          </table>\n        </f:block>\n      </p:blockWrapper>\n    </f:entry>\n  </f:block>\n</j:jelly>\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/constraints/AbsoluteConstraint/config.properties",
    "content": ""
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/constraints/AbstractConstraint/help-relatedPerfReport.html",
    "content": "<div>\n<p>\n  Specify a report this constraint is refered to. You defined the reports above. \n  Please use only the filename of the report not the URL.\n  <a href=https://issues.jenkins-ci.org/browse/JENKINS-25729>JENKINS-25729</a>\n</p>\n<p>\n  If your report is defined as path/to/report/result.xml, use only result.xml\n</p>\n</div>\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/constraints/AbstractConstraint/help-testCase.html",
    "content": "<div>\n<p>\n  Specify test case/s this constraint is refered to. Possible entries:\n</p>\n<ul>\n    <li>Comma seperated list of test cases\n    <li>'*' - constraint is applied to all test cases found in the report.\n    <li>If the checkbox is unchecked the constraint is applied to the average of all test cases\n</ul>\n</div>"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/constraints/RelativeConstraint/config.jelly",
    "content": "<?jelly escape-by-default='true'?>\n<j:jelly xmlns:j=\"jelly:core\" xmlns:f=\"/lib/form\" xmlns:p=\"/lib/performance\">\n  <f:block>\n    <f:entry>\n      <p:blockWrapper tableStyle=\"width: 500px; cellspacing:0; border:0px;\">\n        <f:block>\n          <f:entry title=\"Related Report\" field=\"relatedPerfReport\">\n            <f:textbox name=\"relatedPerfReport\"/>\n          </f:entry>\n        </f:block>\n        <f:block>\n          <f:optionalBlock name=\"testCaseBlock\" title=\"Specify a test case\" checked=\"${instance.getTestCaseBlock() != null}\">\n            <f:entry field=\"testCase\">\n              <f:textbox name=\"testCase\"/>\n            </f:entry>\n          </f:optionalBlock>\n        </f:block>\n        <f:block>\n          <table>\n            <tr>\n              <td width=\"25%\" align=\"center\">\n                <label> Metric </label>\n              </td>\n              <td width=\"30%\" align=\"center\">\n                <label> Operator </label>\n              </td>\n              <td width=\"15%\" align=\"center\">\n                <label> Tolerance-%</label>\n              </td>\n              <td width=\"30%\" align=\"center\">\n                <label> Escalation ${radioId}</label>\n              </td>\n            </tr>\n            <tr>\n              <td style=\"vertical-align: middle\">\n                <table>\n                  <tr>\n                    <f:entry field=\"meteredValue\" name=\"meteredValue\">\n                      <f:enum>${it}</f:enum>\n                    </f:entry>\n                  </tr>\n                </table>\n              </td>\n              <td style=\"vertical-align: middle\">\n                <table>\n                  <tr>\n                    <f:entry field=\"operator\" name=\"operator\">\n                      <f:enum>\n                        <j:if test=\"${!it.text.equals('not be equal to')}\">${it}</j:if>\n                      </f:enum>\n                    </f:entry>\n                  </tr>\n                </table>\n              </td>\n              <td style=\"vertical-align: middle\">\n                <table>\n                  <tr>\n                    <f:entry field=\"tolerance\" name=\"tolerance\">\n                      <f:number field=\"tolerance\" name=\"tolerance\" default=\"0\" min=\"0\"/>\n                    </f:entry>\n                  </tr>\n                </table>\n              </td>\n              <td style=\"vertical-align: middle\">\n                <table>\n                  <tr>\n                    <f:entry field=\"escalationLevel\" name=\"escalationLevel\">\n                      <f:enum>${it}</f:enum>\n                    </f:entry>\n                  </tr>\n                </table>\n              </td>\n            </tr>\n          </table>\n        </f:block>\n        <j:set var=\"radioId\" value=\"${h.generateId()}\"/>\n        <f:block>\n          <f:radioBlock name=\"${radioId}.previousResultsBlock\" field=\"previousResultsBlock\" value=\"true\"\n              title=\"Compare with number of previous builds\" checked=\"${instance.getPreviousResultsBlock().isChoicePreviousResults()}\">\n            <f:entry title=\"Number of previous builds\" field=\"previousResultsString\">\n              <f:number min=\"1\" />\n            </f:entry>\n          </f:radioBlock>\n        </f:block>\n        <f:block>\n          <f:radioBlock name=\"${radioId}.previousResultsBlock\" field=\"previousResultsBlock\" value=\"false\"\n              title=\"Compare with Builds within a timeframe\" checked=\"${instance.getPreviousResultsBlock().isChoiceTimeframe()}\">\n            <f:entry>\n              <f:entry title=\"Min date/time\" field=\"timeframeStartString\">\n                <f:textbox maxlength=\"16\"/>\n              </f:entry>\n              <f:entry title=\"Max date/time\" field=\"timeframeEndString\">\n                <f:textbox maxlength=\"16\"/>\n              </f:entry>\n            </f:entry>\n          </f:radioBlock>\n        </f:block>\n        <f:block>\n          <f:radioBlock name=\"${radioId}.previousResultsBlock\" field=\"previousResultsBlock\" value=\"BASELINE\"\n              title=\"Compare with baseline build\" checked=\"${instance.getPreviousResultsBlock().isChoiceBaselineBuild()}\">\n          </f:radioBlock>\n        </f:block>\n      </p:blockWrapper>\n    </f:entry>\n  </f:block>\n</j:jelly>\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/constraints/RelativeConstraint/config.properties",
    "content": ""
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/constraints/RelativeConstraint/help-previousResultsString.html",
    "content": "<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",
    "content": "<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>yyyy-MM-dd (will set time to 00:00)\n    <li>enter 'now' for current date time (at the begin of a build)\n</ul>\n</p>\n</div>"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/constraints/RelativeConstraint/help-timeframeStartString.html",
    "content": "<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    <li>yyyy-MM-dd (will set time to 00:00)\n</ul>\n</p>\n</div>"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/details/GraphConfigurationDetail/CVS/Entries",
    "content": "/index.jelly/1.1/Fri Nov 13 11:18:05 2009//\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/details/GraphConfigurationDetail/CVS/Repository",
    "content": "iceteaperf/hudson/plugins/jmeter/src/main/resources/hudson/plugins/jmeter/GraphConfigurationDetail\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/details/GraphConfigurationDetail/CVS/Root",
    "content": ":extssh:aespy@cvs.venezia.dev.impots:/cvsroot/ice\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/details/GraphConfigurationDetail/index.jelly",
    "content": "<?jelly escape-by-default='true'?>\n<j:jelly xmlns:j=\"jelly:core\" xmlns:st=\"jelly:stapler\" xmlns:l=\"/lib/layout\" xmlns:f=\"/lib/form\">\n  <l:layout norefresh=\"true\">\n    <l:main-panel>\n      <f:form method=\"post\" action=\"save\" name=\"Save\">\n        <h1>${%Configure}</h1>\n        <p>${it.description}</p>\n        <j:set var=\"instance\" value=\"${it}\" />\n        <f:entry>\n          <f:block>\n            <p>${%Configure.description}</p>\t\t\t\n          </f:block>\n          <p>\n            <f:block>\n              <f:radio name=\"radioConfigType\" value=\"NONE\" checked=\"${it.configType == 'NONE'}\" id=\"radioConfigType.none\"/>\n              <st:nbsp/>\n              <label for=\"radioConfigType.none\">${%AllBuilds}</label>\n              <st:nbsp/>\n            </f:block>\n          </p>\n          <p>\n            <f:block>\n              <f:radio name=\"radioConfigType\" value=\"DATE\" checked=\"${it.configType == 'DATE'}\" id=\"radioConfigType.date\"/>\n              <st:nbsp/>\n              <label for=\"radioConfigType.build\">${%Range.description}</label>\n            </f:block>\n          </p>\n          <p>\n            <f:entry title=\"${%first day}\" description=\"${%DateFormat}: DD/MM/YYYY\">\n              <f:textbox name=\"firstDayCountString\" value=\"${it.firstDayCount}\"/>\n            </f:entry>\n            <f:entry title=\"${%last day}\" description=\"${%DateFormat}: DD/MM/YYYY\">\n              <f:textbox name=\"lastDayCountString\" value=\"${it.lastDayCount}\"/>\n            </f:entry>\n          </p>\n          <f:block>\n            <f:radio name=\"radioConfigType\" value=\"BUILD\" checked=\"${it.configType == 'BUILD'}\" id=\"radioConfigType.build\"/>\n            <st:nbsp/>\n            <label for=\"radioConfigType.date\">${%LastBuilds}</label>\n            <st:nbsp/>\n          </f:block>\n          <f:entry title=\"${%builds}\" description=\"${%NumberOfBuilds}\">\n            <f:textbox name=\"buildCountString\" value=\"${it.buildCount}\"/>\n          </f:entry>\n          <f:block>\n            <f:radio name=\"radioConfigType\" value=\"BUILDNTH\" checked=\"${it.configType == 'BUILDNTH'}\" id=\"radioConfigType.buildnth\"/>\n            <st:nbsp/>\n            <label for=\"radioConfigType.buildnth\">${%BuildStep.description}</label>\n            <st:nbsp/>\n          </f:block>\n          <f:entry title=\"${%BuildStep}\" description=\"${%BuildStep.info}\">\n            <f:textbox name=\"buildStepString\" value=\"${it.buildStep}\"/>\n          </f:entry>\n          <f:entry title=\"\">\n            <input type=\"submit\" name=\"Submit'\" value=\"${%Save}\" class=\"submit-button\" /> \n          </f:entry>\n        </f:entry>\n      </f:form>\n    </l:main-panel>\n  </l:layout>\n</j:jelly>\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/details/GraphConfigurationDetail/index.properties",
    "content": "Configure=Configure the trend graph\nConfigure.description=\\\n  Configure the trend graph of this plug-in for the current job and user. <br/>\\\n  These values are persisted in a cookie, so please make sure that cookies are enabled in your browser.\n  \nAllBuilds=Show all the builds\nRange.description=Show only the builds in the following range of dates\nfirst\\ day=First day\nlast\\ day=Last day\nDateFormat=Format of the date\nLastBuilds=Show only the n last builds</label>\nbuilds=Builds\nNumberOfBuilds=number of builds to show\nSave=Save\nBuildStep.description=Show builds only from nth to nth\nBuildStep=Build step\nBuildStep.info = select the build step (the builds from nth to nth will only be displayed) \n \n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/details/GraphConfigurationDetail/index_es.properties",
    "content": "Configure=Configurar el grfico\nConfigure.description=\\\n  Configurar el grfico de tendencia de rendimiento para la tarea y el usuario actuales. <br/> \\\n  Estos valores se almacenan en una cookie en el navegador. <br/>\\\n  Asegurat que tu navegador tiene habilitado el uso de cookies.\nAllBuilds=Mostrar todas las ejecuciones\nRange.description=Mostrar slo las ejecuciones en el siguiente rango de fechas\nfirst\\ day=Primer da\nlast\\ day=ltimo da\nDateFormat=Formato de fecha\nLastBuilds=Mostrar slo las ltimas ''n'' ejecuciones\nbuilds=Ejecuciones\nNumberOfBuilds=Nmero de ejecuciones a mostrar\nSave=Guardar\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/details/TestSuiteReportDetail/index.jelly",
    "content": "<?jelly escape-by-default='true'?>\n<j:jelly xmlns:j=\"jelly:core\" xmlns:l=\"/lib/layout\">\n  <l:layout css=\"/plugin/performance/css/style.css\">\n    <l:main-panel>\n      <h1>${%Performance Trend Per Test Case}</h1>\n      <div>\n        <j:forEach var=\"performanceReportTestCase\" items=\"${it.performanceReportTestCaseList}\">\n          <div class=\"title\"><h1><center>${%Test case}: ${performanceReportTestCase}</center></h1></div>\n          <center>\n           <j:choose>\n                <a href=\"./respondingTimeGraphPerTestCaseMode?width=900&amp;height=550&amp;performanceReportPosition=${it.filename}&amp;performanceReportTest=${performanceReportTestCase}\" title=\"${%Click for larger image}\">\n                <img class=\"trend\" src=\"./respondingTimeGraphPerTestCaseMode?width=300&amp;height=225&amp;performanceReportPosition=${it.filename}&amp;performanceReportTest=${performanceReportTestCase}\" width=\"300\" height=\"225\" />\n                </a>\n           </j:choose>\n          </center>\n        </j:forEach>\n      </div>\n    </l:main-panel>\n  </l:layout>\n</j:jelly>\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/details/TrendReportDetail/index.jelly",
    "content": "<?jelly escape-by-default='true'?>\r\n<j:jelly xmlns:j=\"jelly:core\" xmlns:l=\"/lib/layout\">\r\n  <l:layout css=\"/plugin/performance/css/style.css\">\r\n    <l:main-panel>\r\n      <h1>${%Trend report}: ${it.filename}</h1>\r\n      <table class=\"sortable source\" border=\"1\">\r\n      <thead>\r\n         <tr>\r\n         <th>Build</th>\r\n         <j:forEach var=\"label\" items=\"${it.columnLabels}\">\r\n         <th>${label}</th>\r\n         </j:forEach>\r\n         </tr>\r\n      </thead>\r\n      <tbody>\r\n         <j:forEach var=\"row\" items=\"${it.iterator}\">\r\n         <tr>\r\n            <td>${row.label}</td>\r\n            <j:forEach var=\"value\" items=\"${row.values}\">\r\n            <td>${value}</td>\r\n            </j:forEach>\r\n         </tr>\r\n        </j:forEach>\r\n      </tbody>\r\n      </table>\r\n    </l:main-panel>\r\n  </l:layout>\r\n</j:jelly>\r\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/details/TrendReportDetail/index_es.properties",
    "content": "# The MIT License\n#\n# Copyright (c) 2004-2010, Sun Microsystems, Inc.\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n# THE SOFTWARE.\n\nTrend\\ report=Informe de tendencia\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/reports/UriReport/index.jelly",
    "content": "<?jelly escape-by-default='true'?>\r\n<j:jelly xmlns:j=\"jelly:core\" xmlns:st=\"jelly:stapler\" xmlns:l=\"/lib/layout\">\r\n  <l:layout xmlns:jm=\"/hudson/plugins/performance/tags\" css=\"/plugin/performance/css/style.css\">\r\n    <st:include it=\"${it.build}\" page=\"sidepanel.jelly\" />\r\n    <l:main-panel>\r\n      <h1>${it.performanceReport.getReportFileName()}</h1>\r\n        <j:if test=\"${it.hasSamples()}\">\r\n            <a href=\"./summarizerTrendGraph?width=1500&amp;height=650&amp;performanceReportPosition=${performanceReport}\"  title=\"${%Click for larger image}\">\r\n                <img class=\"trend\" src=\"./summarizerTrendGraph?width=600&amp;height=325&amp;performanceReportPosition=${performanceReport}\" width=\"600\" height=\"325\" />\r\n            </a>\r\n            <a href=\"./percentileGraph?width=1500&amp;height=650&amp;performanceReportPosition=${it.filename}&amp;summarizerTrendUri=${URI}\" title=\"${%Click for larger image}\">\r\n                <img class=\"trend\" src=\"./percentileGraph?width=600&amp;height=325&amp;performanceReportPosition=${it.filename}&amp;summarizerTrendUri=${URI}\" width=\"600\" height=\"325\" />\r\n            </a>\r\n            <a href=\"./throughputGraph?width=1500&amp;height=650&amp;performanceReportPosition=${it.filename}&amp;summarizerTrendUri=${URI}\" title=\"${%Click for larger image}\">\r\n                <img class=\"trend\" src=\"./throughputGraph?width=600&amp;height=325&amp;performanceReportPosition=${it.filename}&amp;summarizerTrendUri=${URI}\" width=\"600\" height=\"325\" />\r\n            </a>\r\n            <a href=\"./errorGraph?width=1500&amp;height=650&amp;performanceReportPosition=${performanceReport}\" title=\"${%Click for larger image}\">\r\n                <img class=\"trend\" src=\"./errorGraph?width=600&amp;height=325&amp;performanceReportPosition=${performanceReport}\" width=\"600\" height=\"325\" />\r\n            </a>\r\n        </j:if>\r\n        <br></br>\r\n      <strong class=\"uri\">URI: ${it.uri}</strong>\r\n      <table border=\"1\" class=\"source\">\r\n        <jm:captionLine it=\"${it.performanceReport}\"/>\r\n        <tr>\r\n          <td class=\"left\">${it.uri}</td>\r\n            <j:choose>\r\n              <j:when test=\"${it.getPerformanceReport().ifSummarizerParserUsed(it.getPerformanceReport().getReportFileName())}\">\r\n                <jm:summaryTableSummarizer it=\"${it}\" />\r\n              </j:when>\r\n              <j:otherwise>\r\n                <jm:summaryTable it=\"${it}\" />\r\n              </j:otherwise>\r\n            </j:choose>\r\n        </tr>\r\n      </table>\r\n      <j:if test=\"${it.hasSamples()}\">\r\n      <h3>${%Performance samples}</h3>\r\n      <table class=\"sortable source\" border=\"1\">\r\n        <j:choose>\r\n          <j:when test=\"${it.getPerformanceReport().ifSummarizerParserUsed(it.getPerformanceReport().getReportFileName())}\">\r\n            <th>${%Samples}</th>\r\n            <th>${%Time}</th>\r\n            <th>${% Avg Response Time} (ms)</th>\r\n            <j:forEach var=\"c\" items=\"${it.httpSampleList}\">\r\n                <tr>\r\n                <td>${c.summarizerSamples}</td>\r\n                <td class=\"center\" data=\"${c.date.getTime()}\">${c.date}</td>\r\n                <td>${c.duration} ms.</td>\r\n                </tr>\r\n            </j:forEach>\r\n          </j:when>\r\n          <j:otherwise>\r\n            <th>${%Http Code}</th>\r\n            <th>${%Time}</th>\r\n            <th>${%Duration} (ms)</th>\r\n            <j:forEach var=\"c\" items=\"${it.httpSampleList}\">\r\n                <tr class=\"${h.ifThenElse(c.failed,'red','')}\">\r\n                <td>${c.httpCode}</td>\r\n                <td class=\"center\" data=\"${c.date.getTime()}\">${c.date}</td>\r\n                <td>${c.duration} ms.</td>\r\n                </tr>\r\n            </j:forEach>\r\n          </j:otherwise>\r\n        </j:choose>\r\n      </table>\r\n      </j:if>\r\n    </l:main-panel>\r\n  </l:layout>\r\n</j:jelly>"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/reports/UriReport/index_es.properties",
    "content": "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",
    "content": "# The MIT License\n#\n# Copyright (c) 2004-2010, Sun Microsystems, Inc.\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n# THE SOFTWARE.\n\nDuration=Dur\\u00E9e\nPerformance\\ Summary=R\\u00E9sum\\u00E9 des performances\nPerformance\\ samples=\\u00C9chantillons des performances\nTime=Date\nURI=URI\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/tags/captionLine.jelly",
    "content": "<?jelly escape-by-default='true'?>\r\n<j:jelly xmlns:j=\"jelly:core\">\r\n <j:choose>\r\n <j:when test=\"${it.ifSummarizerParserUsed(it.getReportFileName())}\">\r\n  <tr>\r\n    <th>${%URI}</th>\r\n    <th>${%Samples}</th>\r\n    <th>${%Average} (ms)</th>\r\n    <th>${%Minimum} (ms)</th>\r\n    <th>${%Maximum} (ms)</th>\r\n    <th>${%Errors} (%)</th>\r\n </tr>\r\n </j:when>\r\n <j:otherwise>\r\n  <tr>\r\n    <th>${%URI}</th>\r\n    <th>${%Samples}</th>\r\n    <th>${%Average} (ms)</th>\r\n\r\n    <j:set var=\"percentiles\" value=\"${it.getPercentilesValues()}\"/>\r\n    <j:forEach var=\"entry\" items=\"${percentiles}\">\r\n        <th>\r\n            ${it.getPercentileLabel(entry.getKey())}\r\n        </th>\r\n    </j:forEach>\r\n\r\n    <th>${%Http Code}</th>\r\n    <th>${%Errors} (%)</th>\r\n    <th>${%Average} (KB)</th>\r\n    <th>${%Total} (KB)</th>\r\n  </tr>\r\n </j:otherwise>\r\n </j:choose>\r\n</j:jelly>"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/tags/captionLine_es.properties",
    "content": "Max=M\\u00e1x\nsamples=Peticiones\nsamples\\ diff=Diferencia peticiones\nMedian=Mediana\nMedian\\ diff=Variaci\\u00f3n de la mediana\nLine90=L\\u00ednea 90%\nLine95=L\\u00ednea 95%\nAverage=Media\nAverage\\ diff=Variaci\\u00f3n de la media\nURI=URI\nErrors=Errores\nErrors\\ diff=Variaci\\u00f3n de errores\nMin=M\\u00edn\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/tags/captionLine_fr.properties",
    "content": "# The MIT License\n#\n# Copyright (c) 2004-2010, Sun Microsystems, Inc.\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n# THE SOFTWARE.\n\nAverage=Moyenne\nErrors=Erreurs\nMax=Max\nMin=Min\nURI=URI\nsamples=\\u00C9chantillons\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/tags/summaryTable.jelly",
    "content": "<?jelly escape-by-default='true'?>\r\n<j:jelly xmlns:j=\"jelly:core\">\r\n    <td>\r\n        ${it.samplesCount()}\r\n        <sup class=\"${h.ifThenElse(it.getSamplesCountDiff()>=0,'green','red')}\">\r\n            ${h.ifThenElse(it.getSamplesCountDiff()>=0,'+','')}${it.getSamplesCountDiff()}\r\n        </sup>\r\n    </td>\r\n\r\n    <td>\r\n        ${it.getAverage()}\r\n        <sup class=\"${h.ifThenElse(it.getAverageDiff()>0,'red','green')}\">\r\n            ${h.ifThenElse(it.getAverageDiff()>0,'+','')}${it.getAverageDiff()}\r\n        </sup>\r\n    </td>\r\n\r\n\r\n    <j:set var=\"percentiles\" value=\"${it.getPercentilesValues()}\"/>\r\n    <j:set var=\"percentilesDiff\" value=\"${it.getPercentilesDiffValues()}\"/>\r\n    <j:forEach var=\"entry\" items=\"${percentiles}\">\r\n        <td>\r\n            ${entry.getValue()}\r\n            <j:set var=\"diff\" value=\"${percentilesDiff.get(entry.getKey())}\"/>\r\n            <sup class=\"${h.ifThenElse(diff > 0,'red','green')}\">\r\n                ${h.ifThenElse(diff > 0,'+','')}${diff}\r\n            </sup>\r\n        </td>\r\n    </j:forEach>\r\n\r\n    <td>\r\n        ${it.getHttpCode()}\r\n        <sup>\r\n            ${it.getLastBuildHttpCodeIfChanged()}\r\n        </sup>\r\n    </td>\r\n\r\n    <td>\r\n        ${it.errorPercent()} %\r\n        <sup class=\"${h.ifThenElse(it.getErrorPercentDiff()>0,'red','green')}\">\r\n            ${h.ifThenElse(it.getErrorPercentDiff()>0,'+','')}${it.getErrorPercentDiff()} %\r\n        </sup>\r\n    </td>\r\n\r\n    <td>\r\n    \t${it.getAverageSizeInKb()}\r\n    \t<sup class=\"${h.ifThenElse(it.getAverageSizeInKbDiff()>0,'red','green')}\">\r\n            ${h.ifThenElse(it.getAverageSizeInKbDiff()>0,'+','')}${it.getAverageSizeInKbDiff()}\r\n        </sup>\r\n    </td>\r\n    <td>\r\n    \t${it.getTotalTrafficInKb()}\r\n    \t<sup class=\"${h.ifThenElse(it.getTotalTrafficInKbDiff()>0,'red','green')}\">\r\n            ${h.ifThenElse(it.getTotalTrafficInKbDiff()>0,'+','')}${it.getTotalTrafficInKbDiff()}\r\n        </sup>\r\n    </td>\r\n</j:jelly>"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/tags/summaryTableSummarizer.jelly",
    "content": "<?jelly escape-by-default='true'?>\n<j:jelly xmlns:j=\"jelly:core\">\n\n        <td>${it.getSummarizerSize()}</td>\n        <td>${it.getAverage()}</td>\n        <td>${it.getSummarizerMin()}</td>\n        <td>${it.getSummarizerMax()}</td>\n        <td>${it.getSummarizerErrors()}  %</td>\n\n</j:jelly>"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/tags/taglib",
    "content": ""
  },
  {
    "path": "src/main/resources/index.jelly",
    "content": "<?jelly escape-by-default='true'?>\n<!--\n  This view is used to render the plugin list page.\n\n  Since we don't really have anything dynamic here, let's just use static HTML. \n-->\n<div>\nThis plugin allows tracking performance KPIs, based on results read from popular testing tools (\n<a href=\"https://jmeter.apache.org/\">Apache JMeter</a>,\n<a href=\"https://junit.org/junit5/\">JUnit</a>,\n<a href=\"http://gettaurus.org/\">Taurus</a>). \n</div>"
  },
  {
    "path": "src/main/resources/lib/performance/blockWrapper.jelly",
    "content": "<?jelly escape-by-default='true'?>\n<j:jelly xmlns:j=\"jelly:core\" xmlns:st=\"jelly:stapler\" xmlns:d=\"jelly:define\" xmlns:l=\"/lib/layout\" xmlns:t=\"/lib/hudson\" xmlns:f=\"/lib/form\">\n  <st:documentation>\n    This adds a wrapper allowing adding an ID to a field or group of fields that can be targeted by JavaScript\n    The wrapper will be a `table` tag on Jenkins Core less than 2.264, and a `div` tag after that.\n\n    <st:attribute name=\"id\">\n      ID to add to the wrapper\n    </st:attribute>\n    <st:attribute name=\"style\">\n      Inline style to pass to the wrapper tag\n    </st:attribute>\n    <st:attribute name=\"tableStyle\">\n      Inline style to pass to the wrapper tag (table only)\n    </st:attribute>\n    <st:attribute name=\"divStyle\">\n      Inline style to pass to the wrapper tag (div only)\n    </st:attribute>\n\n  </st:documentation>\n\n  <j:choose>\n    <j:when test=\"${divBasedFormLayout}\">\n      <div id=\"${attrs.id}\" style=\"${attrs.style};${attrs.divStyle}\">\n        <d:invokeBody/>\n      </div>\n    </j:when>\n    <j:otherwise>\n      <table id=\"${attrs.id}\" style=\"${attrs.style};${attrs.tableStyle}\">\n        <d:invokeBody/>\n      </table>\n    </j:otherwise>\n  </j:choose>\n\n</j:jelly>\n"
  },
  {
    "path": "src/main/resources/lib/performance/taglib",
    "content": ""
  },
  {
    "path": "src/main/tools/checkstyle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    This configuration file was written by the eclipse-cs plugin configuration editor\n-->\n<!--\n    Checkstyle-Configuration: GWT Checks\n    Description: none\n-->\n<!DOCTYPE module PUBLIC \"-//Puppy Crawl//DTD Check Configuration 1.2//EN\"\n        \"http://www.puppycrawl.com/dtds/configuration_1_2.dtd\">\n<module name=\"Checker\">\n    <property name=\"severity\" value=\"warning\"/>\n    <module name=\"TreeWalker\">\n        <module name=\"FileContentsHolder\"/>\n        <module name=\"InterfaceIsType\">\n            <property name=\"severity\" value=\"ignore\"/>\n        </module>\n        <module name=\"RedundantImport\">\n            <property name=\"severity\" value=\"error\"/>\n        </module>\n        <module name=\"UnusedImports\">\n            <property name=\"severity\" value=\"error\"/>\n        </module>\n        <module name=\"JavadocType\">\n            <property name=\"severity\" value=\"error\"/>\n            <property name=\"scope\" value=\"protected\"/>\n        </module>\n        <module name=\"PackageName\">\n            <property name=\"severity\" value=\"error\"/>\n            <property name=\"format\" value=\"^[a-z]+(\\.[a-z][a-z0-9]{1,})*$\"/>\n        </module>\n        <module name=\"ParameterName\">\n            <property name=\"severity\" value=\"error\"/>\n        </module>\n        <module name=\"LocalFinalVariableName\">\n            <property name=\"severity\" value=\"error\"/>\n        </module>\n        <module name=\"LocalVariableName\">\n            <property name=\"severity\" value=\"error\"/>\n            <property name=\"tokens\" value=\"PARAMETER_DEF,VARIABLE_DEF\"/>\n        </module>\n        <module name=\"LeftCurly\"/>\n        <module name=\"RightCurly\"/>\n        <module name=\"CovariantEquals\">\n            <property name=\"severity\" value=\"error\"/>\n        </module>\n        <module name=\"HiddenField\">\n            <property name=\"severity\" value=\"error\"/>\n            <property name=\"tokens\" value=\"VARIABLE_DEF\"/>\n            <property name=\"ignoreConstructorParameter\" value=\"true\"/>\n            <property name=\"ignoreSetter\" value=\"true\"/>\n        </module>\n        <module name=\"IllegalInstantiation\">\n            <property name=\"severity\" value=\"error\"/>\n            <property name=\"classes\" value=\"java.lang.Boolean\"/>\n        </module>\n        <module name=\"UpperEll\">\n            <metadata name=\"com.atlassw.tools.eclipse.checkstyle.comment\" value=\"checking for 4l rather than 4L\"/>\n            <property name=\"severity\" value=\"error\"/>\n        </module>\n        <module name=\"JavadocStyle\">\n            <metadata name=\"com.atlassw.tools.eclipse.checkstyle.comment\" value=\"Well formed java docs\"/>\n            <property name=\"severity\" value=\"info\"/>\n            <property name=\"checkHtml\" value=\"false\"/>\n            <property name=\"tokens\" value=\"CLASS_DEF,CTOR_DEF,INTERFACE_DEF,METHOD_DEF,VARIABLE_DEF\"/>\n        </module>\n        <module name=\"NeedBraces\">\n            <metadata name=\"com.atlassw.tools.eclipse.checkstyle.comment\" value=\"make sure if has braces\"/>\n        </module>\n        <module name=\"JavadocMethod\">\n            <metadata name=\"com.atlassw.tools.eclipse.checkstyle.lastEnabledSeverity\" value=\"info\"/>\n            <property name=\"severity\" value=\"info\"/>\n            <property name=\"scope\" value=\"protected\"/>\n            <property name=\"allowUndeclaredRTE\" value=\"true\"/>\n            <property name=\"allowMissingParamTags\" value=\"true\"/>\n            <property name=\"allowMissingThrowsTags\" value=\"true\"/>\n            <property name=\"allowMissingReturnTag\" value=\"true\"/>\n            <property name=\"allowMissingJavadoc\" value=\"true\"/>\n            <property name=\"allowMissingPropertyJavadoc\" value=\"true\"/>\n            <property name=\"logLoadErrors\" value=\"true\"/>\n            <property name=\"tokens\" value=\"METHOD_DEF\"/>\n        </module>\n        <module name=\"RegexpHeader\">\n            <property name=\"severity\" value=\"error\"/>\n            <property name=\"header\" value=\"/\\*\\n \\* Copyright 20(0[6789]|1[0])\"/>\n        </module>\n        <module name=\"ImportOrder\">\n            <metadata name=\"com.atlassw.tools.eclipse.checkstyle.lastEnabledSeverity\" value=\"error\"/>\n            <property name=\"severity\" value=\"ignore\"/>\n            <property name=\"groups\" value=\"com.google, com,  junit, net,org, java,javax\"/>\n            <property name=\"ordered\" value=\"false\"/>\n            <property name=\"separated\" value=\"true\"/>\n        </module>\n        <module name=\"TabCharacter\">\n            <metadata name=\"com.atlassw.tools.eclipse.checkstyle.comment\" value=\"no tabs\"/>\n            <property name=\"severity\" value=\"error\"/>\n        </module>\n        <module name=\"DefaultComesLast\">\n            <property name=\"severity\" value=\"error\"/>\n        </module>\n        <module name=\"MultipleStringLiterals\">\n            <property name=\"severity\" value=\"info\"/>\n            <property name=\"ignoreStringsRegexp\" value=\".{0,3}\"/>\n        </module>\n        <module name=\"FallThrough\">\n            <property name=\"severity\" value=\"error\"/>\n        </module>\n        <module name=\"IllegalInstantiation\">\n            <property name=\"severity\" value=\"error\"/>\n            <property name=\"classes\" value=\"Boolean\"/>\n        </module>\n        <module name=\"Regexp\">\n            <metadata name=\"com.atlassw.tools.eclipse.checkstyle.comment\"\n                      value=\"check that a space is left after a colon with an assembled error message\"/>\n            <property name=\"severity\" value=\"info\"/>\n            <property name=\"format\" value=\"[^:^&quot;]:&quot; .*+\"/>\n            <property name=\"message\" value=\"check that a space is left after a colon on an assembled error message\"/>\n            <property name=\"illegalPattern\" value=\"true\"/>\n        </module>\n        <module name=\"Regexp\">\n            <metadata name=\"com.atlassw.tools.eclipse.checkstyle.comment\" value=\"more than one blank line\"/>\n            <property name=\"severity\" value=\"info\"/>\n            <property name=\"format\" value=\"[\\r]?[\\n][ \\t]*[\\r]?[\\n][ \\t]*[\\r]?[\\n][ \\t]*\"/>\n            <property name=\"message\" value=\"more than one blank line\"/>\n            <property name=\"illegalPattern\" value=\"true\"/>\n        </module>\n        <module name=\"WhitespaceAround\">\n            <metadata name=\"com.atlassw.tools.eclipse.checkstyle.comment\" value=\"Must have spaces\"/>\n            <property name=\"severity\" value=\"error\"/>\n            <property name=\"tokens\"\n                      value=\"COLON,NOT_EQUAL,QUESTION,DIV,DIV_ASSIGN,BXOR,BXOR_ASSIGN,MINUS,LCURLY,STAR,STAR_ASSIGN,TYPE_EXTENSION_AND,BAND,LAND,BAND_ASSIGN,MOD,MOD_ASSIGN,PLUS,PLUS_ASSIGN,LT,SL,SL_ASSIGN,LE,ASSIGN,MINUS_ASSIGN,EQUAL,GT,GE,SR,SR_ASSIGN,BSR,BSR_ASSIGN,BOR,BOR_ASSIGN,LOR,LITERAL_ASSERT,LITERAL_ASSERT,LITERAL_CATCH,LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_FOR,LITERAL_IF,LITERAL_RETURN,SLIST,LITERAL_SYNCHRONIZED,LITERAL_TRY,LITERAL_WHILE\"/>\n        </module>\n        <module name=\"Regexp\">\n            <metadata name=\"com.atlassw.tools.eclipse.checkstyle.comment\" value=\"newline before }\"/>\n            <property name=\"severity\" value=\"error\"/>\n            <property name=\"format\" value=\"[\\r]?[\\n][ \\t]*[\\r]?[\\n][ \\t]+[}][ ]*[\\n]\"/>\n            <property name=\"message\" value=\"newline before }\"/>\n            <property name=\"illegalPattern\" value=\"true\"/>\n        </module>\n        <module name=\"ModifierOrder\">\n            <property name=\"severity\" value=\"error\"/>\n        </module>\n        <module name=\"AvoidStarImport\">\n            <property name=\"severity\" value=\"error\"/>\n        </module>\n        <module name=\"com.google.gwt.checkstyle.OrderCheck\">\n            <property name=\"severity\" value=\"error\"/>\n        </module>\n        <module name=\"com.google.gwt.checkstyle.FieldCheck\">\n            <property name=\"severity\" value=\"error\"/>\n        </module>\n        <module name=\"GenericIllegalRegexp\">\n            <metadata name=\"com.atlassw.tools.eclipse.checkstyle.comment\" value=\"bad // comment\"/>\n            <property name=\"severity\" value=\"error\"/>\n            <property name=\"format\" value=\"  [/][/][A-z]\"/>\n            <property name=\"message\" value=\"// comments must be followed by a space and be on their own line\"/>\n        </module>\n        <module name=\"DoubleCheckedLocking\">\n            <property name=\"severity\" value=\"error\"/>\n        </module>\n        <module name=\"EmptyStatement\">\n            <property name=\"severity\" value=\"error\"/>\n        </module>\n        <module name=\"MethodName\">\n            <property name=\"severity\" value=\"error\"/>\n        </module>\n        <module name=\"MemberName\">\n            <property name=\"severity\" value=\"error\"/>\n            <property name=\"format\" value=\"[a-z]|[a-z][a-z_0-9][A-Za-z0-9_]*|[a-z](?&lt;!f)[A-Z0-9]*\"/>\n        </module>\n        <module name=\"TodoComment\">\n            <metadata name=\"com.atlassw.tools.eclipse.checkstyle.comment\" value=\"Author tags\"/>\n            <metadata name=\"com.atlassw.tools.eclipse.checkstyle.lastEnabledSeverity\" value=\"error\"/>\n            <property name=\"severity\" value=\"ignore\"/>\n            <property name=\"format\" value=\"@author\"/>\n        </module>\n        <module name=\"Regexp\">\n            <metadata name=\"com.atlassw.tools.eclipse.checkstyle.comment\" value=\"No one line javadoc comments\"/>\n            <property name=\"severity\" value=\"error\"/>\n            <property name=\"format\" value=\"[/][*][*][^\\n]*[*][/]\"/>\n            <property name=\"message\" value=\"No one line javadoc comments\"/>\n            <property name=\"illegalPattern\" value=\"true\"/>\n        </module>\n        <module name=\"NoWhitespaceAfter\">\n            <property name=\"severity\" value=\"error\"/>\n            <property name=\"allowLineBreaks\" value=\"false\"/>\n            <property name=\"tokens\" value=\"BNOT,DEC,DOT,INC,LNOT,UNARY_MINUS,UNARY_PLUS\"/>\n        </module>\n        <module name=\"WhitespaceAfter\">\n            <property name=\"tokens\" value=\"TYPECAST\"/>\n        </module>\n        <module name=\"TypecastParenPad\">\n            <property name=\"severity\" value=\"error\"/>\n            <property name=\"tokens\" value=\"RPAREN,TYPECAST\"/>\n        </module>\n        <module name=\"ParenPad\"/>\n        <module name=\"MethodParamPad\"/>\n        <module name=\"NoWhitespaceBefore\">\n            <property name=\"severity\" value=\"error\"/>\n            <property name=\"tokens\" value=\"SEMI,POST_DEC,POST_INC\"/>\n        </module>\n        <module name=\"NoWhitespaceBefore\">\n            <property name=\"severity\" value=\"error\"/>\n            <property name=\"allowLineBreaks\" value=\"true\"/>\n            <property name=\"tokens\" value=\"DOT\"/>\n        </module>\n        <module name=\"RedundantModifier\"/>\n        <module name=\"EqualsHashCode\"/>\n    </module>\n    <module name=\"PackageHtml\">\n        <property name=\"severity\" value=\"ignore\"/>\n    </module>\n    <module name=\"SuppressionCommentFilter\">\n        <property name=\"offCommentFormat\" value=\"CHECKSTYLE_OFF\"/>\n        <property name=\"onCommentFormat\" value=\"CHECKSTYLE_ON\"/>\n    </module>\n    <module name=\"SuppressionCommentFilter\">\n        <metadata name=\"com.atlassw.tools.eclipse.checkstyle.comment\" value=\"Avoid name checking\"/>\n        <property name=\"offCommentFormat\" value=\"CHECKSTYLE_NAMING_OFF\"/>\n        <property name=\"onCommentFormat\" value=\"CHECKSTYLE_NAMING_ON\"/>\n        <property name=\"checkFormat\" value=\".*Name.*\"/>\n        <property name=\"messageFormat\" value=\".*name.*\"/>\n    </module>\n</module>\n"
  },
  {
    "path": "src/main/tools/format.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<profiles version=\"11\">\n    <profile kind=\"CodeFormatterProfile\" name=\"GWT Format\" version=\"11\">\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_enum_constant\" value=\"end_of_line\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_semicolon\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.align_type_members_on_columns\" value=\"false\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.format_line_comments\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve\" value=\"1\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations\" value=\"1\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.indent_statements_compare_to_body\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line\" value=\"false\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.tabulation.size\" value=\"2\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.blank_lines_before_imports\" value=\"0\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk\" value=\"1\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.continuation_indentation\" value=\"2\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_binary_operator\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_assignment\" value=\"0\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.blank_lines_before_member_type\" value=\"0\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_conditional_expression\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.indent_parameter_description\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.format_html\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.format_source_code\" value=\"false\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations\" value=\"insert\"/>\n        <setting\n                id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference\"\n                value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_unary_operator\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.indentation.size\" value=\"2\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration\" value=\"end_of_line\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.lineSplit\" value=\"80\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment\" value=\"false\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_array_initializer\" value=\"end_of_line\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.format_header\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_multiple_fields\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line\" value=\"false\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_binary_operator\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header\"\n                 value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer\" value=\"32\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_method_declaration\" value=\"end_of_line\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant\"\n                 value=\"do not insert\"/>\n        <setting\n                id=\"org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration\"\n                value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments\"\n                 value=\"do not insert\"/>\n        <setting\n                id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference\"\n                value=\"do not insert\"/>\n        <setting\n                id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration\"\n                value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.blank_lines_before_field\" value=\"0\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.format_javadoc_comments\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.format_block_comments\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_binary_expression\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.wrap_before_binary_operator\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.blank_lines_after_package\" value=\"1\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.blank_lines_between_import_groups\" value=\"1\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_ellipsis\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration\" value=\"end_of_line\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment\" value=\"false\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.blank_lines_after_imports\" value=\"1\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.compiler.problem.assertIdentifier\" value=\"error\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_block_in_case\" value=\"end_of_line\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration\" value=\"end_of_line\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration\" value=\"0\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line\" value=\"false\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.indent_empty_lines\" value=\"false\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.compiler.source\" value=\"1.5\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header\"\n                 value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.line_length\" value=\"80\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_type_declaration\" value=\"end_of_line\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.compiler.compliance\" value=\"1.5\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.compact_else_if\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations\" value=\"false\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.use_spaces_only_for_leading_indentations\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_switch\" value=\"end_of_line\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body\" value=\"0\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation\" value=\"insert\"/>\n        <setting\n                id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference\"\n                value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.compiler.problem.enumIdentifier\" value=\"error\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line\" value=\"false\"/>\n        <setting id=\"org.eclipse.jdt.core.compiler.codegen.targetPlatform\" value=\"1.5\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_compact_if\" value=\"48\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_ellipsis\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression\"\n                 value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.indent_statements_compare_to_block\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line\" value=\"false\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration\"\n                 value=\"end_of_line\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation\" value=\"4\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header\"\n                 value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column\" value=\"false\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_unary_operator\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer\" value=\"2\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.indent_root_tags\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_enum_constants\" value=\"0\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.tabulation.char\" value=\"space\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.blank_lines_before_package\" value=\"0\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line\" value=\"false\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.blank_lines_before_method\" value=\"1\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_after_annotation\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column\" value=\"false\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_block\" value=\"end_of_line\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter\" value=\"insert\"/>\n    </profile>\n</profiles>\n"
  },
  {
    "path": "src/main/webapp/css/style.css",
    "content": "table.source {\n    border-style: solid;\n    border-color: #bbb;\n    border-spacing: 0;\n    border-collapse: collapse;\n    width: 100%;\n}\n\ntable.source td {\n    text-align: right;\n    white-space: nowrap;\n}\ntable.source td.left {\n    text-align: left;\n}\ntable.source td.center {\n    text-align: center;\n}\ntable.source td.right {\n    text-align: right;\n}\ntable.source a {\n\ttext-decoration: none;\n}\n\n\ntable.source th {\n    padding-left: 0.5em;\n    font-weight: bold;\n    background-color: #f0f0f0;\n    white-space: nowrap;\n}\n\ndiv.title {\n    background-color: #f0f0f0;\n    padding: 0px;\n    margin-top: 20px;\n}\n\n.bold {\n\tfont-weight: bold; \n}\n\n.nwrap {\n  white-space: nowrap;\n}\n.red, table.source .red a {\n\tcolor: red;\n}\n\n.green, table.source .green a {\n\tcolor: green;\n}\n.trend {\n\tmargin-right: 40px;\n\tborder: solid 1px pink;\n        margin-bottom: 20px;\n}\n\n"
  },
  {
    "path": "src/main/webapp/help.html",
    "content": "<div>This plugin understands the <a\r\n\thref=\"http://jakarta.apache.org/jmeter/\">JMeter</a> analysis report XML\r\nformat, <a\r\n\thref=\"http://jakarta.apache.org/jmeter/\">JMeter</a> Summariser report text format,  \r\n\t<a href=\"http://www.soapui.org/\"> SOAPUI report in JUnit format</a>, \r\n  <a href=\"http://www.soapui.org/\">Iago</a> format as recorded while parrot server is running, and\r\n  <a href=\"https://saas.hpe.com/en-us/software/loadrunner\">LoadRunner</a> analysis format.\r\n\t<br/>\r\n\r\n\r\nThis plug-in does not perform the actual analysis; it only\r\ndisplays useful information about analysis results, such as average\r\nresponding time, historical result trend, web UI for viewing analysis\r\nreports, and so on.\r\n\r\n<p>\r\nTo use this feature, first set up your build to run tests, then select the adequate parser for your tests (JMeter, JUnit, or Iago) and finally\r\nyou have to specify the path to the different performance files. By default the plugin will use the <tt>**/*.jtl</tt> pattern for\r\nJMeter, <tt>**/TEST*.xml</tt> for JUnit tests ,<tt>**/*.log</tt> pattern for JMeter Summariser, <tt>parrot-server-stats.log</tt> for Iago, and <tt>**/*.mdb</tt> for LoadRunner.\r\n</p>\r\n</div>\r\n"
  },
  {
    "path": "src/main/webapp/help_es.html",
    "content": "<div>Este plugin es capaz de analizar los informes XML de <a\r\n\thref=\"http://jakarta.apache.org/jmeter/\">JMeter</a> y de <a href=\"http://www.soapui.org/\"> SOAPUI en formato JUnit</a>. <br/>\r\nEl plugin no realiza el análisis de rendimiento, únicamente muestra información útil de los\r\nresultados del análisis como son la media en el tiempo de respuesta, tendencia del rendimiento a lo largo de las distintas\r\nejecuciones, páginas y gráficos para ver los resultados de análisis.\r\n\r\n<p>\r\nPara utilizar esta funcionalidad, primero debes configurar tu proyecto para ejecutar tests de rendimiento, después debes\r\nelegir el tipo de ficheros de informe a analizar (JMeter o JUnit), y finalmente la ubicación de estos ficheros.\r\nPor defecto el plugin utilizará el patrón <tt>**/*.jtl</tt> para ficheros JMeter y <tt>**/TEST*.xml</tt> en el caso de JUnit.\r\n</p>\r\n</div>\r\n"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/AbstractGraphGenerationTest.java",
    "content": "package hudson.plugins.performance;\n\nimport hudson.model.AbstractProject;\nimport hudson.model.Run;\nimport hudson.plugins.performance.actions.PerformanceBuildAction;\nimport hudson.plugins.performance.parsers.JMeterTestHelper;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.util.DescribableList;\nimport org.jfree.data.category.CategoryDataset;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.kohsuke.stapler.StaplerRequest;\nimport org.kohsuke.stapler.StaplerResponse;\nimport org.mockito.Mock;\nimport org.mockito.quality.Strictness;\n\nimport javax.servlet.ServletOutputStream;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.when;\nimport static org.mockito.Mockito.withSettings;\n\n\npublic abstract class AbstractGraphGenerationTest {\n\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    protected PerformanceBuildAction performanceBuildAction;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    protected AbstractProject project;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    protected Run build;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    protected StaplerRequest request;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    protected StaplerResponse response;\n\n    protected PerformanceReport report;\n\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    protected PerformanceReportMap reportMap;\n\n    @BeforeEach\n    public void baseSetup() throws Exception {\n        report = JMeterTestHelper.parse(\"/JMeterResults.jtl\");\n        report.setBuildAction(performanceBuildAction);\n        when(build.getDisplayName()).thenReturn(\"mock\");\n        when(response.getOutputStream()).thenReturn(mock(ServletOutputStream.class));\n        when(build.getAction(PerformanceBuildAction.class)).thenReturn(performanceBuildAction);\n        when(performanceBuildAction.getPerformanceReportMap()).thenReturn(reportMap);\n        when(performanceBuildAction.getBuild()).thenReturn(build);\n        when(performanceBuildAction.getParserByDisplayName(\"JmeterSummarizer\")).thenReturn(null);\n        when(performanceBuildAction.getParserByDisplayName(\"Iago\")).thenReturn(null);\n        when(reportMap.getPerformanceReport(\"JMeterResults.jtl\")).thenReturn(report);\n    }\n\n    protected void setGraphType(String graphType) {\n        DescribableList list = mock(DescribableList.class, withSettings().strictness(Strictness.LENIENT));\n        when(project.getPublishersList()).thenReturn(list);\n        PerformancePublisher publisher = mock(PerformancePublisher.class, withSettings().strictness(Strictness.LENIENT));\n        when(list.get(PerformancePublisher.class)).thenReturn(publisher);\n        when(publisher.getGraphType()).thenReturn(graphType);\n    }\n\n    protected Number[] toArray(CategoryDataset cd) {\n        List<Number> values = new ArrayList<>();\n        for (int i = 0; i < cd.getRowCount(); i++) {\n            for (int j = 0; j < cd.getColumnCount(); j++) {\n                values.add(cd.getValue(i, j));\n            }\n        }\n        return values.toArray(new Number[0]);\n    }\n}\n"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/BaselineComparisonTest.java",
    "content": "package hudson.plugins.performance;\n\nimport hudson.model.Run;\nimport hudson.model.TaskListener;\nimport hudson.plugins.performance.actions.PerformanceBuildAction;\nimport hudson.plugins.performance.data.TaurusFinalStats;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.mockito.Mock;\nimport org.mockito.junit.jupiter.MockitoExtension;\n\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.when;\n\n@ExtendWith(MockitoExtension.class)\nclass BaselineComparisonTest extends AbstractGraphGenerationTest {\n    private static final String LABEL = \"BlazeDemo\";\n\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    protected Run prevBuild;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    protected PerformanceBuildAction prevAction;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    protected PerformanceReportMap prevReportMap;\n\n\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    protected Run buildWithNumber3;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    protected PerformanceBuildAction actionWithNumber3;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    protected PerformanceReportMap reportMapWithNumber3;\n\n    private Map<String, PerformanceReport> reportMapForBuild = new HashMap<>();\n    private Map<String, PerformanceReport> reportMapForPreviousBuild = new HashMap<>();\n    private Map<String, PerformanceReport> reportMapForBuildNumber3 = new HashMap<>();\n\n\n    @BeforeEach\n    void setup() {\n        when(build.getPreviousBuild()).thenReturn(prevBuild);\n        when(prevBuild.getPreviousBuild()).thenReturn(buildWithNumber3);\n        when(prevBuild.getPreviousCompletedBuild()).thenReturn(buildWithNumber3);\n        when(build.getNumber()).thenReturn(5);\n        when(prevBuild.getNumber()).thenReturn(4);\n        when(buildWithNumber3.getNumber()).thenReturn(3);\n\n        prepareReportForBuild(5, 3, reportMapForBuild);\n        prepareReportForBuild(4, 0, reportMapForPreviousBuild);\n        prepareReportForBuild(3, 0, reportMapForBuildNumber3);\n        when(reportMap.getPerformanceReportMap()).thenReturn(reportMapForBuild);\n\n\n        when(prevBuild.getAction(PerformanceBuildAction.class)).thenReturn(prevAction);\n        when(prevAction.getBuild()).thenReturn(prevBuild);\n        when(prevAction.getPerformanceReportMap(false)).thenReturn(prevReportMap);\n        when(prevReportMap.getPerformanceReportMap()).thenReturn(reportMapForPreviousBuild);\n\n        when(buildWithNumber3.getAction(PerformanceBuildAction.class)).thenReturn(actionWithNumber3);\n        when(actionWithNumber3.getBuild()).thenReturn(buildWithNumber3);\n        when(actionWithNumber3.getPerformanceReportMap(false)).thenReturn(reportMapWithNumber3);\n        when(reportMapWithNumber3.getPerformanceReportMap()).thenReturn(reportMapForBuildNumber3);\n    }\n\n    private void prepareReportForBuild(int num, int baseline, Map<String, PerformanceReport> map) {\n        PerformanceReport report = new PerformanceReport();\n        TaurusFinalStats sample = new TaurusFinalStats();\n        sample.setLabel(LABEL);\n        sample.setSucc(num * 30);\n        sample.setFail(num * 3);\n        sample.setPerc0(num * 10);\n        sample.setPerc50(num * 10 + 1);\n        sample.setPerc90(num * 10 + 2);\n        sample.setPerc95(num * 10 + 2);\n        sample.setPerc100(num * 10 + 3);\n        sample.setAverageResponseTime(num * 10 + 6);\n        report.addSample(sample, true);\n        report.setBaselineBuild(baseline);\n        map.put(LABEL, report);\n    }\n\n    @Test\n    void testBaselineBuild5() throws Exception {\n        new PerformanceReportMap(performanceBuildAction, mock(TaskListener.class)) {\n            @Override\n            protected void parseReports(Run<?, ?> build, TaskListener listener, PerformanceReportCollector collector, String filename) throws IOException {\n                setPerformanceReportMap(reportMapForBuild);\n            }\n        };\n\n        // Comparison between build 5 and 3.\n        PerformanceReport report = reportMapForBuild.get(LABEL);\n        assertEquals(165, report.samplesCount());\n        assertEquals(66, report.getSamplesCountDiff());\n\n        assertEquals(56, report.getAverage());\n        assertEquals(20, report.getAverageDiff());\n\n        Map<Double, Long> percentilesValues = report.getPercentilesValues();\n        Map<Double, Long> percentilesDiffValues = report.getPercentilesDiffValues();\n        assertEquals(Long.valueOf(50), percentilesValues.get(0.0));\n        assertEquals(Long.valueOf(51), percentilesValues.get(50.0));\n        assertEquals(Long.valueOf(52), percentilesValues.get(90.0));\n        assertEquals(Long.valueOf(52), percentilesValues.get(95.0));\n        assertEquals(Long.valueOf(53), percentilesValues.get(100.0));\n\n        assertEquals(Long.valueOf(20), percentilesDiffValues.get(0.0));\n        assertEquals(Long.valueOf(20), percentilesDiffValues.get(50.0));\n        assertEquals(Long.valueOf(20), percentilesDiffValues.get(90.0));\n        assertEquals(Long.valueOf(20), percentilesDiffValues.get(95.0));\n        assertEquals(Long.valueOf(20), percentilesDiffValues.get(100.0));\n    }\n\n    @Test\n    void testBaselineBuild4() throws Exception {\n        new PerformanceReportMap(prevAction, mock(TaskListener.class)) {\n            @Override\n            protected void parseReports(Run<?, ?> build, TaskListener listener, PerformanceReportCollector collector, String filename) throws IOException {\n                setPerformanceReportMap(reportMapForPreviousBuild);\n            }\n        };\n\n        // Comparison between build 4 and previous 3.\n        PerformanceReport report = reportMapForPreviousBuild.get(LABEL);\n        assertEquals(132, report.samplesCount());\n        assertEquals(33, report.getSamplesCountDiff());\n\n        assertEquals(46, report.getAverage());\n        assertEquals(10, report.getAverageDiff());\n\n        Map<Double, Long> percentilesValues = report.getPercentilesValues();\n        Map<Double, Long> percentilesDiffValues = report.getPercentilesDiffValues();\n        assertEquals(Long.valueOf(40), percentilesValues.get(0.0));\n        assertEquals(Long.valueOf(41), percentilesValues.get(50.0));\n        assertEquals(Long.valueOf(42), percentilesValues.get(90.0));\n        assertEquals(Long.valueOf(42), percentilesValues.get(95.0));\n        assertEquals(Long.valueOf(43), percentilesValues.get(100.0));\n\n        assertEquals(Long.valueOf(10), percentilesDiffValues.get(0.0));\n        assertEquals(Long.valueOf(10), percentilesDiffValues.get(50.0));\n        assertEquals(Long.valueOf(10), percentilesDiffValues.get(90.0));\n        assertEquals(Long.valueOf(10), percentilesDiffValues.get(95.0));\n        assertEquals(Long.valueOf(10), percentilesDiffValues.get(100.0));\n    }\n\n    @Test\n    void testBaselineBuild3() throws Exception {\n        new PerformanceReportMap(actionWithNumber3, mock(TaskListener.class)) {\n            @Override\n            protected void parseReports(Run<?, ?> build, TaskListener listener, PerformanceReportCollector collector, String filename) throws IOException {\n                setPerformanceReportMap(reportMapForBuildNumber3);\n            }\n        };\n\n        // Comparison between build 3 and 3\n        PerformanceReport report = reportMapForBuildNumber3.get(LABEL);\n        assertEquals(99, report.samplesCount());\n        assertEquals(0, report.getSamplesCountDiff());\n\n        assertEquals(36, report.getAverage());\n        assertEquals(0, report.getAverageDiff());\n\n        Map<Double, Long> percentilesValues = report.getPercentilesValues();\n        Map<Double, Long> percentilesDiffValues = report.getPercentilesDiffValues();\n        assertEquals(Long.valueOf(30), percentilesValues.get(0.0));\n        assertEquals(Long.valueOf(31), percentilesValues.get(50.0));\n        assertEquals(Long.valueOf(32), percentilesValues.get(90.0));\n        assertEquals(Long.valueOf(32), percentilesValues.get(95.0));\n        assertEquals(Long.valueOf(33), percentilesValues.get(100.0));\n\n        assertEquals(Long.valueOf(0), percentilesDiffValues.get(0.0));\n        assertEquals(Long.valueOf(0), percentilesDiffValues.get(50.0));\n        assertEquals(Long.valueOf(0), percentilesDiffValues.get(90.0));\n        assertEquals(Long.valueOf(0), percentilesDiffValues.get(95.0));\n        assertEquals(Long.valueOf(0), percentilesDiffValues.get(100.0));\n    }\n}\n"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/PerformancePipelineTest.java",
    "content": "package hudson.plugins.performance;\n\nimport hudson.model.Result;\nimport hudson.slaves.DumbSlave;\nimport org.apache.commons.io.IOUtils;\nimport org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;\nimport org.jenkinsci.plugins.workflow.job.WorkflowJob;\nimport org.jenkinsci.plugins.workflow.job.WorkflowRun;\nimport org.junit.jupiter.api.Test;\nimport org.jvnet.hudson.test.JenkinsRule;\nimport org.jvnet.hudson.test.junit.jupiter.WithJenkins;\n\nimport java.net.URL;\nimport java.nio.charset.StandardCharsets;\n\n@WithJenkins\nclass PerformancePipelineTest {\n\n    @Test\n    void bztSmokeTests(JenkinsRule rule) throws Exception {\n        final String path = getClass().getResource(\"/performanceTest.yml\").getPath();\n        DumbSlave s = rule.createOnlineSlave();\n        s.setLabelString(\"test performance test \");\n        WorkflowJob p = rule.createProject(WorkflowJob.class, \"demo job\");\n        p.getRootDir().mkdirs();\n        String bztParams = path + ' ' + \"-o modules.jmeter.plugins=[] -o services=[] \" +\n                \"-o \\\\'reporting.-1={module: \\\"junit-xml\\\", filename: \\\"report.xml\\\"}\\\\' \" +\n                \"-o \\\\'execution.0.scenario.requests.1={url: \\\"http://blazedemo.com/\\\": assert: [\\\"yo mamma\\\"]}\\\\'\";\n        p.setDefinition(new CpsFlowDefinition(\n                \"node('\" + rule.jenkins.getSelfLabel().getName() + \"'){ bzt(params: '\" + bztParams\n                        + \"', useSystemSitePackages: false, printDebugOutput: true, bztVersion: '1.16.19') }\",\n                true));\n        WorkflowRun r = p.scheduleBuild2(0).waitForStart();\n        rule.assertBuildStatusSuccess(rule.waitForCompletion(r));\n        rule.assertLogContains(\"Writing JUnit XML report into: report.xml\", r);\n        rule.assertLogContains(\"File aggregate-results.xml reported\", r);\n        rule.assertLogContains(\"of errors [SUCCESS].\", r);\n        if (JenkinsRule.getLog(r).contains(\"Performance test: Installing bzt into 'taurus-venv'\")) {\n            rule.assertLogContains(\"Taurus CLI Tool v1.16.19\", r);\n        }\n    }\n\n    @Test\n    void perfReportSmokeTests(JenkinsRule rule) throws Exception {\n        String fileContents = null;\n\n        URL url = getClass().getResource(\"/TaurusXMLReport.xml\");\n        if (url != null) {\n            fileContents = IOUtils.toString(url, StandardCharsets.UTF_8);\n        }\n\n        final String report = fileContents;\n\n        DumbSlave s = rule.createOnlineSlave();\n        s.setLabelString(\"test performance report DSL function\");\n        WorkflowJob p = rule.createProject(WorkflowJob.class, \"demo\");\n        p.setDefinition(new CpsFlowDefinition(\n                \"node{ writeFile file: 'test.xml', text: '''\" + report\n                        + \"'''; perfReport errorFailedThreshold: 0, errorUnstableThreshold: 0, sourceDataFiles: 'test.xml' }\",\n                true));\n        WorkflowRun r = p.scheduleBuild2(0).waitForStart();\n        rule.assertBuildStatus(Result.FAILURE, rule.waitForCompletion(r));\n        rule.assertLogContains(\"File test.xml reported 1.625% of errors [FAILURE]. Build status is: FAILURE\", r);\n    }\n\n}\n"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/PerformancePublisherTest.java",
    "content": "package hudson.plugins.performance;\n\nimport edu.umd.cs.findbugs.annotations.NonNull;\nimport hudson.EnvVars;\nimport hudson.FilePath;\nimport hudson.Launcher;\nimport hudson.model.AbstractBuild;\nimport hudson.model.BuildListener;\nimport hudson.model.FreeStyleBuild;\nimport hudson.model.FreeStyleProject;\nimport hudson.model.Job;\nimport hudson.model.Result;\nimport hudson.model.Run;\nimport hudson.model.TaskListener;\nimport hudson.plugins.performance.actions.PerformanceBuildAction;\nimport hudson.plugins.performance.build.PerformanceTestBuildTest;\nimport hudson.plugins.performance.constraints.AbstractConstraint;\nimport hudson.plugins.performance.data.TaurusFinalStats;\nimport hudson.plugins.performance.parsers.JMeterCsvParser;\nimport hudson.plugins.performance.parsers.JMeterParser;\nimport hudson.plugins.performance.parsers.PerformanceReportParser;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.reports.PerformanceReportTest;\nimport hudson.plugins.performance.reports.UriReport;\nimport hudson.util.StreamTaskListener;\nimport jenkins.util.BuildListenerAdapter;\nimport org.junit.jupiter.api.Disabled;\nimport org.junit.jupiter.api.Test;\nimport org.jvnet.hudson.test.Issue;\nimport org.jvnet.hudson.test.JenkinsRule;\nimport org.jvnet.hudson.test.JenkinsRule.WebClient;\nimport org.jvnet.hudson.test.TestBuilder;\nimport org.jvnet.hudson.test.junit.jupiter.WithJenkins;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.PrintStream;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.List;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\nimport static org.junit.jupiter.api.Assertions.assertFalse;\nimport static org.junit.jupiter.api.Assertions.assertNotNull;\nimport static org.junit.jupiter.api.Assertions.assertNull;\nimport static org.junit.jupiter.api.Assertions.assertTrue;\nimport static org.junit.jupiter.api.Assertions.fail;\n\n/**\n * @author Kohsuke Kawaguchi\n */\n@WithJenkins\nclass PerformancePublisherTest {\n\n    @Test\n    void testBuild(JenkinsRule jenkinsRule) throws Exception {\n        FreeStyleProject p = jenkinsRule.createFreeStyleProject();\n        p.getBuildersList().add(new TestBuilder() {\n            @Override\n            public boolean perform(AbstractBuild<?, ?> build,\n                    Launcher launcher, BuildListener listener)\n                    throws InterruptedException, IOException {\n                build.getWorkspace().child(\"test.jtl\").copyFrom(\n                        getClass().getResource(\"/JMeterResults.jtl\"));\n                return true;\n            }\n        });\n        p.getPublishersList().add(\n                new PerformancePublisher(\"\", 0, 0, \"\", 0, 0, 0, 0, 0, false, \"\", false, false, false, false, false,\n                        null));\n\n        FreeStyleBuild b = jenkinsRule.assertBuildStatusSuccess(p.scheduleBuild2(0).get());\n        PerformanceBuildAction a = b.getAction(PerformanceBuildAction.class);\n\n        try {\n            //assertNotNull(a);\n            // poke a few random pages to verify rendering\n            WebClient wc = jenkinsRule.createWebClient();\n            wc.getPage(b, \"performance\");\n            wc.getPage(b, \"performance/uriReport/test.jtl:Home.endperformanceparameter/\");\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n\n    @Test\n    void testBuildWithFormattedTimeStamp(JenkinsRule jenkinsRule) throws Exception {\n        final FreeStyleProject p = jenkinsRule.createFreeStyleProject();\n        p.getBuildersList().add(new TestBuilder() {\n            @Override\n            public boolean perform(AbstractBuild<?, ?> build,\n                    Launcher launcher, BuildListener listener)\n                    throws InterruptedException, IOException {\n                build.getWorkspace().child(\"test.csv\").copyFrom(\n                        getClass().getResource(\"/JMeterPublisher_formatted_timeStamp.csv\"));\n                return true;\n            }\n        });\n        p.getPublishersList().add(new PerformancePublisher(\"test.csv\"));\n\n        FreeStyleBuild b = jenkinsRule.assertBuildStatus(Result.SUCCESS, p.scheduleBuild2(0).get());\n        b.save();\n    }\n\n    @Test\n    void testStandardResultsXML(JenkinsRule jenkinsRule) throws Exception {\n        FreeStyleProject p = jenkinsRule.createFreeStyleProject();\n        p.getBuildersList().add(new TestBuilder() {\n            @Override\n            public boolean perform(AbstractBuild<?, ?> build,\n                    Launcher launcher, BuildListener listener)\n                    throws InterruptedException, IOException {\n                build.getWorkspace().child(\"test.jtl\").copyFrom(getClass().getResource(\"/JMeterResults.jtl\"));\n                return true;\n            }\n        });\n\n        List<PerformanceReportParser> parsers = new ArrayList<PerformanceReportParser>();\n        parsers.add(new JMeterParser(\"test.jtl\", PerformanceReportTest.DEFAULT_PERCENTILES));\n\n        PerformancePublisher publisher = new PerformancePublisher(\"\", 0, 0, \"\", 0, 0, 0, 0, 0, false, \"\", false, false,\n                false, false, false, parsers);\n        publisher.setModeEvaluation(false);\n        p.getPublishersList().add(publisher);\n\n        FreeStyleBuild b = jenkinsRule.assertBuildStatusSuccess(p.scheduleBuild2(0).get());\n        b.getAction(PerformanceBuildAction.class);\n\n        String standardExportFilename = b.getRootDir().getAbsolutePath() + File.separator + \"archive\" + File.separator\n                + \"standardResults.xml\";\n        String content = new String(Files.readAllBytes(Paths.get(standardExportFilename)));\n        assertEquals(\"<?xml version=\\\"1.0\\\"?>\\n\" +\n                \"<results>\\n\" +\n                \"<api>\\n\" +\n                \"\\t<uri>Home</uri>\\n\" +\n                \"\\t<samples>4</samples>\\n\" +\n                \"\\t<average>7930</average>\\n\" +\n                \"\\t<min>501</min>\\n\" +\n                \"\\t<median>598</median>\\n\" +\n                \"\\t<ninetieth>14720</ninetieth>\\n\" +\n                \"\\t<ninetyFifth>14720</ninetyFifth>\\n\" +\n                \"\\t<max>15902</max>\\n\" +\n                \"\\t<httpCode>200</httpCode>\\n\" +\n                \"\\t<errors>0.0</errors>\\n\" +\n                \"</api>\\n\" +\n                \"<api>\\n\" +\n                \"\\t<uri>Workgroup</uri>\\n\" +\n                \"\\t<samples>4</samples>\\n\" +\n                \"\\t<average>354</average>\\n\" +\n                \"\\t<min>58</min>\\n\" +\n                \"\\t<median>63</median>\\n\" +\n                \"\\t<ninetieth>278</ninetieth>\\n\" +\n                \"\\t<ninetyFifth>278</ninetyFifth>\\n\" +\n                \"\\t<max>1017</max>\\n\" +\n                \"\\t<httpCode>200</httpCode>\\n\" +\n                \"\\t<errors>0.0</errors>\\n\" +\n                \"</api>\\n\" +\n                \"</results>\\n\", content);\n    }\n\n    @Test\n    void testBuildWithParameters(JenkinsRule jenkinsRule) throws Exception {\n        FreeStyleProject p = jenkinsRule.createFreeStyleProject(\"JobTest\");\n        p.getBuildersList().add(new TestBuilder() {\n            @Override\n            public boolean perform(AbstractBuild<?, ?> build,\n                    Launcher launcher, BuildListener listener)\n                    throws InterruptedException, IOException {\n                build.getWorkspace().child(\"JobTest/test.jtl\").copyFrom(\n                        getClass().getResource(\"/JMeterResults.jtl\"));\n                return true;\n            }\n        });\n        p.getPublishersList().add(\n                new PerformancePublisher(\"\", 0, 0, \"\", 0, 0, 0, 0, 0, false, \"\", false, false, false, false, false,\n                        null));\n\n        FreeStyleBuild b = jenkinsRule.assertBuildStatusSuccess(p.scheduleBuild2(0).get());\n        PerformanceBuildAction a = b.getAction(PerformanceBuildAction.class);\n\n        try {\n            //assertNotNull(a);\n            // poke a few random pages to verify rendering\n            WebClient wc = jenkinsRule.createWebClient();\n            wc.getPage(b, \"performance\");\n            wc.getPage(b, \"performance/uriReport/test.jtl:Home.endperformanceparameter/\");\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n\n    }\n\n    @Test\n    void testBuildUnstableResponseThreshold(JenkinsRule jenkinsRule) throws Exception {\n        FreeStyleProject p = jenkinsRule.createFreeStyleProject(\"TestJob\");\n        p.getBuildersList().add(new TestBuilder() {\n            @Override\n            public boolean perform(AbstractBuild<?, ?> build,\n                    Launcher launcher, BuildListener listener)\n                    throws InterruptedException, IOException {\n                build.getWorkspace().child(\"test.jtl\").copyFrom(\n                        getClass().getResource(\"/JMeterResults.jtl\"));\n                return true;\n            }\n        });\n        p.getPublishersList().add(\n                new PerformancePublisher(\"test.jtl\", 0, 0, \"test.jtl:100\", 0, 0, 0, 0, 0, false, \"\", false, false,\n                        false, false, false, null));\n\n        FreeStyleBuild b = jenkinsRule.assertBuildStatus(Result.UNSTABLE, p.scheduleBuild2(0).get());\n        PerformanceBuildAction a = b.getAction(PerformanceBuildAction.class);\n\n        try {\n            assertNotNull(a);\n            // poke a few random pages to verify rendering\n            WebClient wc = jenkinsRule.createWebClient();\n            wc.getPage(b, \"performance\");\n            wc.getPage(b, \"performance/uriReport/test.jtl:Home.endperformanceparameter/\");\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n\n    @Test\n    void testBuildStableResponseThreshold(JenkinsRule jenkinsRule) throws Exception {\n        FreeStyleProject p = jenkinsRule.createFreeStyleProject();\n        p.getBuildersList().add(new TestBuilder() {\n            @Override\n            public boolean perform(AbstractBuild<?, ?> build,\n                    Launcher launcher, BuildListener listener)\n                    throws InterruptedException, IOException {\n                build.getWorkspace().child(\"test.jtl\").copyFrom(\n                        getClass().getResource(\"/JMeterResults.jtl\"));\n                return true;\n            }\n        });\n        p.getPublishersList().add(\n                new PerformancePublisher(\"\", 0, 0, \"test.jtl:5000\", 0, 0, 0, 0, 0, false, \"\", false, false, false,\n                        false, false, null));\n\n        FreeStyleBuild b = jenkinsRule.assertBuildStatusSuccess(p.scheduleBuild2(0).get());\n        PerformanceBuildAction a = b.getAction(PerformanceBuildAction.class);\n\n        try {\n            //assertNotNull(a);\n\n            // poke a few random pages to verify rendering\n            WebClient wc = jenkinsRule.createWebClient();\n            wc.getPage(b, \"performance\");\n            wc.getPage(b, \"performance/uriReport/test.jtl:Home.endperformanceparameter/\");\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n\n    @Issue(\"JENKINS-22011\")\n    // TODO - Fix this test case, it was not compiling with forking over\n    // and now its not passing due to second build being successful,\n    // not failing due to threshold problems Ignore flag not being\n    // used, have to look at dependency tree, most likely pre 4.x\n    // junit dependency\n    @Disabled\n    @Test\n    void buildUnstableAverageResponseTimeRelativeThreshold(JenkinsRule jenkinsRule) throws Exception {\n        FreeStyleProject p = jenkinsRule.createFreeStyleProject();\n\n        p.getPublishersList().add(\n                new PerformancePublisher(\"\", 0, 0, null, 100.0d, 0, 50.0d, 0, 0, false, \"ART\", true, false, true, false,\n                        false, null));\n        // first build\n        p.getBuildersList().add(new TestBuilder() {\n            @Override\n            public boolean perform(AbstractBuild<?, ?> build,\n                    Launcher launcher, BuildListener listener)\n                    throws InterruptedException, IOException {\n                build.getWorkspace().child(\"test1.xml\").copyFrom(\n                        getClass().getResource(\"/TEST-JUnitResults-relative-thrashould.xml\"));\n                return true;\n            }\n        });\n\n        jenkinsRule.assertBuildStatus(Result.SUCCESS, p.scheduleBuild2(0).get());\n\n        // second build with high time\n        p.getBuildersList().add(new TestBuilder() {\n            @Override\n            public boolean perform(AbstractBuild<?, ?> build,\n                    Launcher launcher, BuildListener listener)\n                    throws InterruptedException, IOException {\n                build.getWorkspace().child(\"test2.xml\").copyFrom(\n                        getClass().getResource(\"/TEST-JUnitResults-relative-thrashould-2.xml\"));\n                return true;\n            }\n        });\n\n        jenkinsRule.assertBuildStatus(Result.UNSTABLE, p.scheduleBuild2(0).get());\n\n    }\n\n    @Test\n    void testEmptyReportParsersList(JenkinsRule jenkinsRule) throws Exception {\n        PerformancePublisher publisher = new PerformancePublisher(\"\", 0, 0, \"\", 0.0, 0.0, 0.0, 0.0, 0, true, \"MRT\",\n                true, true, true, true, false, null);\n        RunExt run = new RunExt(jenkinsRule.createFreeStyleProject());\n        run.onStartBuilding();\n        try {\n            publisher.perform(run, new FilePath(new File(\".\")), jenkinsRule.createLocalLauncher(),\n                    jenkinsRule.createTaskListener());\n        } catch (NullPointerException ex) {\n            fail(\"Plugin must work with empty parser list\" + ex.getMessage());\n        }\n    }\n\n    private class RunExt extends Run {\n\n        protected RunExt(@NonNull Job job) throws IOException {\n            super(job);\n        }\n\n        @Override\n        protected void onStartBuilding() {\n            super.onStartBuilding();\n        }\n    }\n\n    @Test\n    void testOptionMethods(JenkinsRule jenkinsRule) throws Exception {\n        final double DELTA = 0.001;\n        PerformancePublisher publisher = new PerformancePublisher(\"reportFile.xml\", 15, 16, \"reportFile.xml:100\", 9.0,\n                8.0, 7.0, 6.0, 3, true, \"MRT\",\n                true, true, true, true, false, null);\n        assertEquals(\"reportFile.xml\", publisher.getSourceDataFiles());\n        assertEquals(15, publisher.getErrorFailedThreshold());\n        assertEquals(16, publisher.getErrorUnstableThreshold());\n        assertEquals(\"reportFile.xml:100\", publisher.getErrorUnstableResponseTimeThreshold());\n        assertEquals(9.0, publisher.getRelativeFailedThresholdPositive(), DELTA);\n        assertEquals(8.0, publisher.getRelativeFailedThresholdNegative(), DELTA);\n        assertEquals(7.0, publisher.getRelativeUnstableThresholdPositive(), DELTA);\n        assertEquals(6.0, publisher.getRelativeUnstableThresholdNegative(), DELTA);\n        assertEquals(3, publisher.getNthBuildNumber());\n        assertTrue(publisher.isModePerformancePerTestCase());\n        assertEquals(\"MRT\", publisher.getConfigType());\n        assertTrue(publisher.getModeOfThreshold());\n        assertTrue(publisher.isFailBuildIfNoResultFile());\n        assertTrue(publisher.getCompareBuildPrevious());\n        assertTrue(publisher.isModeThroughput());\n\n        publisher.setSourceDataFiles(\"newReportFile.xml\");\n        publisher.setErrorFailedThreshold(0);\n        publisher.setErrorUnstableThreshold(0);\n        publisher.setErrorUnstableResponseTimeThreshold(\"newReportFile.xml:101\");\n        publisher.setRelativeFailedThresholdPositive(0.0);\n        publisher.setRelativeFailedThresholdNegative(0.0);\n        publisher.setRelativeUnstableThresholdPositive(0.0);\n        publisher.setRelativeUnstableThresholdNegative(0.0);\n        publisher.setNthBuildNumber(0);\n        publisher.setModePerformancePerTestCase(false);\n        publisher.setConfigType(\"ART\");\n        publisher.setModeOfThreshold(false);\n        publisher.setFailBuildIfNoResultFile(false);\n        publisher.setCompareBuildPrevious(false);\n        publisher.setModeThroughput(false);\n\n        assertEquals(\"newReportFile.xml\", publisher.getSourceDataFiles());\n        assertEquals(0, publisher.getErrorFailedThreshold());\n        assertEquals(0, publisher.getErrorUnstableThreshold());\n        assertEquals(\"newReportFile.xml:101\", publisher.getErrorUnstableResponseTimeThreshold());\n        assertEquals(0.0, publisher.getRelativeFailedThresholdPositive(), DELTA);\n        assertEquals(0.0, publisher.getRelativeFailedThresholdNegative(), DELTA);\n        assertEquals(0.0, publisher.getRelativeUnstableThresholdPositive(), DELTA);\n        assertEquals(0.0, publisher.getRelativeUnstableThresholdNegative(), DELTA);\n        assertEquals(0, publisher.getNthBuildNumber());\n        assertFalse(publisher.isModePerformancePerTestCase());\n        assertFalse(publisher.isModePerformancePerTestCase());\n        assertEquals(\"ART\", publisher.getConfigType());\n        assertFalse(publisher.getModeOfThreshold());\n        assertFalse(publisher.isFailBuildIfNoResultFile());\n        assertFalse(publisher.getCompareBuildPrevious());\n        assertFalse(publisher.isModeThroughput());\n\n        publisher.setModeEvaluation(true);\n        assertTrue(publisher.isModeEvaluation());\n        publisher.setPersistConstraintLog(true);\n        assertTrue(publisher.isPersistConstraintLog());\n        publisher.setIgnoreUnstableBuilds(true);\n        assertTrue(publisher.isIgnoreUnstableBuilds());\n        publisher.setIgnoreFailedBuilds(true);\n        assertTrue(publisher.isIgnoreFailedBuilds());\n        List<AbstractConstraint> allConstraints = AbstractConstraint.all();\n        publisher.setConstraints(allConstraints);\n        assertEquals(allConstraints, publisher.getConstraints());\n\n        publisher = new PerformancePublisher(\"reportFile.xml\", 15, 16, \"reportFile.xml:100\", 9.0, 8.0, 7.0, 6.0, 3,\n                true, \"MRT\",\n                true, true, true, true, false, null);\n        assertTrue(publisher.isMRT());\n        publisher = new PerformancePublisher(\"reportFile.xml\", 15, 16, \"reportFile.xml:100\", 9.0, 8.0, 7.0, 6.0, 3,\n                true, \"ART\",\n                true, true, true, true, false, null);\n        assertTrue(publisher.isART());\n        publisher = new PerformancePublisher(\"reportFile.xml\", 15, 16, \"reportFile.xml:100\", 9.0, 8.0, 7.0, 6.0, 3,\n                true, \"PRT\",\n                true, true, true, true, false, null);\n        assertTrue(publisher.isPRT());\n\n        publisher.setFilename(\"testfilename\");\n        assertEquals(\"testfilename\", publisher.getFilename());\n\n        List<PerformanceReportParser> emptyList = Collections.emptyList();\n        publisher.setParsers(emptyList);\n        assertEquals(emptyList, publisher.getParsers());\n    }\n\n    @Test\n    void testErrorThresholdUnstable(JenkinsRule jenkinsRule) throws Exception {\n\n        PerformancePublisher publisherUnstable = new PerformancePublisher(\"JMeterPublisher.csv\",\n                -1,\n                1, // errorUnstableThreshold\n                \"\", 0.0, 0.0, 0.0, 0.0, 1, true, \"MRT\",\n                false, // modeOfThreshold (false = Error Threshold)\n                true, true, true, false, null);\n\n        FreeStyleProject project = jenkinsRule.createFreeStyleProject();\n\n        PerformanceTestBuildTest.FreeStyleBuildExt buildExt = new PerformanceTestBuildTest.FreeStyleBuildExt(project);\n        buildExt.setWorkspace(new FilePath(Files.createTempDirectory(null).toFile()));\n        buildExt.onStartBuilding();\n\n        buildExt.getRootDir().mkdirs();\n        buildExt.getWorkspace().child(\"JMeterPublisher.csv\").copyFrom(\n                getClass().getResource(\"/JMeterPublisher.csv\"));\n\n        ByteArrayOutputStream stream = new ByteArrayOutputStream();\n        publisherUnstable.perform(buildExt, buildExt.getWorkspace(), jenkinsRule.createLocalLauncher(),\n                new BuildListenerAdapter(new StreamTaskListener(stream, StandardCharsets.UTF_8)));\n\n        String log = new String(stream.toByteArray());\n        assertEquals(Result.UNSTABLE, buildExt.getResult(), log);\n        assertTrue(log.contains(\n                \"Performance: File JMeterPublisher.csv reported 33.333% of errors [UNSTABLE]. Build status is: UNSTABLE\"),\n                log);\n    }\n\n    @Test\n    void testErrorThresholdFailed(JenkinsRule jenkinsRule) throws Exception {\n\n        PerformancePublisher publisherFailed = new PerformancePublisher(\"JMeterPublisher.csv\",\n                2, // errorFailedThreshold\n                -1, \"\", 0.0, 0.0, 0.0, 0.0, 1, true, \"MRT\",\n                false, // modeOfThreshold (false = Error Threshold)\n                true, true, true, false, null);\n\n        FreeStyleProject project = jenkinsRule.createFreeStyleProject();\n\n        PerformanceTestBuildTest.FreeStyleBuildExt buildExt = new PerformanceTestBuildTest.FreeStyleBuildExt(project);\n        buildExt.setWorkspace(new FilePath(Files.createTempDirectory(null).toFile()));\n        buildExt.onStartBuilding();\n\n        buildExt.getRootDir().mkdirs();\n        buildExt.getWorkspace().child(\"JMeterPublisher.csv\").copyFrom(\n                getClass().getResource(\"/JMeterPublisher.csv\"));\n\n        ByteArrayOutputStream stream = new ByteArrayOutputStream();\n        publisherFailed.perform(buildExt, buildExt.getWorkspace(), jenkinsRule.createLocalLauncher(),\n                new BuildListenerAdapter(new StreamTaskListener(stream, StandardCharsets.UTF_8)));\n\n        String log = new String(stream.toByteArray());\n        assertEquals(Result.FAILURE, buildExt.getResult(), log);\n        assertTrue(log.contains(\n                \"Performance: File JMeterPublisher.csv reported 33.333% of errors [FAILURE]. Build status is: FAILURE\"),\n                log);\n    }\n\n    @Test\n    void testErrorThresholdAverageResponseTime(JenkinsRule jenkinsRule) throws Exception {\n\n        PerformancePublisher publisherART = new PerformancePublisher(\"JMeterPublisher.csv\", -1, -1,\n                \"JMeterPublisher.csv:1000\", 0.0, 0.0, 0.0, 0.0, 1, true, \"MRT\",\n                false, // modeOfThreshold (false = Error Threshold)\n                true, true, true, false, null);\n\n        FreeStyleProject project = jenkinsRule.createFreeStyleProject();\n\n        PerformanceTestBuildTest.FreeStyleBuildExt buildExt = new PerformanceTestBuildTest.FreeStyleBuildExt(project);\n        buildExt.setWorkspace(new FilePath(Files.createTempDirectory(null).toFile()));\n        buildExt.onStartBuilding();\n\n        buildExt.getRootDir().mkdirs();\n        buildExt.getWorkspace().child(\"JMeterPublisher.csv\").copyFrom(\n                getClass().getResource(\"/JMeterPublisher.csv\"));\n\n        ByteArrayOutputStream stream = new ByteArrayOutputStream();\n        publisherART.perform(buildExt, buildExt.getWorkspace(), jenkinsRule.createLocalLauncher(),\n                new BuildListenerAdapter(new StreamTaskListener(stream, StandardCharsets.UTF_8)));\n\n        String log = new String(stream.toByteArray());\n        assertEquals(Result.UNSTABLE, buildExt.getResult(), log);\n        assertTrue(log.contains(\n                \"UNSTABLE: JMeterPublisher.csv has exceeded the threshold of [1000] with the time of [1433]\"), log);\n\n        // For Number Format Exception\n        publisherART.setErrorUnstableResponseTimeThreshold(\"JMeterPublisher.csv:1!00\");\n        stream = new ByteArrayOutputStream();\n        publisherART.perform(buildExt, buildExt.getWorkspace(), jenkinsRule.createLocalLauncher(),\n                new BuildListenerAdapter(new StreamTaskListener(stream, StandardCharsets.UTF_8)));\n\n        log = new String(stream.toByteArray());\n        assertEquals(Result.FAILURE, buildExt.getResult(), log);\n        assertTrue(log.contains(\"ERROR: Threshold set to a non-number [1!00]\"), log);\n    }\n\n    @Test\n    void testMigration(JenkinsRule jenkinsRule) throws Exception {\n        List<PerformanceReportParser> parsers = new ArrayList<PerformanceReportParser>();\n        parsers.add(new JMeterCsvParser(\"test1\", PerformanceReportTest.DEFAULT_PERCENTILES));\n        parsers.add(new JMeterParser(\"test2\", PerformanceReportTest.DEFAULT_PERCENTILES));\n\n        PerformancePublisher publisher = new PerformancePublisher(\"\", -1, -1, \"\", 0.0, 0.0, 0.0, 0.0, 1, true, \"MRT\",\n                false, true, true, true, false, parsers);\n\n        assertEquals(\"test1;test2\", publisher.getSourceDataFiles());\n        assertNull(publisher.getParsers());\n        publisher.setSourceDataFiles(\"\");\n        assertEquals(\"\", publisher.getSourceDataFiles());\n\n        publisher.setParsers(parsers);\n        publisher.setFilename(\"test3\");\n        publisher.readResolve();\n        assertEquals(\"test1;test2;test3\", publisher.getSourceDataFiles());\n        assertNull(publisher.getParsers());\n    }\n\n    @Test\n    void testRelativeThresholdUnstableNegative(JenkinsRule jenkinsRule) throws Exception {\n\n        FreeStyleProject p = jenkinsRule.createFreeStyleProject();\n\n        PerformancePublisher publisher = new PerformancePublisher(\"JMeterCsvResults.csv\", -1, -1, \"\", -0.1, -0.1, -0.1,\n                5.0, // relativeUnstableThresholdNegative\n                1, true, \"MRT\",\n                true, // modeOfThreshold (true = Relative Threshold)\n                true, true, true, false, null);\n\n        p.getPublishersList().add(publisher);\n        // first build\n        p.getBuildersList().add(new TestBuilder() {\n            @Override\n            public boolean perform(AbstractBuild<?, ?> build,\n                    Launcher launcher, BuildListener listener)\n                    throws InterruptedException, IOException {\n                build.getWorkspace().child(\"JMeterCsvResults.csv\").copyFrom(\n                        getClass().getResource(\"/JMeterCsvResults.csv\"));\n                build.getWorkspace().child(\"JMeterPublisher.csv\").copyFrom(\n                        getClass().getResource(\"/JMeterPublisher.csv\"));\n\n                return true;\n            }\n        });\n\n        jenkinsRule.assertBuildStatus(Result.SUCCESS, p.scheduleBuild2(0).get());\n\n        publisher.setSourceDataFiles(\"JMeterPublisher.csv\");\n        jenkinsRule.assertBuildStatus(Result.UNSTABLE, p.scheduleBuild2(0).get());\n    }\n\n    @Test\n    void testRelativeThresholdUnstablePositive(JenkinsRule jenkinsRule) throws Exception {\n\n        FreeStyleProject p = jenkinsRule.createFreeStyleProject();\n\n        PerformancePublisher publisher = new PerformancePublisher(\"JMeterPublisher.csv\", -1, -1, \"\", -0.1, -0.1,\n                9.0, // relativeUnstableThresholdPositive\n                -0.1, // relativeUnstableThresholdNegative\n                1, true, \"ART\",\n                true, // modeOfThreshold (true = Relative Threshold)\n                true, true, true, false, null);\n\n        p.getPublishersList().add(publisher);\n        // first build\n        p.getBuildersList().add(new TestBuilder() {\n            @Override\n            public boolean perform(AbstractBuild<?, ?> build,\n                    Launcher launcher, BuildListener listener)\n                    throws InterruptedException, IOException {\n                build.getWorkspace().child(\"JMeterCsvResults.csv\").copyFrom(\n                        getClass().getResource(\"/JMeterCsvResults.csv\"));\n                build.getWorkspace().child(\"JMeterPublisher.csv\").copyFrom(\n                        getClass().getResource(\"/JMeterPublisher.csv\"));\n\n                return true;\n            }\n        });\n\n        jenkinsRule.assertBuildStatus(Result.SUCCESS, p.scheduleBuild2(0).get());\n\n        publisher.setSourceDataFiles(\"JMeterCsvResults.csv\");\n        jenkinsRule.assertBuildStatus(Result.UNSTABLE, p.scheduleBuild2(0).get());\n    }\n\n    @Test\n    void testRelativeThresholdFailedNegative(JenkinsRule jenkinsRule) throws Exception {\n\n        FreeStyleProject p = jenkinsRule.createFreeStyleProject();\n\n        PerformancePublisher publisher = new PerformancePublisher(\"JMeterCsvResults.csv\", -1, -1, \"\", -0.1,\n                5.1, // relativeFailedThresholdNegative\n                -0.1, -0.1, 1, true, \"PRT\",\n                true, // modeOfThreshold (true = Relative Threshold)\n                true, false, // false - means compare with Build Number\n                true, false, null);\n\n        p.getPublishersList().add(publisher);\n        // first build\n        p.getBuildersList().add(new TestBuilder() {\n            @Override\n            public boolean perform(AbstractBuild<?, ?> build,\n                    Launcher launcher, BuildListener listener)\n                    throws InterruptedException, IOException {\n                build.getWorkspace().child(\"JMeterCsvResults.csv\").copyFrom(\n                        getClass().getResource(\"/JMeterCsvResults.csv\"));\n                build.getWorkspace().child(\"JMeterPublisher.csv\").copyFrom(\n                        getClass().getResource(\"/JMeterPublisher.csv\"));\n\n                return true;\n            }\n        });\n\n        jenkinsRule.assertBuildStatus(Result.SUCCESS, p.scheduleBuild2(0).get());\n\n        publisher.setSourceDataFiles(\"JMeterPublisher.csv\");\n        jenkinsRule.assertBuildStatus(Result.FAILURE, p.scheduleBuild2(0).get());\n    }\n\n    @Test\n    void testRelativeThresholdFailedPositive(JenkinsRule jenkinsRule) throws Exception {\n\n        FreeStyleProject p = jenkinsRule.createFreeStyleProject();\n\n        PerformancePublisher publisher = new PerformancePublisher(\"JMeterPublisher.csv\", -1, -1, \"\",\n                5.1, // relativeFailedThresholdPositive\n                -0.1, -0.1, -0.1, 1, true, \"PRT\",\n                true, // modeOfThreshold (true = Relative Threshold)\n                true, false, // false - means compare with Build Number\n                true, false, null);\n\n        p.getPublishersList().add(publisher);\n        // first build\n        p.getBuildersList().add(new TestBuilder() {\n            @Override\n            public boolean perform(AbstractBuild<?, ?> build,\n                    Launcher launcher, BuildListener listener)\n                    throws InterruptedException, IOException {\n                build.getWorkspace().child(\"JMeterCsvResults.csv\").copyFrom(\n                        getClass().getResource(\"/JMeterCsvResults.csv\"));\n                build.getWorkspace().child(\"JMeterPublisher.csv\").copyFrom(\n                        getClass().getResource(\"/JMeterPublisher.csv\"));\n\n                return true;\n            }\n        });\n\n        jenkinsRule.assertBuildStatus(Result.SUCCESS, p.scheduleBuild2(0).get());\n\n        publisher.setSourceDataFiles(\"JMeterCsvResults.csv\");\n        jenkinsRule.assertBuildStatus(Result.FAILURE, p.scheduleBuild2(0).get());\n    }\n\n    @Test\n    void testRelativeThresholds(JenkinsRule jenkinsRule) throws Exception {\n        FreeStyleProject freeStyleProject = jenkinsRule.createFreeStyleProject();\n\n        final RunExt prevBuild = new RunExt(freeStyleProject);\n        prevBuild.onStartBuilding();\n\n        PerformancePublisher publisher = new PerformancePublisher(\"\") {\n            @Override\n            protected List<PerformanceReportParser> getParsers(Run<?, ?> build, FilePath workspace, PrintStream logger,\n                    EnvVars env) throws IOException, InterruptedException {\n                List<PerformanceReportParser> parsers = new ArrayList<>();\n                parsers.add(new JMeterCsvParser(\"\", \"\"));\n                return parsers;\n            }\n\n            @Override\n            public Collection<PerformanceReport> prepareEvaluation(Run<?, ?> run, FilePath workspace,\n                    TaskListener listener, List<PerformanceReportParser> parsers)\n                    throws IOException, InterruptedException {\n                List<PerformanceReport> reports = new ArrayList<>();\n                reports.add(new PerformanceReport());\n                reports.add(new PerformanceReport());\n                return reports;\n            }\n\n            @Override\n            protected List<UriReport> getBuildUriReports(Run<?, ?> build, FilePath workspace, TaskListener listener,\n                    List<PerformanceReportParser> parsers, boolean locatePerformanceReports)\n                    throws IOException, InterruptedException {\n                List<UriReport> uriReports = new ArrayList<>();\n                if (locatePerformanceReports) {\n                    UriReport report = new UriReport(new PerformanceReport(), \"aaaaa\", \"bbbbb\");\n                    TaurusFinalStats taurusFinalStats = new TaurusFinalStats();\n                    taurusFinalStats.setAverageResponseTime(100d);\n                    report.setFromTaurusFinalStats(taurusFinalStats);\n                    uriReports.add(report);\n                } else {\n                    UriReport report = new UriReport(new PerformanceReport(), \"aaaaa\", \"bbbbb\");\n                    TaurusFinalStats taurusFinalStats = new TaurusFinalStats();\n                    taurusFinalStats.setAverageResponseTime(200d);\n                    report.setFromTaurusFinalStats(taurusFinalStats);\n                    uriReports.add(report);\n                }\n                return uriReports;\n            }\n\n            @Override\n            public Run<?, ?> getnthBuild(Run<?, ?> build) {\n                return prevBuild;\n            }\n        };\n        publisher.setModeOfThreshold(true);\n        publisher.setRelativeFailedThresholdPositive(10);\n        publisher.setRelativeUnstableThresholdPositive(5);\n\n        RunExt run1 = new RunExt(freeStyleProject);\n        run1.onStartBuilding();\n        publisher.perform(run1, new FilePath(new File(\".\")), jenkinsRule.createLocalLauncher(),\n                jenkinsRule.createTaskListener());\n        assertEquals(Result.SUCCESS, run1.getResult());\n\n        publisher.setRelativeUnstableThresholdNegative(10);\n        RunExt run2 = new RunExt(freeStyleProject);\n        run2.onStartBuilding();\n        publisher.perform(run2, new FilePath(new File(\".\")), jenkinsRule.createLocalLauncher(),\n                jenkinsRule.createTaskListener());\n        assertEquals(Result.UNSTABLE, run2.getResult());\n\n        publisher.setRelativeFailedThresholdNegative(10);\n        RunExt run3 = new RunExt(freeStyleProject);\n        run3.onStartBuilding();\n        publisher.perform(run3, new FilePath(new File(\".\")), jenkinsRule.createLocalLauncher(),\n                jenkinsRule.createTaskListener());\n        assertEquals(Result.FAILURE, run3.getResult());\n    }\n}"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/PerformanceReportMapTest.java",
    "content": "package hudson.plugins.performance;\n\nimport hudson.model.Run;\nimport hudson.model.TaskListener;\nimport hudson.plugins.performance.actions.PerformanceBuildAction;\nimport hudson.util.DescribableList;\nimport hudson.util.RunList;\nimport org.jfree.chart.JFreeChart;\nimport org.jfree.data.category.CategoryDataset;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.mockito.Mock;\nimport org.mockito.junit.jupiter.MockitoExtension;\nimport org.mockito.quality.Strictness;\n\nimport java.io.IOException;\nimport java.util.Collections;\n\nimport static org.junit.jupiter.api.Assertions.assertArrayEquals;\nimport static org.junit.jupiter.api.Assertions.assertEquals;\nimport static org.junit.jupiter.api.Assertions.assertFalse;\nimport static org.junit.jupiter.api.Assertions.assertTrue;\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.when;\nimport static org.mockito.Mockito.withSettings;\n\n@ExtendWith(MockitoExtension.class)\nclass PerformanceReportMapTest extends AbstractGraphGenerationTest {\n\n    private TestablePerformanceReportMap target;\n\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    protected PerformancePublisher performancePublisher;\n\n    @BeforeEach\n    void reportMapSetup() throws Exception {\n        when(build.getParent()).thenReturn(project);\n        when(request.getParameter(\"performanceReportPosition\")).thenReturn(\"JMeterResults.jtl\");\n        when(project.getBuilds()).thenReturn(RunList.fromRuns(Collections.singletonList(build)));\n\n        DescribableList publisherList = mock(DescribableList.class, withSettings().strictness(Strictness.LENIENT));\n        when(publisherList.get(PerformancePublisher.class)).thenReturn(performancePublisher);\n        when(performancePublisher.isModeThroughput()).thenReturn(true);\n        when(performancePublisher.isModePerformancePerTestCase()).thenReturn(false);\n        when(project.getPublishersList()).thenReturn(publisherList);\n        target = new TestablePerformanceReportMap(performanceBuildAction, mock(TaskListener.class));\n    }\n\n    @Test\n    void testGetters() throws Exception {\n        PerformanceReportMap reportMap = new PerformanceReportMap(performanceBuildAction, mock(TaskListener.class));\n        assertTrue(reportMap.ifModeThroughputUsed());\n        assertFalse(reportMap.ifModePerformancePerTestCaseUsed());\n        assertFalse(reportMap.ifShowTrendGraphsUsed());\n        assertEquals(performanceBuildAction, reportMap.getBuildAction());\n        assertEquals(\"Performance\", reportMap.getDisplayName());\n        assertEquals(\"performance\", reportMap.getUrlName());\n    }\n    \n    @Test\n    void testNoPerformancePublisher() throws Exception {\n    \twhen(build.getParent()).thenReturn(null);\n        PerformanceReportMap reportMap = new PerformanceReportMap(performanceBuildAction, mock(TaskListener.class));\n        assertTrue(reportMap.ifModeThroughputUsed());\n        assertTrue(reportMap.ifModePerformancePerTestCaseUsed());\n        assertTrue(reportMap.ifShowTrendGraphsUsed());\n    }\n\n    @Test\n    void testRespondingTimeGraphAverageValues() throws Exception {\n        setGraphType(PerformancePublisher.ART);\n        target.doRespondingTimeGraph(request, response);\n        assertArrayEquals(new Number[]{4142L}, toArray(target.dataset));\n    }\n\n    @Test\n    void testRespondingTimeGraphMedianValues() throws Exception {\n        setGraphType(PerformancePublisher.MRT);\n        target.doRespondingTimeGraph(request, response);\n        assertArrayEquals(new Number[]{501L}, toArray(target.dataset));\n    }\n\n    @Test\n    void testSummarizerGraphAverageValues() throws Exception {\n        setGraphType(PerformancePublisher.ART);\n        target.doSummarizerGraph(request, response);\n        assertArrayEquals(new Number[]{7930L, 354L}, toArray(target.dataset));\n    }\n\n    @Test\n    void testSummarizerGraphMedianValues() throws Exception {\n        setGraphType(PerformancePublisher.MRT);\n        target.doSummarizerGraph(request, response);\n        assertArrayEquals(new Number[]{598L, 63L}, toArray(target.dataset));\n    }\n\n    @Test\n    void testThroughputGraph() throws Exception {\n        target.doThroughputGraph(request, response);\n        assertArrayEquals(new Number[]{0.04515946937623483}, toArray(target.dataset));\n    }\n\n    @Test\n    void testRespondingTimeGraphPerTestCaseMode() throws Exception {\n        setGraphType(PerformancePublisher.MRT);\n        target.doRespondingTimeGraphPerTestCaseMode(request, response);\n        assertArrayEquals(new Number[]{598L, 63L}, toArray(target.dataset));\n    }\n\n    @Test\n    void testErrorsGraph() throws Exception {\n        setGraphType(PerformancePublisher.MRT);\n        target.doErrorsGraph(request, response);\n        assertArrayEquals(new Number[]{0.0}, toArray(target.dataset));\n    }\n\n    public class TestablePerformanceReportMap extends PerformanceReportMap {\n\n        public CategoryDataset dataset;\n\n        public TestablePerformanceReportMap(PerformanceBuildAction buildAction, TaskListener listener) throws IOException {\n            super(buildAction, listener);\n        }\n\n        @Override\n        protected JFreeChart createRespondingTimeChart(CategoryDataset dataset, int legendLimit) {\n            this.dataset = dataset;\n            return super.createRespondingTimeChart(dataset, legendLimit);\n        }\n\n        @Override\n        protected JFreeChart createSummarizerChart(CategoryDataset dataset) {\n            this.dataset = dataset;\n            return super.createSummarizerChart(dataset);\n        }\n\n        @Override\n        protected void parseReports(Run<?, ?> build, TaskListener listener, PerformanceReportCollector collector, String filename) {\n            collector.addAll(Collections.singletonList(report));\n        }\n\n        @Override\n        protected JFreeChart createThroughputChart(CategoryDataset dataset) {\n            this.dataset = dataset;\n            return super.createThroughputChart(dataset);\n        }\n\n        @Override\n        protected JFreeChart createErrorsChart(CategoryDataset dataset) {\n            this.dataset = dataset;\n            return super.createErrorsChart(dataset);\n        }\n    }\n}\n"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/TrendReportGraphsTest.java",
    "content": "package hudson.plugins.performance;\n\nimport hudson.model.FreeStyleBuild;\nimport hudson.model.FreeStyleProject;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.reports.PerformanceReportTest;\nimport org.junit.jupiter.api.Test;\nimport org.jvnet.hudson.test.JenkinsRule;\nimport org.jvnet.hudson.test.junit.jupiter.WithJenkins;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\nimport static org.junit.jupiter.api.Assertions.assertFalse;\nimport static org.junit.jupiter.api.Assertions.assertNull;\n\n@WithJenkins\nclass TrendReportGraphsTest {\n\n    @Test\n    void test(JenkinsRule j) throws Exception {\n        FreeStyleProject project = j.createFreeStyleProject();\n        FreeStyleBuild build = project.createExecutable();\n        PerformanceReport report = new PerformanceReport(PerformanceReportTest.DEFAULT_PERCENTILES);\n\n        TrendReportGraphs graphs = new TrendReportGraphs(project, build, null, \"simpleFilename\", report);\n\n        assertEquals(0, graphs.getUris().size());\n        assertFalse(graphs.hasSamples(\"\"));\n        assertEquals(\"simpleFilename\", graphs.getFilename());\n        assertEquals(\"Trend report\", graphs.getDisplayName());\n        assertEquals(project, graphs.getProject());\n        assertEquals(build, graphs.getBuild());\n        assertEquals(report, graphs.getPerformanceReport());\n        assertNull(graphs.getUriReport(\"null\"));\n    }\n}"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/actions/ExternalBuildReportActionTest.java",
    "content": "package hudson.plugins.performance.actions;\n\nimport org.junit.jupiter.api.Test;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\nimport static org.junit.jupiter.api.Assertions.assertNull;\n\nclass ExternalBuildReportActionTest {\n\n    @Test\n    void test() throws Exception {\n        ExternalBuildReportAction report = new ExternalBuildReportAction(\"http://some.url.com\");\n\n        assertEquals(\"View External Report\", report.getDisplayName());\n        assertEquals(\"graph.gif\", report.getIconFileName());\n        assertEquals(\"http://some.url.com\", report.getUrlName());\n        assertNull(report.getTarget());\n    }\n}"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/actions/PerformanceProjectActionGraphTest.java",
    "content": "package hudson.plugins.performance.actions;\n\nimport edu.umd.cs.findbugs.annotations.NonNull;\nimport hudson.model.AbstractProject;\nimport hudson.model.Run;\nimport hudson.plugins.performance.AbstractGraphGenerationTest;\nimport hudson.plugins.performance.PerformancePublisher;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.util.RunList;\nimport org.jfree.chart.JFreeChart;\nimport org.jfree.data.category.CategoryDataset;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.mockito.junit.jupiter.MockitoExtension;\n\nimport java.util.Collections;\nimport java.util.List;\n\nimport static org.junit.jupiter.api.Assertions.assertArrayEquals;\nimport static org.mockito.Mockito.when;\n\n@ExtendWith(MockitoExtension.class)\nclass PerformanceProjectActionGraphTest extends AbstractGraphGenerationTest {\n\n    private TestablePerformanceProjectAction target;\n\n    @BeforeEach\n    void actionSetup() throws Exception {\n        when(project.getBuilds()).thenReturn(RunList.fromRuns(Collections.singletonList(build)));\n        target = new TestablePerformanceProjectAction(project);\n    }\n\n    @Test\n    void testRespondingTimeGraphPerTestCaseModeAverageValues() throws Exception {\n        setGraphType(PerformancePublisher.ART);\n        target.doRespondingTimeGraphPerTestCaseMode(request, response);\n        assertArrayEquals(new Number[]{7930L, 354L}, toArray(target.dataset));\n    }\n\n    @Test\n    void testRespondingTimeGraphPerTestCaseModeMedianValues() throws Exception {\n        setGraphType(PerformancePublisher.MRT);\n        target.doRespondingTimeGraphPerTestCaseMode(request, response);\n        assertArrayEquals(new Number[]{598L, 63L}, toArray(target.dataset));\n    }\n\n    @Test\n    void testSummarizerGraphAverageValues() throws Exception {\n        setGraphType(PerformancePublisher.ART);\n        target.doSummarizerGraph(request, response);\n        assertArrayEquals(new Number[]{7930L, 354L}, toArray(target.dataset));\n    }\n\n    @Test\n    void testSummarizerGraphMedianValues() throws Exception {\n        setGraphType(PerformancePublisher.MRT);\n        target.doSummarizerGraph(request, response);\n        assertArrayEquals(new Number[]{598L, 63L}, toArray(target.dataset));\n    }\n\n    @Test\n    void testErrorsGraph() throws Exception {\n        setGraphType(PerformancePublisher.MRT);\n        target.doErrorsGraph(request, response);\n        assertArrayEquals(new Number[]{0.0}, toArray(target.dataset));\n    }\n\n    @Test\n    void testRespondingTimeGraph() throws Exception {\n        setGraphType(PerformancePublisher.MRT);\n        target.doRespondingTimeGraph(request, response);\n        assertArrayEquals(new Number[]{14720L, 14720L, 4142L, 501L}, toArray(target.dataset));\n    }\n\n    @Test\n    void testThroughputGraph() throws Exception {\n        target.doThroughputGraph(request, response);\n        assertArrayEquals(new Number[]{0.04515946937623483}, toArray(target.dataset));\n    }\n\n    private class TestablePerformanceProjectAction extends PerformanceProjectAction {\n\n        public CategoryDataset dataset;\n\n        public TestablePerformanceProjectAction(AbstractProject<?, ?> project) {\n            super(project);\n        }\n\n        @NonNull\n        @Override\n        public List<String> getPerformanceReportList() {\n            return Collections.singletonList(\"JMeterResults.jtl\");\n        }\n\n        @Override\n        protected PerformanceReport getPerformanceReport(Run<?, ?> build, String reportFileName) {\n            return report;\n        }\n\n        @Override\n        protected JFreeChart createRespondingTimeChart(CategoryDataset dataset, int legendLimit) {\n            this.dataset = dataset;\n            return super.createRespondingTimeChart(dataset, legendLimit);\n        }\n\n        @Override\n        protected JFreeChart createSummarizerChart(CategoryDataset dataset, String yAxis, String chartTitle) {\n            this.dataset = dataset;\n            return super.createSummarizerChart(dataset, yAxis, chartTitle);\n        }\n\n        @Override\n        protected JFreeChart createErrorsGraph(CategoryDataset dataset) {\n            this.dataset = dataset;\n            return super.createErrorsGraph(dataset);\n        }\n\n        @Override\n        protected JFreeChart createThroughputGraph(CategoryDataset dataset) {\n            this.dataset = dataset;\n            return super.createThroughputGraph(dataset);\n        }\n    }\n}\n"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/actions/PerformanceProjectActionTest.java",
    "content": "package hudson.plugins.performance.actions;\n\nimport hudson.model.FreeStyleProject;\nimport hudson.plugins.performance.PerformancePublisher;\nimport hudson.plugins.performance.details.GraphConfigurationDetail;\nimport hudson.plugins.performance.details.TestSuiteReportDetail;\nimport hudson.plugins.performance.details.TrendReportDetail;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.jvnet.hudson.test.JenkinsRule;\nimport org.jvnet.hudson.test.junit.jupiter.WithJenkins;\nimport org.kohsuke.stapler.StaplerRequest;\nimport org.mockito.Mock;\nimport org.mockito.junit.jupiter.MockitoExtension;\n\nimport static org.junit.jupiter.api.Assertions.assertFalse;\nimport static org.junit.jupiter.api.Assertions.assertInstanceOf;\nimport static org.junit.jupiter.api.Assertions.assertNull;\nimport static org.junit.jupiter.api.Assertions.assertTrue;\n\n@WithJenkins\n@ExtendWith(MockitoExtension.class)\nclass PerformanceProjectActionTest {\n\n    @Mock\n    private StaplerRequest staplerRequest;\n\n    @Test\n    void testDynamic(JenkinsRule j) throws Exception {\n        FreeStyleProject freeStyleProject = j.createFreeStyleProject(\"testProject\");\n        PerformanceProjectAction performanceProjectAction = new PerformanceProjectAction(freeStyleProject);\n\n        Object nullObj = performanceProjectAction.getDynamic(\"testNull\", null, null);\n        assertNull(nullObj);\n\n        Object graphConfigurationDetail = performanceProjectAction.getDynamic(\"configure\", staplerRequest, null);\n        assertInstanceOf(GraphConfigurationDetail.class, graphConfigurationDetail);\n\n        Object trendReportDetail = performanceProjectAction.getDynamic(\"trendReport\", staplerRequest, null);\n        assertInstanceOf(TrendReportDetail.class, trendReportDetail);\n\n        Object testSuiteReportDetail = performanceProjectAction.getDynamic(\"testsuiteReport\", staplerRequest, null);\n        assertInstanceOf(TestSuiteReportDetail.class, testSuiteReportDetail);\n\n        assertFalse(performanceProjectAction.ifModePerformancePerTestCaseUsed());\n        assertTrue(performanceProjectAction.ifModeThroughputUsed());\n\n        freeStyleProject.getPublishersList().add(new PerformancePublisher(\"\", 0, 0, \"\", 0.0, 0.0, 0.0, 0.0, 0, false, \"\", true, false, false, true,false, null));\n        assertFalse(performanceProjectAction.ifModePerformancePerTestCaseUsed());\n        assertTrue(performanceProjectAction.ifModeThroughputUsed());\n    }\n}"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/build/PerformanceTestBuildTest.java",
    "content": "package hudson.plugins.performance.build;\n\nimport edu.umd.cs.findbugs.annotations.NonNull;\nimport hudson.EnvVars;\nimport hudson.FilePath;\nimport hudson.Launcher;\nimport hudson.model.AbstractProject;\nimport hudson.model.FreeStyleBuild;\nimport hudson.model.FreeStyleProject;\nimport hudson.model.Result;\nimport hudson.model.Run;\nimport hudson.plugins.performance.actions.PerformanceProjectAction;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.tasks.Publisher;\nimport hudson.util.StreamTaskListener;\nimport jenkins.util.BuildListenerAdapter;\nimport org.jenkinsci.plugins.workflow.job.WorkflowJob;\nimport org.junit.jupiter.api.Test;\nimport org.jvnet.hudson.test.JenkinsRule;\nimport org.jvnet.hudson.test.junit.jupiter.WithJenkins;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.util.Arrays;\nimport java.util.Iterator;\nimport java.util.LinkedList;\nimport java.util.List;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\nimport static org.junit.jupiter.api.Assertions.assertFalse;\nimport static org.junit.jupiter.api.Assertions.assertTrue;\n\n@WithJenkins\npublic class PerformanceTestBuildTest {\n\n    @Test\n    void testFlow(JenkinsRule jenkinsRule) throws Exception {\n        String path = getClass().getResource(\"/performanceTest.yml\").getPath();\n\n        FreeStyleProject project = jenkinsRule.createFreeStyleProject();\n\n        FreeStyleBuildExt buildExt = new FreeStyleBuildExt(project);\n        FilePath workspace = new FilePath(Files.createTempDirectory(null).toFile());\n        buildExt.setWorkspace(workspace);\n        buildExt.onStartBuilding();\n\n        buildExt.getRootDir().mkdirs();\n\n        PerformanceTestBuild buildTest = new PerformanceTestBuild(new File(path).getAbsolutePath() + ' '\n                + \"-o modules.jmeter.plugins=[] -o services=[] -o modules.jmeter.version=3.1 -o modules.jmeter.path=\"\n                + workspace.getRemote());\n        buildTest.setGeneratePerformanceTrend(true);\n        buildTest.setPrintDebugOutput(true);\n        buildTest.setUseSystemSitePackages(false);\n        buildTest.setUseBztExitCode(false);\n\n        assertEquals(PerformanceProjectAction.class, buildTest.getProjectAction((AbstractProject) project).getClass());\n\n        ByteArrayOutputStream stream = new ByteArrayOutputStream();\n        StreamTaskListener taskListener = new StreamTaskListener(stream, StandardCharsets.UTF_8);\n        buildTest.perform(buildExt, buildExt.getWorkspace(), jenkinsRule.createLocalLauncher(),\n                new BuildListenerAdapter(taskListener));\n\n        Iterator<Publisher> iterator = project.getPublishersList().iterator();\n        StringBuilder builder = new StringBuilder(\"\\n\\nList publishers:\\n\");\n        while (iterator.hasNext()) {\n            builder.append(iterator.next().getClass().getName()).append(\"\\n\");\n        }\n\n        String jobLog = new String(stream.toByteArray()) + builder.toString();\n\n        assertEquals(Result.SUCCESS, buildExt.getResult(), jobLog);\n    }\n\n    @Test\n    void testInstallFromGit(JenkinsRule jenkinsRule) throws Exception {\n        String path = getClass().getResource(\"/performanceTest.yml\").getPath();\n        String gitRepo = \"git+https://github.com/Blazemeter/taurus.git\";\n\n        FreeStyleProject project = jenkinsRule.createFreeStyleProject();\n\n        FreeStyleBuildExt buildExt = new FreeStyleBuildExt(project);\n        FilePath workspace = new FilePath(Files.createTempDirectory(null).toFile());\n        buildExt.setWorkspace(workspace);\n        buildExt.onStartBuilding();\n\n        buildExt.getRootDir().mkdirs();\n\n        PerformanceTestBuildExt buildTest = new PerformanceTestBuildExt(new File(path).getAbsolutePath());\n        buildTest.setGeneratePerformanceTrend(false);\n        buildTest.setPrintDebugOutput(true);\n        buildTest.setUseSystemSitePackages(false);\n        buildTest.setUseBztExitCode(false);\n        buildTest.setAlwaysUseVirtualenv(true);\n        buildTest.setBztVersion(gitRepo);\n\n        ByteArrayOutputStream stream = new ByteArrayOutputStream();\n        StreamTaskListener taskListener = new StreamTaskListener(stream, StandardCharsets.UTF_8);\n        buildTest.perform(buildExt, buildExt.getWorkspace(), jenkinsRule.createLocalLauncher(),\n                new BuildListenerAdapter(taskListener));\n\n        Iterator<Publisher> iterator = project.getPublishersList().iterator();\n        StringBuilder builder = new StringBuilder(\"\\n\\nList publishers:\\n\");\n        while (iterator.hasNext()) {\n            builder.append(iterator.next().getClass().getName()).append(\"\\n\");\n        }\n\n        String jobLog = new String(stream.toByteArray()) + builder.toString();\n\n        assertEquals(Result.SUCCESS, buildExt.getResult(), jobLog);\n        assertEquals(5, buildTest.commands.size(), jobLog);\n        assertTrue(\n                Arrays.toString(buildTest.commands.get(buildTest.commands.size() - 3)).contains(\"install, \" + gitRepo),\n                jobLog);\n    }\n\n    @Test\n    void testInstallFromURL(JenkinsRule jenkinsRule) throws Exception {\n        String path = getClass().getResource(\"/performanceTest.yml\").getPath();\n        String url = \"http://gettaurus.org/snapshots/bzt-1.9.5.1622.tar.gz\";\n\n        FreeStyleProject project = jenkinsRule.createFreeStyleProject();\n\n        FreeStyleBuildExt buildExt = new FreeStyleBuildExt(project);\n        FilePath workspace = new FilePath(Files.createTempDirectory(null).toFile());\n        buildExt.setWorkspace(workspace);\n        buildExt.onStartBuilding();\n\n        buildExt.getRootDir().mkdirs();\n\n        PerformanceTestBuildExt buildTest = new PerformanceTestBuildExt(new File(path).getAbsolutePath());\n        buildTest.setGeneratePerformanceTrend(false);\n        buildTest.setPrintDebugOutput(true);\n        buildTest.setUseSystemSitePackages(false);\n        buildTest.setUseBztExitCode(false);\n        buildTest.setAlwaysUseVirtualenv(true);\n        buildTest.setBztVersion(url);\n\n        ByteArrayOutputStream stream = new ByteArrayOutputStream();\n        StreamTaskListener taskListener = new StreamTaskListener(stream, StandardCharsets.UTF_8);\n        buildTest.perform(buildExt, buildExt.getWorkspace(), jenkinsRule.createLocalLauncher(),\n                new BuildListenerAdapter(taskListener));\n\n        Iterator<Publisher> iterator = project.getPublishersList().iterator();\n        StringBuilder builder = new StringBuilder(\"\\n\\nList publishers:\\n\");\n        while (iterator.hasNext()) {\n            builder.append(iterator.next().getClass().getName()).append(\"\\n\");\n        }\n\n        String jobLog = new String(stream.toByteArray()) + builder.toString();\n\n        assertEquals(Result.SUCCESS, buildExt.getResult(), jobLog);\n        assertEquals(5, buildTest.commands.size(), jobLog);\n        assertTrue(Arrays.toString(buildTest.commands.get(buildTest.commands.size() - 3)).contains(\"install, \" + url),\n                jobLog);\n    }\n\n    @Test\n    void testInstallFromPath(JenkinsRule jenkinsRule) throws Exception {\n        String path = getClass().getResource(\"/performanceTest.yml\").getPath();\n\n        FreeStyleProject project = jenkinsRule.createFreeStyleProject();\n\n        FreeStyleBuildExt buildExt = new FreeStyleBuildExt(project);\n        FilePath workspace = new FilePath(Files.createTempDirectory(null).toFile());\n        buildExt.setWorkspace(workspace);\n        buildExt.onStartBuilding();\n\n        buildExt.getRootDir().mkdirs();\n\n        PerformanceTestBuildExt buildTest = new PerformanceTestBuildExt(new File(path).getAbsolutePath());\n        buildTest.setGeneratePerformanceTrend(false);\n        buildTest.setPrintDebugOutput(true);\n        buildTest.setUseSystemSitePackages(false);\n        buildTest.setUseBztExitCode(false);\n        buildTest.setAlwaysUseVirtualenv(true);\n        buildTest.setBztVersion(path);\n\n        ByteArrayOutputStream stream = new ByteArrayOutputStream();\n        StreamTaskListener taskListener = new StreamTaskListener(stream, StandardCharsets.UTF_8);\n        buildTest.perform(buildExt, buildExt.getWorkspace(), jenkinsRule.createLocalLauncher(),\n                new BuildListenerAdapter(taskListener));\n\n        Iterator<Publisher> iterator = project.getPublishersList().iterator();\n        StringBuilder builder = new StringBuilder(\"\\n\\nList publishers:\\n\");\n        while (iterator.hasNext()) {\n            builder.append(iterator.next().getClass().getName()).append(\"\\n\");\n        }\n\n        String jobLog = new String(stream.toByteArray()) + builder.toString();\n\n        assertEquals(Result.SUCCESS, buildExt.getResult(), jobLog);\n        assertEquals(5, buildTest.commands.size(), jobLog);\n        assertTrue(Arrays.toString(buildTest.commands.get(buildTest.commands.size() - 3)).contains(\"install, \" + path),\n                jobLog);\n    }\n\n    public static class PerformanceTestBuildExt extends PerformanceTestBuild {\n        public PerformanceTestBuildExt(String params) {\n            super(params);\n        }\n\n        public List<String[]> commands = new LinkedList<>();\n\n        @Override\n        public int runCmd(String[] commands, FilePath workspace, OutputStream logger, Launcher launcher,\n                EnvVars envVars) throws InterruptedException, IOException {\n            if (launcher instanceof Launcher.DummyLauncher) {\n                super.runCmd(commands, workspace, logger, launcher, envVars);\n            }\n            this.commands.add(commands);\n            return 0;\n        }\n    }\n\n    public static class FreeStyleBuildExt extends FreeStyleBuild {\n\n        public FreeStyleBuildExt(FreeStyleProject project) throws IOException {\n            super(project);\n        }\n\n        @Override\n        public void setWorkspace(@NonNull FilePath ws) {\n            super.setWorkspace(ws);\n        }\n\n        @Override\n        public void onStartBuilding() {\n            super.onStartBuilding();\n        }\n    }\n\n    @Test\n    void testGetters(JenkinsRule jenkinsRule) throws Exception {\n        PerformanceTestBuild.Descriptor descriptor = new PerformanceTestBuild.Descriptor();\n        assertTrue(descriptor.isApplicable(null));\n\n        PerformanceTestBuild testBuild = new PerformanceTestBuild(\"test option\");\n        testBuild.setGeneratePerformanceTrend(false);\n        testBuild.setUseBztExitCode(false);\n        testBuild.setUseSystemSitePackages(false);\n        testBuild.setPrintDebugOutput(false);\n        testBuild.setAlwaysUseVirtualenv(false);\n        testBuild.setBztVersion(\"1.0.0.0.0\");\n        testBuild.setWorkingDirectory(\"workingDir\");\n        assertEquals(\"workingDir\", testBuild.getWorkingDirectory());\n        assertEquals(\"1.0.0.0.0\", testBuild.getBztVersion());\n        assertEquals(\"test option\", testBuild.getParams());\n        testBuild.setParams(\"test1\");\n        assertEquals(\"test1\", testBuild.getParams());\n        testBuild.setWorkspace(\"workingDirResolve\");\n        assertEquals(\"workingDirResolve\", testBuild.getWorkingDirectory());\n        assertEquals(\"\", testBuild.getWorkspace());\n\n        assertFalse(testBuild.isUseSystemSitePackages());\n        assertFalse(testBuild.isPrintDebugOutput());\n        assertFalse(testBuild.isGeneratePerformanceTrend());\n        assertFalse(testBuild.isUseBztExitCode());\n        assertFalse(testBuild.isAlwaysUseVirtualenv());\n        testBuild.setGeneratePerformanceTrend(true);\n        testBuild.setPrintDebugOutput(true);\n        testBuild.setUseSystemSitePackages(true);\n        testBuild.setUseBztExitCode(true);\n        testBuild.setAlwaysUseVirtualenv(true);\n        assertTrue(testBuild.isUseSystemSitePackages());\n        assertTrue(testBuild.isPrintDebugOutput());\n        assertTrue(testBuild.isGeneratePerformanceTrend());\n        assertTrue(testBuild.isUseBztExitCode());\n        assertTrue(testBuild.isAlwaysUseVirtualenv());\n\n        testBuild.setVirtualEnvCommand(\"\");\n        assertEquals(\"\", testBuild.getVirtualEnvCommand());\n        testBuild.setVirtualEnvCommand(\"/hardcoded/path/to/virtualenv\");\n        assertEquals(\"/hardcoded/path/to/virtualenv\", testBuild.getVirtualEnvCommand());\n        testBuild.setVirtualEnvCommand(\"$VARIABLE_PATH/virtualenv\");\n        assertEquals(\"$VARIABLE_PATH/virtualenv\", testBuild.getVirtualEnvCommand());\n    }\n\n    @Test\n    void testGenerateReportInPipe(JenkinsRule jenkinsRule) throws Exception {\n        String path = getClass().getResource(\"/performanceTest.yml\").getPath();\n\n        WorkflowJob p = jenkinsRule.createProject(WorkflowJob.class, \"p\");\n        FilePath workspace = new FilePath(Files.createTempDirectory(null).toFile());\n        p.createExecutable();\n        Run run = p.getFirstBuild();\n        String args = new File(path).getAbsolutePath() + ' ' + \"-o modules.jmeter.plugins=[] -o services=[]\";\n\n        FilePath report = new FilePath(new File(workspace.getRemote(), \"aggregate-results.xml\"));\n        report.copyFrom(getClass().getResource(\"/aggregate-results.xml\"));\n\n        PerformanceTestBuildExt buildTest = new PerformanceTestBuildExt(args);\n        buildTest.setGeneratePerformanceTrend(true);\n        buildTest.setPrintDebugOutput(true);\n        buildTest.setUseSystemSitePackages(false);\n        buildTest.setUseBztExitCode(false);\n\n        ByteArrayOutputStream stream = new ByteArrayOutputStream();\n        StreamTaskListener taskListener = new StreamTaskListener(stream, StandardCharsets.UTF_8);\n        buildTest.perform(run, workspace, jenkinsRule.createLocalLauncher(), new BuildListenerAdapter(taskListener));\n\n        String jobLog = new String(stream.toByteArray());\n\n        File reportFile = new File(run.getRootDir(), \"performance-reports/Taurus/aggregate-results.xml\");\n        assertTrue(reportFile.exists(), \"Report file \" + reportFile.getAbsolutePath() + \" expected to exist\");\n        assertTrue(jobLog.contains(\"Performance: Recording Taurus reports\"),\n                \"Job log expected to contains 'Performance: Recording Taurus reports', jobLog:\" + jobLog);\n        assertTrue(jobLog.contains(\"aggregate-results.xml'\"),\n                \"Job log expected to contains 'aggregate-results.xml', jobLog:\" + jobLog);\n        assertTrue(jobLog.contains(\n                \"Performance: Parsing report file '\" + reportFile.getAbsolutePath() + \"' with filterRegex '\"\n                        + PerformanceReport.INCLUDE_ALL + \"'.\"),\n                \"Job log expected to contains 'Performance: Parsing report file ...', jobLog:\" + jobLog);\n    }\n\n    @Test\n    void testFailCriteria(JenkinsRule jenkinsRule) throws Exception {\n        String path = getClass().getResource(\"/performanceTestWithFailCriteria.yml\").getPath();\n\n        WorkflowJob p = jenkinsRule.createProject(WorkflowJob.class, \"p\");\n        FilePath workspace = new FilePath(Files.createTempDirectory(null).toFile());\n        p.createExecutable();\n        Run run = p.getFirstBuild();\n        String args = new File(path).getAbsolutePath() + ' ' + \"-o modules.jmeter.plugins=[] -o services=[]\";\n\n        PerformanceTestBuild buildTest = new PerformanceTestBuildExt(args) {\n            @Override\n            public int runCmd(String[] commands, FilePath workspace, OutputStream logger, Launcher launcher,\n                    EnvVars envVars) throws InterruptedException, IOException {\n                for (String cmd : commands) {\n                    if (cmd.contains(\"performanceTestWithFailCriteria.yml\")) {\n                        logger.write(\"Done performing with code: 3\".getBytes());\n                        return 3;\n                    }\n                }\n                return super.runCmd(commands, workspace, logger, launcher, envVars);\n            }\n        };\n        buildTest.setGeneratePerformanceTrend(false);\n        buildTest.setPrintDebugOutput(true);\n        buildTest.setUseSystemSitePackages(false);\n        buildTest.setUseBztExitCode(true);\n\n        ByteArrayOutputStream stream = new ByteArrayOutputStream();\n        StreamTaskListener taskListener = new StreamTaskListener(stream, StandardCharsets.UTF_8);\n        buildTest.perform(run, workspace, jenkinsRule.createLocalLauncher(), new BuildListenerAdapter(taskListener));\n\n        String jobLog = new String(stream.toByteArray());\n        assertEquals(Result.UNSTABLE, run.getResult(), jobLog);\n        assertTrue(jobLog.contains(\"Done performing with code: 3\"), jobLog);\n    }\n\n    @Test\n    void testResutsChecker(JenkinsRule jenkinsRule) throws Exception {\n        PerformanceTestBuild testBuild = new PerformanceTestBuild(\"test option\");\n        testBuild.setGeneratePerformanceTrend(false);\n        testBuild.setPrintDebugOutput(false);\n        testBuild.setUseSystemSitePackages(false);\n        testBuild.setUseBztExitCode(false);\n\n        assertEquals(Result.SUCCESS, testBuild.getBztJobResult(0));\n        assertEquals(Result.FAILURE, testBuild.getBztJobResult(1));\n        assertEquals(Result.UNSTABLE, testBuild.getBztJobResult(3));\n\n        assertEquals(Result.SUCCESS, testBuild.getJobResult(0));\n        assertEquals(Result.FAILURE, testBuild.getJobResult(1));\n\n        assertTrue(testBuild.isSuccessCode(0));\n        assertFalse(testBuild.isSuccessCode(1));\n    }\n\n    @Test\n    void testPWD(JenkinsRule jenkinsRule) throws Exception {\n        WorkflowJob p = jenkinsRule.createProject(WorkflowJob.class, \"p\");\n        File buildWorkspace = Files.createTempDirectory(null).toFile();\n        FilePath workspace = new FilePath(buildWorkspace);\n        p.createExecutable();\n        Run run = p.getFirstBuild();\n        ByteArrayOutputStream stream = new ByteArrayOutputStream();\n        StreamTaskListener taskListener = new StreamTaskListener(stream, StandardCharsets.UTF_8);\n\n        PerformanceTestBuildExt testBuild = new PerformanceTestBuildExt(\"\");\n        testBuild.setUseSystemSitePackages(false);\n        testBuild.setPrintDebugOutput(true);\n\n        // test absolute path\n        String absoluteWorkspace = \"/tmp/o/work/bzt\";\n        testBuild.setWorkspace(absoluteWorkspace);\n        testBuild.perform(run, workspace, jenkinsRule.createLocalLauncher(), new BuildListenerAdapter(taskListener));\n        String jobLog = new String(stream.toByteArray());\n        assertTrue(new File(absoluteWorkspace).isDirectory(), jobLog);\n        assertTrue(new File(absoluteWorkspace).exists(), jobLog);\n        assertTrue(new File(absoluteWorkspace, \"jenkins-report.yml\").exists(), jobLog);\n\n        // test relative path\n        String relativeWorkspace = \"oooooh/relative/path\";\n        testBuild.setWorkspace(relativeWorkspace);\n        testBuild.perform(run, workspace, jenkinsRule.createLocalLauncher(), new BuildListenerAdapter(taskListener));\n        jobLog = new String(stream.toByteArray());\n        assertTrue(new File(buildWorkspace, relativeWorkspace).isDirectory(), jobLog);\n        assertTrue(new File(buildWorkspace, relativeWorkspace).exists(), jobLog);\n        assertTrue(new File(buildWorkspace, relativeWorkspace + \"/jenkins-report.yml\").exists(), jobLog);\n\n        // test Permission denied\n        String rootPath = \"/rootWorkspace/\";\n        testBuild.setWorkspace(rootPath);\n        testBuild.perform(run, workspace, jenkinsRule.createLocalLauncher(), new BuildListenerAdapter(taskListener));\n        jobLog = new String(stream.toByteArray());\n        assertTrue(jobLog.contains(\"Cannot create working directory because of error: /rootWorkspace\"), jobLog);\n    }\n\n    private void resetVirtualEnvCommands() {\n        PerformanceTestBuild.CHECK_VIRTUALENV_COMMAND[0] = PerformanceTestBuild.VIRTUALENV_COMMAND;\n        PerformanceTestBuild.CREATE_LOCAL_PYTHON_COMMAND_WITH_SYSTEM_PACKAGES_OPTION[0] = PerformanceTestBuild.VIRTUALENV_COMMAND;\n        PerformanceTestBuild.CREATE_LOCAL_PYTHON_COMMAND[0] = PerformanceTestBuild.VIRTUALENV_COMMAND;\n    }\n\n    @Test\n    void testDefaultVirtualEnvCommand(JenkinsRule jenkinsRule) throws Exception {\n        resetVirtualEnvCommands();\n        String path = getClass().getResource(\"/performanceTest.yml\").getPath();\n\n        FreeStyleProject project = jenkinsRule.createFreeStyleProject();\n\n        FreeStyleBuildExt buildExt = new FreeStyleBuildExt(project);\n        FilePath workspace = new FilePath(Files.createTempDirectory(null).toFile());\n        buildExt.setWorkspace(workspace);\n        buildExt.onStartBuilding();\n\n        buildExt.getRootDir().mkdirs();\n\n        PerformanceTestBuildExt buildTest = new PerformanceTestBuildExt(new File(path).getAbsolutePath());\n        buildTest.setGeneratePerformanceTrend(false);\n        buildTest.setPrintDebugOutput(true);\n        buildTest.setUseSystemSitePackages(false);\n        buildTest.setUseBztExitCode(false);\n        buildTest.setAlwaysUseVirtualenv(true);\n\n        ByteArrayOutputStream stream = new ByteArrayOutputStream();\n        StreamTaskListener taskListener = new StreamTaskListener(stream, StandardCharsets.UTF_8);\n        buildTest.perform(buildExt, buildExt.getWorkspace(), new Launcher.DummyLauncher(taskListener),\n                new BuildListenerAdapter(taskListener));\n\n        Iterator<Publisher> iterator = project.getPublishersList().iterator();\n        StringBuilder builder = new StringBuilder(\"\\n\\nList publishers:\\n\");\n        while (iterator.hasNext()) {\n            builder.append(iterator.next().getClass().getName()).append(\"\\n\");\n        }\n\n        String jobLog = new String(stream.toByteArray()) + builder.toString();\n\n        assertEquals(Result.SUCCESS, buildExt.getResult(), jobLog);\n        assertEquals(5, buildTest.commands.size(), jobLog);\n        assertEquals(\"virtualenv\",\n                buildTest.commands.get(0)[0],\n                \"Command should have been 'virtualenv', but instead it was: '\" + buildTest.commands.get(0)[0] + \"'\");\n        resetVirtualEnvCommands();\n    }\n\n    @Test\n    void testHardcodedVirtualEnvCommand(JenkinsRule jenkinsRule) throws Exception {\n        resetVirtualEnvCommands();\n        String path = getClass().getResource(\"/performanceTest.yml\").getPath();\n\n        FreeStyleProject project = jenkinsRule.createFreeStyleProject();\n\n        FreeStyleBuildExt buildExt = new FreeStyleBuildExt(project);\n        FilePath workspace = new FilePath(Files.createTempDirectory(null).toFile());\n        buildExt.setWorkspace(workspace);\n        buildExt.onStartBuilding();\n\n        buildExt.getRootDir().mkdirs();\n\n        PerformanceTestBuildExt buildTest = new PerformanceTestBuildExt(new File(path).getAbsolutePath());\n        buildTest.setGeneratePerformanceTrend(false);\n        buildTest.setPrintDebugOutput(true);\n        buildTest.setUseSystemSitePackages(false);\n        buildTest.setUseBztExitCode(false);\n        buildTest.setAlwaysUseVirtualenv(true);\n        buildTest.setVirtualEnvCommand(\"/path/to/virtualenv\");\n\n        ByteArrayOutputStream stream = new ByteArrayOutputStream();\n        StreamTaskListener taskListener = new StreamTaskListener(stream, StandardCharsets.UTF_8);\n        buildTest.perform(buildExt, buildExt.getWorkspace(), new Launcher.DummyLauncher(taskListener),\n                new BuildListenerAdapter(taskListener));\n\n        Iterator<Publisher> iterator = project.getPublishersList().iterator();\n        StringBuilder builder = new StringBuilder(\"\\n\\nList publishers:\\n\");\n        while (iterator.hasNext()) {\n            builder.append(iterator.next().getClass().getName()).append(\"\\n\");\n        }\n\n        String jobLog = new String(stream.toByteArray()) + builder.toString();\n\n        assertEquals(Result.SUCCESS, buildExt.getResult(), jobLog);\n        assertEquals(5, buildTest.commands.size(), jobLog);\n        assertEquals(\"/path/to/virtualenv\",\n                buildTest.commands.get(0)[0],\n                \"Command should have been '/path/to/virtualenv', but instead it was: '\" + buildTest.commands.get(0)[0] + \"'\");\n        resetVirtualEnvCommands();\n    }\n\n    @Test\n    void testVariableVirtualEnvCommand(JenkinsRule jenkinsRule) throws Exception {\n        resetVirtualEnvCommands();\n        String path = getClass().getResource(\"/performanceTest.yml\").getPath();\n\n        FreeStyleProject project = jenkinsRule.createFreeStyleProject();\n\n        FreeStyleBuildExt buildExt = new FreeStyleBuildExt(project);\n        FilePath workspace = new FilePath(Files.createTempDirectory(null).toFile());\n        buildExt.setWorkspace(workspace);\n        buildExt.onStartBuilding();\n\n        buildExt.getRootDir().mkdirs();\n\n        PerformanceTestBuildExt buildTest = new PerformanceTestBuildExt(new File(path).getAbsolutePath());\n        buildTest.setGeneratePerformanceTrend(false);\n        buildTest.setPrintDebugOutput(true);\n        buildTest.setUseSystemSitePackages(false);\n        buildTest.setUseBztExitCode(false);\n        buildTest.setAlwaysUseVirtualenv(true);\n        buildTest.setVirtualEnvCommand(\"$WORKSPACE/virtualenv\");\n\n        ByteArrayOutputStream stream = new ByteArrayOutputStream();\n        StreamTaskListener taskListener = new StreamTaskListener(stream, StandardCharsets.UTF_8);\n        buildTest.perform(buildExt, buildExt.getWorkspace(), new Launcher.DummyLauncher(taskListener),\n                new BuildListenerAdapter(taskListener));\n\n        Iterator<Publisher> iterator = project.getPublishersList().iterator();\n        StringBuilder builder = new StringBuilder(\"\\n\\nList publishers:\\n\");\n        while (iterator.hasNext()) {\n            builder.append(iterator.next().getClass().getName()).append(\"\\n\");\n        }\n\n        String jobLog = new String(stream.toByteArray()) + builder.toString();\n\n        assertEquals(Result.SUCCESS, buildExt.getResult(), jobLog);\n        assertEquals(5, buildTest.commands.size(), jobLog);\n        assertEquals(workspace + \"/virtualenv\",\n                buildTest.commands.get(0)[0],\n                \"Command should have been '\" + workspace + \"/virtualenv', but instead it was: '\" + buildTest.commands.get(0)[0] + \"'\");\n        resetVirtualEnvCommands();\n    }\n}"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/constraints/ConstraintCheckerTest.java",
    "content": "package hudson.plugins.performance.constraints;\n\nimport hudson.model.AbstractBuild;\nimport hudson.model.BuildListener;\nimport hudson.model.Result;\nimport hudson.plugins.performance.PerformanceReportMap;\nimport hudson.plugins.performance.actions.PerformanceBuildAction;\nimport hudson.plugins.performance.constraints.AbstractConstraint.Escalation;\nimport hudson.plugins.performance.constraints.AbstractConstraint.Metric;\nimport hudson.plugins.performance.constraints.AbstractConstraint.Operator;\nimport hudson.plugins.performance.constraints.blocks.PreviousResultsBlock;\nimport hudson.plugins.performance.constraints.blocks.TestCaseBlock;\nimport hudson.plugins.performance.data.ConstraintSettings;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.reports.UriReport;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.mockito.InjectMocks;\nimport org.mockito.Mock;\nimport org.mockito.junit.jupiter.MockitoExtension;\n\nimport java.io.IOException;\nimport java.io.PrintStream;\nimport java.lang.reflect.InvocationTargetException;\nimport java.text.ParseException;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Calendar;\nimport java.util.Date;\nimport java.util.GregorianCalendar;\nimport java.util.Iterator;\nimport java.util.List;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\nimport static org.junit.jupiter.api.Assertions.assertFalse;\nimport static org.junit.jupiter.api.Assertions.assertTrue;\nimport static org.mockito.Mockito.when;\n\n@ExtendWith(MockitoExtension.class)\nclass ConstraintCheckerTest {\n\n    @InjectMocks\n    ConstraintChecker constraintChecker = new ConstraintChecker(null, null);\n\n    @InjectMocks\n    ConstraintSettings constraintSettings = new ConstraintSettings(null, false, false, false, 0);\n\n    // @Mock\n    List<AbstractBuild<?, ?>> abstractBuildsList = new ArrayList<AbstractBuild<?, ?>>();\n\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    AbstractBuild<?, ?> abstractBuild0;\n    // needed for check_evaluatePreviousBuilds\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    AbstractBuild<?, ?> abstractBuild1;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    AbstractBuild<?, ?> abstractBuild2;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    AbstractBuild<?, ?> abstractBuild3;\n\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    PerformanceBuildAction performanceBuildAction0;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    PerformanceBuildAction performanceBuildAction1;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    PerformanceBuildAction performanceBuildAction2;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    PerformanceBuildAction performanceBuildAction3;\n\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    PerformanceReportMap performanceReportMap0;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    PerformanceReportMap performanceReportMap1;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    PerformanceReportMap performanceReportMap2;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    PerformanceReportMap performanceReportMap3;\n\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    PerformanceReport performanceReport0_0;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    PerformanceReport performanceReport0_1;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    PerformanceReport performanceReport1_0;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    PerformanceReport performanceReport1_1;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    PerformanceReport performanceReport2_0;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    PerformanceReport performanceReport2_1;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    PerformanceReport performanceReport3_0;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    PerformanceReport performanceReport3_1;\n\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    UriReport uriReport0_0_0;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    UriReport uriReport0_0_1;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    UriReport uriReport0_1_0;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    UriReport uriReport0_1_1;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    UriReport uriReport1_0_0;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    UriReport uriReport1_0_1;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    UriReport uriReport1_1_0;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    UriReport uriReport1_1_1;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    UriReport uriReport2_0_0;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    UriReport uriReport2_0_1;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    UriReport uriReport2_1_0;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    UriReport uriReport2_1_1;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    UriReport uriReport3_0_0;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    UriReport uriReport3_0_1;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    UriReport uriReport3_1_0;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    UriReport uriReport3_1_1;\n\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    BuildListener buildListener;\n\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    PrintStream printStream;\n\n    // Constraints\n    TestCaseBlock ob0;\n    TestCaseBlock ob1;\n    TestCaseBlock ob2;\n    AbsoluteConstraint ac0;\n    AbsoluteConstraint ac1;\n    AbsoluteConstraint ac2;\n    AbsoluteConstraint ac3;\n    AbsoluteConstraint ac4;\n    AbsoluteConstraint ac5;\n    AbsoluteConstraint ac6;\n    PreviousResultsBlock rb0;\n    PreviousResultsBlock rb1;\n    PreviousResultsBlock rb2;\n    PreviousResultsBlock rb3;\n    PreviousResultsBlock rb4;\n    PreviousResultsBlock rb5;\n    PreviousResultsBlock rb6;\n    RelativeConstraint rc0;\n    RelativeConstraint rc1;\n    RelativeConstraint rc2;\n    RelativeConstraint rc3;\n    RelativeConstraint rc4;\n    RelativeConstraint rc5;\n    RelativeConstraint rc6;\n    RelativeConstraint rc7;\n\n    /**\n     * TestCase1 HappyPath - Testing every combination of constraints against some\n     * builds\n     *\n     * @throws InterruptedException\n     * @throws IOException\n     * @throws InvocationTargetException\n     * @throws IllegalAccessException\n     * @throws IllegalArgumentException\n     * @throws NoSuchMethodException\n     * @throws SecurityException\n     * @throws ParseException\n     */\n\n    @Test\n    void happyPathForAbsoluteConstraints()\n            throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException,\n            InvocationTargetException, IOException, InterruptedException, ParseException {\n\n        List<AbstractConstraint> constraints = new ArrayList<AbstractConstraint>();\n        constraints.add(ac0);\n        constraints.add(ac1);\n        constraints.add(ac2);\n        constraints.add(ac3);\n        constraints.add(ac4);\n        constraints.add(ac5);\n        constraints.add(ac6);\n\n        ArrayList<ConstraintEvaluation> result = new ArrayList<ConstraintEvaluation>();\n        result = constraintChecker.checkAllConstraints(constraints);\n\n        assertEquals(7, result.size());\n        assertEquals(ac0, result.get(0).getAbstractConstraint());\n        assertEquals(ac1, result.get(1).getAbstractConstraint());\n        assertEquals(ac2, result.get(2).getAbstractConstraint());\n        assertEquals(ac3, result.get(3).getAbstractConstraint());\n        assertEquals(ac4, result.get(4).getAbstractConstraint());\n        assertEquals(ac5, result.get(5).getAbstractConstraint());\n        assertEquals(ac6, result.get(6).getAbstractConstraint());\n\n        assertTrue(result.get(0).getAbstractConstraint().getSuccess());\n        assertTrue(result.get(4).getAbstractConstraint().getSuccess());\n        assertFalse(result.get(5).getAbstractConstraint().getSuccess());\n\n        assertEquals(100, result.get(0).getConstraintValue(), 0);\n        assertEquals(10, result.get(3).getMeasuredValue(), 0);\n    }\n\n    @Test\n    void happyPathForRelativeConstraints()\n            throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException,\n            InvocationTargetException, IOException, InterruptedException, ParseException {\n\n        List<AbstractConstraint> constraints = new ArrayList<AbstractConstraint>();\n        constraints.add(rc0);\n        constraints.add(rc1);\n        constraints.add(rc2);\n        constraints.add(rc3);\n        constraints.add(rc4);\n        constraints.add(rc5);\n        constraints.add(rc6);\n        constraints.add(rc7);\n\n        ArrayList<ConstraintEvaluation> result = new ArrayList<ConstraintEvaluation>();\n        result = constraintChecker.checkAllConstraints(constraints);\n\n        assertEquals(8, result.size());\n        assertEquals(rc0, result.get(0).getAbstractConstraint());\n        assertEquals(rc1, result.get(1).getAbstractConstraint());\n        assertEquals(rc2, result.get(2).getAbstractConstraint());\n        assertEquals(rc3, result.get(3).getAbstractConstraint());\n        assertEquals(rc4, result.get(4).getAbstractConstraint());\n        assertEquals(rc5, result.get(5).getAbstractConstraint());\n        assertEquals(rc6, result.get(6).getAbstractConstraint());\n        assertEquals(rc7, result.get(7).getAbstractConstraint());\n\n        assertTrue(result.get(0).getAbstractConstraint().getSuccess());\n        assertTrue(result.get(4).getAbstractConstraint().getSuccess());\n        assertTrue(result.get(5).getAbstractConstraint().getSuccess());\n        assertTrue(result.get(6).getAbstractConstraint().getSuccess());\n\n        assertEquals(11, result.get(0).getConstraintValue(), 0);\n        assertEquals(10, result.get(3).getMeasuredValue(), 0);\n    }\n\n    @Test\n    void happyPathForMixedConstraints()\n            throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException,\n            InvocationTargetException, IOException, InterruptedException, ParseException {\n\n        List<AbstractConstraint> constraints = new ArrayList<AbstractConstraint>();\n        constraints.add(rc0);\n        constraints.add(rc1);\n        constraints.add(rc2);\n        constraints.add(ac3);\n        constraints.add(ac4);\n        constraints.add(ac5);\n        constraints.add(rc7);\n\n        ArrayList<ConstraintEvaluation> result = new ArrayList<ConstraintEvaluation>();\n        result = constraintChecker.checkAllConstraints(constraints);\n\n        assertEquals(7, result.size());\n        assertEquals(rc0, result.get(0).getAbstractConstraint());\n        assertEquals(rc1, result.get(1).getAbstractConstraint());\n        assertEquals(rc2, result.get(2).getAbstractConstraint());\n        assertEquals(ac3, result.get(3).getAbstractConstraint());\n        assertEquals(ac4, result.get(4).getAbstractConstraint());\n        assertEquals(ac5, result.get(5).getAbstractConstraint());\n        assertEquals(rc7, result.get(6).getAbstractConstraint());\n\n        assertTrue(result.get(0).getAbstractConstraint().getSuccess());\n        assertTrue(result.get(2).getAbstractConstraint().getSuccess());\n        assertTrue(result.get(4).getAbstractConstraint().getSuccess());\n        assertFalse(result.get(5).getAbstractConstraint().getSuccess());\n\n        assertEquals(11, result.get(2).getConstraintValue(), 0);\n        assertEquals(10, result.get(2).getMeasuredValue(), 0);\n\n        assertEquals(100, result.get(5).getConstraintValue(), 0);\n        assertEquals(10, result.get(5).getMeasuredValue(), 0);\n    }\n\n    @BeforeEach\n    void setUp() {\n        /**\n         * Mock behaviour of the builds\n         */\n        constraintSettings = new ConstraintSettings(buildListener, true, true, true, 3);\n        when(this.buildListener.getLogger()).thenReturn(printStream);\n        constraintChecker = new ConstraintChecker(constraintSettings, abstractBuildsList);\n\n        ob0 = new TestCaseBlock(\"testUri0\");\n        ob1 = new TestCaseBlock(\"testUri1\");\n        ob2 = new TestCaseBlock(null);\n\n        ac0 = new AbsoluteConstraint(Metric.AVERAGE, Operator.NOT_GREATER, \"testResult0.xml\", Escalation.INFORMATION, false,\n                ob0, 100L);\n        ac1 = new AbsoluteConstraint(Metric.ERRORPRC, Operator.NOT_GREATER, \"testResult0.xml\", Escalation.INFORMATION,\n                false, ob1, 100L);\n        ac2 = new AbsoluteConstraint(Metric.LINE90, Operator.NOT_GREATER, \"testResult0.xml\", Escalation.WARNING, false, ob0,\n                100L);\n        ac3 = new AbsoluteConstraint(Metric.MAXIMUM, Operator.NOT_GREATER, \"testResult1.xml\", Escalation.WARNING, false,\n                ob1, 100L);\n        ac4 = new AbsoluteConstraint(Metric.MEDIAN, Operator.NOT_EQUAL, \"testResult1.xml\", Escalation.ERROR, false, ob2,\n                100L);\n        ac4.setSpecifiedTestCase(false);\n        ac5 = new AbsoluteConstraint(Metric.MINIMUM, Operator.NOT_LESS, \"testResult1.xml\", Escalation.ERROR, false, ob2,\n                100L);\n        ac5.setSpecifiedTestCase(false);\n        ac6 = new AbsoluteConstraint(Metric.LINE95, Operator.NOT_GREATER, \"testResult0.xml\", Escalation.WARNING, false, ob0,\n                100L);\n\n        rb0 = new PreviousResultsBlock(\"true\", \"3\", \"\", \"\");\n        rb1 = new PreviousResultsBlock(\"true\", \"*\", \"\", \"\");\n        rb2 = new PreviousResultsBlock(\"false\", \"\", \"2015-01-01 02:00\", \"2015-02-01 23:00\");\n        rb3 = new PreviousResultsBlock(\"false\", \"\", \"2015-01-01\", \"2015-02-01\");\n        rb4 = new PreviousResultsBlock(\"false\", \"\", \"2015-01-01 12:00\", \"2015-02-01\");\n        rb5 = new PreviousResultsBlock(\"false\", \"\", \"2015-01-01\", \"now\");\n        rb6 = new PreviousResultsBlock(\"BASELINE\", \"\", \"\", \"\");\n\n        rc0 = new RelativeConstraint(Metric.AVERAGE, Operator.NOT_GREATER, \"testResult0.xml\", Escalation.INFORMATION, false,\n                ob0, rb0, 10);\n        rc1 = new RelativeConstraint(Metric.ERRORPRC, Operator.NOT_GREATER, \"testResult0.xml\", Escalation.INFORMATION,\n                false, ob1, rb1, 10);\n        rc2 = new RelativeConstraint(Metric.LINE90, Operator.NOT_GREATER, \"testResult0.xml\", Escalation.WARNING, false, ob0,\n                rb2, 10);\n        rc3 = new RelativeConstraint(Metric.MAXIMUM, Operator.NOT_LESS, \"testResult1.xml\", Escalation.WARNING, false, ob1,\n                rb3, 10);\n        rc4 = new RelativeConstraint(Metric.MEDIAN, Operator.NOT_LESS, \"testResult1.xml\", Escalation.ERROR, false, ob2, rb4,\n                10);\n        rc4.setSpecifiedTestCase(false);\n        rc5 = new RelativeConstraint(Metric.MINIMUM, Operator.NOT_LESS, \"testResult1.xml\", Escalation.ERROR, false, ob2,\n                rb5, 10);\n        rc5.setSpecifiedTestCase(false);\n        rc6 = new RelativeConstraint(Metric.AVERAGE, Operator.NOT_GREATER, \"testResult0.xml\", Escalation.INFORMATION, false,\n                ob0, rb0, 10); // same as rc0 but against baseline build\n        rc7 = new RelativeConstraint(Metric.LINE95, Operator.NOT_GREATER, \"testResult0.xml\", Escalation.WARNING, false, ob0,\n                rb2, 10);\n\n        abstractBuildsList.add(abstractBuild0);\n        abstractBuildsList.add(abstractBuild1);\n        abstractBuildsList.add(abstractBuild2);\n        abstractBuildsList.add(abstractBuild3);\n\n        List<PerformanceReport> performanceReportList0 = new ArrayList<PerformanceReport>();\n        performanceReportList0.add(performanceReport0_0);\n        performanceReportList0.add(performanceReport0_1);\n\n        List<PerformanceReport> performanceReportList1 = new ArrayList<PerformanceReport>();\n        performanceReportList1.add(performanceReport1_0);\n        performanceReportList1.add(performanceReport1_1);\n\n        List<PerformanceReport> performanceReportList2 = new ArrayList<PerformanceReport>();\n        performanceReportList2.add(performanceReport2_0);\n        performanceReportList2.add(performanceReport2_1);\n\n        List<PerformanceReport> performanceReportList3 = new ArrayList<PerformanceReport>();\n        performanceReportList3.add(performanceReport3_0);\n        performanceReportList3.add(performanceReport3_1);\n\n        when(this.abstractBuild0.getUrl()).thenReturn(\"abstractBuild0testUrl\");\n        when(this.abstractBuild1.getUrl()).thenReturn(\"abstractBuild1testUrl\");\n        when(this.abstractBuild2.getUrl()).thenReturn(\"abstractBuild2testUrl\");\n        when(this.abstractBuild3.getUrl()).thenReturn(\"abstractBuild3testUrl\");\n\n        when(this.abstractBuild0.getResult()).thenReturn(Result.SUCCESS);\n        when(this.abstractBuild1.getResult()).thenReturn(Result.SUCCESS);\n        when(this.abstractBuild2.getResult()).thenReturn(Result.SUCCESS);\n        when(this.abstractBuild3.getResult()).thenReturn(Result.SUCCESS);\n\n        Calendar calendar = new GregorianCalendar();\n        calendar.setTime(new Date());\n        Calendar calendar1 = new GregorianCalendar(2015, 0, 1, 12, 0, 0);\n        Calendar calendar2 = new GregorianCalendar(2015, 0, 15, 12, 0, 0);\n        Calendar calendar3 = new GregorianCalendar(2015, 1, 1, 12, 0, 0);\n\n        when(this.abstractBuild0.getTimestamp()).thenReturn(calendar);\n        when(this.abstractBuild1.getTimestamp()).thenReturn(calendar1);\n        when(this.abstractBuild2.getTimestamp()).thenReturn(calendar2);\n        when(this.abstractBuild3.getTimestamp()).thenReturn(calendar3);\n\n        when(this.abstractBuild0.getAction(PerformanceBuildAction.class)).thenReturn(performanceBuildAction0);\n        when(this.abstractBuild1.getAction(PerformanceBuildAction.class)).thenReturn(performanceBuildAction1);\n        when(this.abstractBuild2.getAction(PerformanceBuildAction.class)).thenReturn(performanceBuildAction2);\n        when(this.abstractBuild3.getAction(PerformanceBuildAction.class)).thenReturn(performanceBuildAction3);\n\n        when(this.performanceBuildAction0.getPerformanceReportMap()).thenReturn(performanceReportMap0);\n        when(this.performanceBuildAction1.getPerformanceReportMap()).thenReturn(performanceReportMap1);\n        when(this.performanceBuildAction2.getPerformanceReportMap()).thenReturn(performanceReportMap2);\n        when(this.performanceBuildAction3.getPerformanceReportMap()).thenReturn(performanceReportMap3);\n\n        when(this.performanceReportMap0.getPerformanceListOrdered()).thenReturn(performanceReportList0);\n        when(this.performanceReportMap1.getPerformanceListOrdered()).thenReturn(performanceReportList1);\n        when(this.performanceReportMap2.getPerformanceListOrdered()).thenReturn(performanceReportList2);\n        when(this.performanceReportMap3.getPerformanceListOrdered()).thenReturn(performanceReportList3);\n\n        when(this.performanceReportMap0.getPerformanceReport(\"testResult0.xml\")).thenReturn(performanceReport0_0);\n        when(this.performanceReportMap0.getPerformanceReport(\"testResult1.xml\")).thenReturn(performanceReport0_1);\n\n        when(this.performanceReportMap1.getPerformanceReport(\"testResult0.xml\")).thenReturn(performanceReport1_0);\n        when(this.performanceReportMap1.getPerformanceReport(\"testResult1.xml\")).thenReturn(performanceReport1_1);\n\n        when(this.performanceReportMap2.getPerformanceReport(\"testResult0.xml\")).thenReturn(performanceReport2_0);\n        when(this.performanceReportMap2.getPerformanceReport(\"testResult1.xml\")).thenReturn(performanceReport2_1);\n\n        when(this.performanceReportMap3.getPerformanceReport(\"testResult0.xml\")).thenReturn(performanceReport3_0);\n        when(this.performanceReportMap3.getPerformanceReport(\"testResult1.xml\")).thenReturn(performanceReport3_1);\n\n        when(this.performanceReport0_0.getReportFileName()).thenReturn(\"testResult0.xml\");\n        when(this.performanceReport0_1.getReportFileName()).thenReturn(\"testResult1.xml\");\n\n        when(this.performanceReport1_0.getReportFileName()).thenReturn(\"testResult0.xml\");\n        when(this.performanceReport1_1.getReportFileName()).thenReturn(\"testResult1.xml\");\n\n        when(this.performanceReport2_0.getReportFileName()).thenReturn(\"testResult0.xml\");\n        when(this.performanceReport2_1.getReportFileName()).thenReturn(\"testResult1.xml\");\n\n        when(this.performanceReport3_0.getReportFileName()).thenReturn(\"testResult0.xml\");\n        when(this.performanceReport3_1.getReportFileName()).thenReturn(\"testResult1.xml\");\n\n        List<UriReport> uriReportList0_0 = new ArrayList<UriReport>();\n        uriReportList0_0.add(uriReport0_0_0);\n        uriReportList0_0.add(uriReport0_0_1);\n\n        List<UriReport> uriReportList0_1 = new ArrayList<UriReport>();\n        uriReportList0_1.add(uriReport0_1_0);\n        uriReportList0_1.add(uriReport0_1_1);\n\n        List<UriReport> uriReportList1_0 = new ArrayList<UriReport>();\n        uriReportList1_0.add(uriReport1_0_0);\n        uriReportList1_0.add(uriReport1_0_1);\n\n        List<UriReport> uriReportList1_1 = new ArrayList<UriReport>();\n        uriReportList1_1.add(uriReport1_1_0);\n        uriReportList1_1.add(uriReport1_1_1);\n\n        List<UriReport> uriReportList2_0 = new ArrayList<UriReport>();\n        uriReportList2_0.add(uriReport2_0_0);\n        uriReportList2_0.add(uriReport2_0_1);\n\n        List<UriReport> uriReportList2_1 = new ArrayList<UriReport>();\n        uriReportList2_1.add(uriReport2_1_0);\n        uriReportList2_1.add(uriReport2_1_1);\n\n        List<UriReport> uriReportList3_0 = new ArrayList<UriReport>();\n        uriReportList3_0.add(uriReport3_0_0);\n        uriReportList3_0.add(uriReport3_0_1);\n\n        List<UriReport> uriReportList3_1 = new ArrayList<UriReport>();\n        uriReportList3_1.add(uriReport3_1_0);\n        uriReportList3_1.add(uriReport3_1_1);\n\n        when(this.performanceReport0_0.getUriListOrdered()).thenReturn(uriReportList0_0);\n        when(this.performanceReport0_1.getUriListOrdered()).thenReturn(uriReportList0_1);\n\n        when(this.performanceReport1_0.getUriListOrdered()).thenReturn(uriReportList1_0);\n        when(this.performanceReport1_1.getUriListOrdered()).thenReturn(uriReportList1_1);\n\n        when(this.performanceReport2_0.getUriListOrdered()).thenReturn(uriReportList2_0);\n        when(this.performanceReport2_1.getUriListOrdered()).thenReturn(uriReportList2_1);\n\n        when(this.performanceReport3_0.getUriListOrdered()).thenReturn(uriReportList3_0);\n        when(this.performanceReport3_1.getUriListOrdered()).thenReturn(uriReportList3_1);\n\n        when(uriReport0_0_0.getUri()).thenReturn(\"testUri0\");\n        when(uriReport0_0_0.getAverage()).thenReturn((long) 10);\n        when(uriReport0_0_0.errorPercent()).thenReturn((double) 10);\n        when(uriReport0_0_0.get90Line()).thenReturn((long) 10);\n        when(uriReport0_0_0.get95Line()).thenReturn((long) 10);\n        when(uriReport0_0_0.getMax()).thenReturn((long) 10);\n        when(uriReport0_0_0.getMedian()).thenReturn((long) 10);\n        when(uriReport0_0_0.getMin()).thenReturn((long) 10);\n        when(uriReport0_0_0.get95Line()).thenReturn((long) 10);\n\n        when(uriReport0_0_1.getUri()).thenReturn(\"testUri1\");\n        when(uriReport0_0_1.getAverage()).thenReturn((long) 10);\n        when(uriReport0_0_1.errorPercent()).thenReturn((double) 10);\n        when(uriReport0_0_1.get90Line()).thenReturn((long) 10);\n        when(uriReport0_0_1.get95Line()).thenReturn((long) 10);\n        when(uriReport0_0_1.getMax()).thenReturn((long) 10);\n        when(uriReport0_0_1.getMedian()).thenReturn((long) 10);\n        when(uriReport0_0_1.getMin()).thenReturn((long) 10);\n        when(uriReport0_0_1.get95Line()).thenReturn((long) 10);\n\n        when(uriReport0_1_0.getUri()).thenReturn(\"testUri0\");\n        when(uriReport0_1_0.getAverage()).thenReturn((long) 10);\n        when(uriReport0_1_0.errorPercent()).thenReturn((double) 10);\n        when(uriReport0_1_0.get90Line()).thenReturn((long) 10);\n        when(uriReport0_1_0.get95Line()).thenReturn((long) 10);\n        when(uriReport0_1_0.getMax()).thenReturn((long) 10);\n        when(uriReport0_1_0.getMedian()).thenReturn((long) 10);\n        when(uriReport0_1_0.getMin()).thenReturn((long) 10);\n        when(uriReport0_1_0.get95Line()).thenReturn((long) 10);\n\n        when(uriReport0_1_1.getUri()).thenReturn(\"testUri1\");\n        when(uriReport0_1_1.getAverage()).thenReturn((long) 10);\n        when(uriReport0_1_1.errorPercent()).thenReturn((double) 10);\n        when(uriReport0_1_1.get90Line()).thenReturn((long) 10);\n        when(uriReport0_1_1.get95Line()).thenReturn((long) 10);\n        when(uriReport0_1_1.getMax()).thenReturn((long) 10);\n        when(uriReport0_1_1.getMedian()).thenReturn((long) 10);\n        when(uriReport0_1_1.getMin()).thenReturn((long) 10);\n        when(uriReport0_1_1.get95Line()).thenReturn((long) 10);\n\n        when(uriReport1_0_0.getUri()).thenReturn(\"testUri0\");\n        when(uriReport1_0_0.getAverage()).thenReturn((long) 10);\n        when(uriReport1_0_0.errorPercent()).thenReturn((double) 10);\n        when(uriReport1_0_0.get90Line()).thenReturn((long) 10);\n        when(uriReport1_0_0.get95Line()).thenReturn((long) 10);\n        when(uriReport1_0_0.getMax()).thenReturn((long) 10);\n        when(uriReport1_0_0.getMedian()).thenReturn((long) 10);\n        when(uriReport1_0_0.getMin()).thenReturn((long) 10);\n        when(uriReport1_0_0.get95Line()).thenReturn((long) 10);\n\n        when(uriReport1_0_1.getUri()).thenReturn(\"testUri1\");\n        when(uriReport1_0_1.getAverage()).thenReturn((long) 10);\n        when(uriReport1_0_1.errorPercent()).thenReturn((double) 10);\n        when(uriReport1_0_1.get90Line()).thenReturn((long) 10);\n        when(uriReport1_0_1.get95Line()).thenReturn((long) 10);\n        when(uriReport1_0_1.getMax()).thenReturn((long) 10);\n        when(uriReport1_0_1.getMedian()).thenReturn((long) 10);\n        when(uriReport1_0_1.getMin()).thenReturn((long) 10);\n        when(uriReport1_0_1.get95Line()).thenReturn((long) 10);\n\n        when(uriReport1_1_0.getUri()).thenReturn(\"testUri0\");\n        when(uriReport1_1_0.getAverage()).thenReturn((long) 10);\n        when(uriReport1_1_0.errorPercent()).thenReturn((double) 10);\n        when(uriReport1_1_0.get90Line()).thenReturn((long) 10);\n        when(uriReport1_1_0.get95Line()).thenReturn((long) 10);\n        when(uriReport1_1_0.getMax()).thenReturn((long) 10);\n        when(uriReport1_1_0.getMedian()).thenReturn((long) 10);\n        when(uriReport1_1_0.getMin()).thenReturn((long) 10);\n        when(uriReport1_1_0.get95Line()).thenReturn((long) 10);\n\n        when(uriReport1_1_1.getUri()).thenReturn(\"testUri1\");\n        when(uriReport1_1_1.getAverage()).thenReturn((long) 10);\n        when(uriReport1_1_1.errorPercent()).thenReturn((double) 10);\n        when(uriReport1_1_1.get90Line()).thenReturn((long) 10);\n        when(uriReport1_1_1.get95Line()).thenReturn((long) 10);\n        when(uriReport1_1_1.getMax()).thenReturn((long) 10);\n        when(uriReport1_1_1.getMedian()).thenReturn((long) 10);\n        when(uriReport1_1_1.getMin()).thenReturn((long) 10);\n        when(uriReport1_1_1.get95Line()).thenReturn((long) 10);\n\n        when(uriReport2_0_0.getUri()).thenReturn(\"testUri0\");\n        when(uriReport2_0_0.getAverage()).thenReturn((long) 10);\n        when(uriReport2_0_0.errorPercent()).thenReturn((double) 10);\n        when(uriReport2_0_0.get90Line()).thenReturn((long) 10);\n        when(uriReport2_0_0.get95Line()).thenReturn((long) 10);\n        when(uriReport2_0_0.getMax()).thenReturn((long) 10);\n        when(uriReport2_0_0.getMedian()).thenReturn((long) 10);\n        when(uriReport2_0_0.getMin()).thenReturn((long) 10);\n        when(uriReport2_0_0.get95Line()).thenReturn((long) 10);\n\n        when(uriReport2_0_1.getUri()).thenReturn(\"testUri1\");\n        when(uriReport2_0_1.getAverage()).thenReturn((long) 10);\n        when(uriReport2_0_1.errorPercent()).thenReturn((double) 10);\n        when(uriReport2_0_1.get90Line()).thenReturn((long) 10);\n        when(uriReport2_0_1.get95Line()).thenReturn((long) 10);\n        when(uriReport2_0_1.getMax()).thenReturn((long) 10);\n        when(uriReport2_0_1.getMedian()).thenReturn((long) 10);\n        when(uriReport2_0_1.getMin()).thenReturn((long) 10);\n        when(uriReport2_0_1.get95Line()).thenReturn((long) 10);\n\n        when(uriReport2_1_0.getUri()).thenReturn(\"testUri0\");\n        when(uriReport2_1_0.getAverage()).thenReturn((long) 10);\n        when(uriReport2_1_0.errorPercent()).thenReturn((double) 10);\n        when(uriReport2_1_0.get90Line()).thenReturn((long) 10);\n        when(uriReport2_1_0.get95Line()).thenReturn((long) 10);\n        when(uriReport2_1_0.getMax()).thenReturn((long) 10);\n        when(uriReport2_1_0.getMedian()).thenReturn((long) 10);\n        when(uriReport2_1_0.getMin()).thenReturn((long) 10);\n        when(uriReport2_1_0.get95Line()).thenReturn((long) 10);\n\n        when(uriReport2_1_1.getUri()).thenReturn(\"testUri1\");\n        when(uriReport2_1_1.getAverage()).thenReturn((long) 10);\n        when(uriReport2_1_1.errorPercent()).thenReturn((double) 10);\n        when(uriReport2_1_1.get90Line()).thenReturn((long) 10);\n        when(uriReport2_1_1.get95Line()).thenReturn((long) 10);\n        when(uriReport2_1_1.getMax()).thenReturn((long) 10);\n        when(uriReport2_1_1.getMedian()).thenReturn((long) 10);\n        when(uriReport2_1_1.getMin()).thenReturn((long) 10);\n        when(uriReport2_1_1.get95Line()).thenReturn((long) 10);\n\n        when(uriReport3_0_0.getUri()).thenReturn(\"testUri0\");\n        when(uriReport3_0_0.getAverage()).thenReturn((long) 10);\n        when(uriReport3_0_0.errorPercent()).thenReturn((double) 10);\n        when(uriReport3_0_0.get90Line()).thenReturn((long) 10);\n        when(uriReport3_0_0.get95Line()).thenReturn((long) 10);\n        when(uriReport3_0_0.getMax()).thenReturn((long) 10);\n        when(uriReport3_0_0.getMedian()).thenReturn((long) 10);\n        when(uriReport3_0_0.getMin()).thenReturn((long) 10);\n        when(uriReport3_0_0.get95Line()).thenReturn((long) 10);\n\n        when(uriReport3_0_1.getUri()).thenReturn(\"testUri1\");\n        when(uriReport3_0_1.getAverage()).thenReturn((long) 10);\n        when(uriReport3_0_1.errorPercent()).thenReturn((double) 10);\n        when(uriReport3_0_1.get90Line()).thenReturn((long) 10);\n        when(uriReport3_0_1.get95Line()).thenReturn((long) 10);\n        when(uriReport3_0_1.getMax()).thenReturn((long) 10);\n        when(uriReport3_0_1.getMedian()).thenReturn((long) 10);\n        when(uriReport3_0_1.getMin()).thenReturn((long) 10);\n        when(uriReport3_0_1.get95Line()).thenReturn((long) 10);\n\n        when(uriReport3_1_0.getUri()).thenReturn(\"testUri0\");\n        when(uriReport3_1_0.getAverage()).thenReturn((long) 10);\n        when(uriReport3_1_0.errorPercent()).thenReturn((double) 10);\n        when(uriReport3_1_0.get90Line()).thenReturn((long) 10);\n        when(uriReport3_1_0.get95Line()).thenReturn((long) 10);\n        when(uriReport3_1_0.getMax()).thenReturn((long) 10);\n        when(uriReport3_1_0.getMedian()).thenReturn((long) 10);\n        when(uriReport3_1_0.getMin()).thenReturn((long) 10);\n        when(uriReport3_1_0.get95Line()).thenReturn((long) 10);\n\n        when(uriReport3_1_1.getUri()).thenReturn(\"testUri1\");\n        when(uriReport3_1_1.getAverage()).thenReturn((long) 10);\n        when(uriReport3_1_1.errorPercent()).thenReturn((double) 10);\n        when(uriReport3_1_1.get90Line()).thenReturn((long) 10);\n        when(uriReport3_1_1.get95Line()).thenReturn((long) 10);\n        when(uriReport3_1_1.getMax()).thenReturn((long) 10);\n        when(uriReport3_1_1.getMedian()).thenReturn((long) 10);\n        when(uriReport3_1_1.getMin()).thenReturn((long) 10);\n        when(uriReport3_1_1.get95Line()).thenReturn((long) 10);\n\n        /*\n         * Mocking behaviour of performance Reports\n         */\n        when(performanceReport0_0.getAverage()).thenReturn((long) 10);\n        when(performanceReport0_0.errorPercent()).thenReturn((double) 10);\n        when(performanceReport0_0.get90Line()).thenReturn((long) 10);\n        when(performanceReport0_0.get95Line()).thenReturn((long) 10);\n        when(performanceReport0_0.getMax()).thenReturn((long) 10);\n        when(performanceReport0_0.getMedian()).thenReturn((long) 10);\n        when(performanceReport0_0.getMin()).thenReturn((long) 10);\n        when(performanceReport0_0.get95Line()).thenReturn((long) 10);\n\n        when(performanceReport0_1.getAverage()).thenReturn((long) 10);\n        when(performanceReport0_1.errorPercent()).thenReturn((double) 10);\n        when(performanceReport0_1.get90Line()).thenReturn((long) 10);\n        when(performanceReport0_1.get95Line()).thenReturn((long) 10);\n        when(performanceReport0_1.getMax()).thenReturn((long) 10);\n        when(performanceReport0_1.getMedian()).thenReturn((long) 10);\n        when(performanceReport0_1.getMin()).thenReturn((long) 10);\n        when(performanceReport0_1.get95Line()).thenReturn((long) 10);\n\n        when(performanceReport1_0.getAverage()).thenReturn((long) 10);\n        when(performanceReport1_0.errorPercent()).thenReturn((double) 10);\n        when(performanceReport1_0.get90Line()).thenReturn((long) 10);\n        when(performanceReport1_0.get95Line()).thenReturn((long) 10);\n        when(performanceReport1_0.getMax()).thenReturn((long) 10);\n        when(performanceReport1_0.getMedian()).thenReturn((long) 10);\n        when(performanceReport1_0.getMin()).thenReturn((long) 10);\n        when(performanceReport1_0.get95Line()).thenReturn((long) 10);\n\n        when(performanceReport1_1.getAverage()).thenReturn((long) 10);\n        when(performanceReport1_1.errorPercent()).thenReturn((double) 10);\n        when(performanceReport1_1.get90Line()).thenReturn((long) 10);\n        when(performanceReport1_1.get95Line()).thenReturn((long) 10);\n        when(performanceReport1_1.getMax()).thenReturn((long) 10);\n        when(performanceReport1_1.getMedian()).thenReturn((long) 10);\n        when(performanceReport1_1.getMin()).thenReturn((long) 10);\n        when(performanceReport1_1.get95Line()).thenReturn((long) 10);\n\n        when(performanceReport2_0.getAverage()).thenReturn((long) 10);\n        when(performanceReport2_0.errorPercent()).thenReturn((double) 10);\n        when(performanceReport2_0.get90Line()).thenReturn((long) 10);\n        when(performanceReport2_0.get95Line()).thenReturn((long) 10);\n        when(performanceReport2_0.getMax()).thenReturn((long) 10);\n        when(performanceReport2_0.getMedian()).thenReturn((long) 10);\n        when(performanceReport2_0.getMin()).thenReturn((long) 10);\n        when(performanceReport2_0.get95Line()).thenReturn((long) 10);\n\n        when(performanceReport2_1.getAverage()).thenReturn((long) 10);\n        when(performanceReport2_1.errorPercent()).thenReturn((double) 10);\n        when(performanceReport2_1.get90Line()).thenReturn((long) 10);\n        when(performanceReport2_1.get95Line()).thenReturn((long) 10);\n        when(performanceReport2_1.getMax()).thenReturn((long) 10);\n        when(performanceReport2_1.getMedian()).thenReturn((long) 10);\n        when(performanceReport2_1.getMin()).thenReturn((long) 10);\n        when(performanceReport2_1.get95Line()).thenReturn((long) 10);\n\n        when(performanceReport3_0.getAverage()).thenReturn((long) 10);\n        when(performanceReport3_0.errorPercent()).thenReturn((double) 10);\n        when(performanceReport3_0.get90Line()).thenReturn((long) 10);\n        when(performanceReport3_0.get95Line()).thenReturn((long) 10);\n        when(performanceReport3_0.getMax()).thenReturn((long) 10);\n        when(performanceReport3_0.getMedian()).thenReturn((long) 10);\n        when(performanceReport3_0.getMin()).thenReturn((long) 10);\n        when(performanceReport3_0.get95Line()).thenReturn((long) 10);\n\n        when(performanceReport3_1.getAverage()).thenReturn((long) 10);\n        when(performanceReport3_1.errorPercent()).thenReturn((double) 10);\n        when(performanceReport3_1.get90Line()).thenReturn((long) 10);\n        when(performanceReport3_1.get95Line()).thenReturn((long) 10);\n        when(performanceReport3_1.getMax()).thenReturn((long) 10);\n        when(performanceReport3_1.getMedian()).thenReturn((long) 10);\n        when(performanceReport3_1.getMin()).thenReturn((long) 10);\n        when(performanceReport3_1.get95Line()).thenReturn((long) 10);\n    }\n\n    @Test\n    void test() throws Exception {\n        ConstraintChecker checker = new ConstraintChecker(null, null);\n        checker.setSettings(constraintSettings);\n        assertEquals(constraintSettings, checker.getSettings());\n\n        List<AbstractBuild<?, ?>> list = new ArrayList<AbstractBuild<?, ?>>();\n        list.add(abstractBuild0);\n        checker.setBuilds(list);\n\n        assertEquals(list, checker.getBuilds());\n    }\n\n    @Test\n    void generateJunitOutput() throws Exception {\n        List<AbstractConstraint> constraints = new ArrayList<AbstractConstraint>();\n        constraints.add(rc0);\n        constraints.add(rc1);\n        constraints.add(rc2);\n        constraints.add(ac3);\n        constraints.add(ac4);\n        constraints.add(ac5);\n        constraints.add(rc7);\n\n        ArrayList<ConstraintEvaluation> result = new ArrayList<ConstraintEvaluation>();\n        result = constraintChecker.checkAllConstraints(constraints);\n\n        List<String> expectedList = Arrays.asList(\n                \"<testcase classname=\\\"testResult0.xml\\\" name=\\\"Average of testUri0 must not be greater than 10.000 percent above/below previous\\\">\\n</testcase>\\n\",\n                \"<testcase classname=\\\"testResult0.xml\\\" name=\\\"Error % of testUri1 must not be greater than 10.000 percent above/below previous\\\">\\n</testcase>\\n\",\n                \"<testcase classname=\\\"testResult0.xml\\\" name=\\\"90% Line of testUri0 must not be greater than 10.000 percent above/below previous\\\">\\n</testcase>\\n\",\n                \"<testcase classname=\\\"testResult1.xml\\\" name=\\\"Maximum of testUri1 must not be greater than 100 milliseconds\\\">\\n</testcase>\\n\",\n                \"<testcase classname=\\\"testResult1.xml\\\" name=\\\"Median of all test cases must not be equal to 100 milliseconds\\\">\\n</testcase>\\n\",\n                \"<testcase classname=\\\"testResult1.xml\\\" name=\\\"Minimum of all test cases must not be less than 100 milliseconds\\\">\\n    <failure type=\\\"Error\\\">Measured value for Minimum: 10 milliseconds</failure>\\n</testcase>\\n\",\n                \"<testcase classname=\\\"testResult0.xml\\\" name=\\\"95% Line of testUri0 must not be greater than 10.000 percent above/below previous\\\">\\n</testcase>\\n\"\n        );\n\n        Iterator<String> expected = expectedList.iterator();\n        for (ConstraintEvaluation ce : result) {\n            assertEquals(expected.next(), ce.getAbstractConstraint().getJunitResult());\n        }\n    }\n}\n"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/constraints/ConstraintFactoryTest.java",
    "content": "package hudson.plugins.performance.constraints;\n\n\nimport hudson.model.AbstractBuild;\nimport hudson.plugins.performance.PerformanceReportMap;\nimport hudson.plugins.performance.actions.PerformanceBuildAction;\nimport hudson.plugins.performance.constraints.AbstractConstraint.Escalation;\nimport hudson.plugins.performance.constraints.AbstractConstraint.Metric;\nimport hudson.plugins.performance.constraints.AbstractConstraint.Operator;\nimport hudson.plugins.performance.constraints.blocks.PreviousResultsBlock;\nimport hudson.plugins.performance.constraints.blocks.TestCaseBlock;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.reports.UriReport;\nimport org.hamcrest.MatcherAssert;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.mockito.InjectMocks;\nimport org.mockito.Mock;\nimport org.mockito.Mockito;\nimport org.mockito.junit.jupiter.MockitoExtension;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport static org.hamcrest.CoreMatchers.is;\nimport static org.junit.jupiter.api.Assertions.assertNull;\n\n\n@ExtendWith(MockitoExtension.class)\nclass ConstraintFactoryTest {\n\n    private List<AbstractConstraint> constraints1;\n    private List<AbstractConstraint> constraints2;\n\n    @InjectMocks\n    ConstraintFactory constraintFactory;\n\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    AbstractBuild<?, ?> abstractBuild;\n\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    PerformanceBuildAction performanceBuildAction;\n\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    PerformanceReportMap performanceReportMap;\n\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    PerformanceReport performanceReport;\n\n\n    @BeforeEach\n    void setUp() {\n        /**\n         * Creating constraints\n         */\n        TestCaseBlock ob1 = new TestCaseBlock(\"tc1\");\n        TestCaseBlock ob2 = new TestCaseBlock(\"*\");\n        TestCaseBlock ob3 = new TestCaseBlock(\"tc1, tc2, tc3\");\n        PreviousResultsBlock rb = new PreviousResultsBlock(\"true\", \"3\", \"\", \"\");\n\n        AbsoluteConstraint ac1 = new AbsoluteConstraint(Metric.AVERAGE, Operator.NOT_GREATER, \"Result.xml\", Escalation.INFORMATION, true, ob1, 100L);\n        AbsoluteConstraint ac2 = new AbsoluteConstraint(Metric.AVERAGE, Operator.NOT_GREATER, \"Result.xml\", Escalation.INFORMATION, true, ob2, 100L);\n        AbsoluteConstraint ac3 = new AbsoluteConstraint(Metric.AVERAGE, Operator.NOT_GREATER, \"Result.xml\", Escalation.INFORMATION, true, ob3, 100L);\n        AbsoluteConstraint ac4 = new AbsoluteConstraint(Metric.AVERAGE, Operator.NOT_GREATER, \"Result.xml\", Escalation.INFORMATION, true, null, 100L);\n        ac4.setSpecifiedTestCase(false);\n\n        RelativeConstraint rc1 = new RelativeConstraint(Metric.AVERAGE, Operator.NOT_GREATER, \"Result.xml\", Escalation.INFORMATION, true, ob1, rb, 10);\n        RelativeConstraint rc2 = new RelativeConstraint(Metric.AVERAGE, Operator.NOT_GREATER, \"Result.xml\", Escalation.INFORMATION, true, ob2, rb, 10);\n        RelativeConstraint rc3 = new RelativeConstraint(Metric.AVERAGE, Operator.NOT_GREATER, \"Result.xml\", Escalation.INFORMATION, true, ob3, rb, 10);\n        /**\n         * Creating UriReports\n         */\n        List<UriReport> list = new ArrayList<UriReport>();\n        PerformanceReport report = new PerformanceReport(PerformanceReport.DEFAULT_PERCENTILES);\n        UriReport ur1 = new UriReport(report, \"tc1\", \"tc1\");\n        UriReport ur2 = new UriReport(report, \"tc2\", \"tc2\");\n        UriReport ur3 = new UriReport(report, \"tc3\", \"tc3\");\n        UriReport ur4 = new UriReport(report, \"tc4\", \"tc4\");\n        list.add(ur1);\n        list.add(ur2);\n        list.add(ur3);\n        list.add(ur4);\n        /**\n         * Mocking Performance Report\n         */\n        Mockito.when(this.abstractBuild.getAction(PerformanceBuildAction.class)).thenReturn(performanceBuildAction);\n        Mockito.when(this.performanceBuildAction.getPerformanceReportMap()).thenReturn(performanceReportMap);\n        Mockito.when(this.performanceReportMap.getPerformanceReport(Mockito.anyString())).thenReturn(performanceReport);\n        Mockito.when(this.performanceReport.getUriListOrdered()).thenReturn(list);\n\n        // List 1 fill\n        constraints1 = new ArrayList<AbstractConstraint>();\n        constraints1.add(ac1);\n        constraints1.add(ac2);\n        constraints1.add(ac3);\n        constraints1.add(rc1);\n        constraints1.add(rc2);\n        constraints1.add(rc3);\n\n        // List 2 fill\n        constraints2 = new ArrayList<AbstractConstraint>();\n        constraints2.add(ac1);\n        constraints2.add(ac4);\n    }\n\n    @Test\n    void testHappyPath() {\n        /**\n         * Executing method\n         */\n        List<? extends AbstractConstraint> result = this.constraintFactory.createConstraintClones(abstractBuild, constraints1);\n        /**\n         * Check list samplesCount\n         */\n        MatcherAssert.assertThat(result.size(), is(16));\n        /**\n         * Check test cases\n         */\n        MatcherAssert.assertThat(result.get(0).getTestCaseBlock().getTestCase(), is(\"tc1\"));\n        MatcherAssert.assertThat(result.get(1).getTestCaseBlock().getTestCase(), is(\"tc1\"));\n        MatcherAssert.assertThat(result.get(2).getTestCaseBlock().getTestCase(), is(\"tc2\"));\n        MatcherAssert.assertThat(result.get(3).getTestCaseBlock().getTestCase(), is(\"tc3\"));\n        MatcherAssert.assertThat(result.get(4).getTestCaseBlock().getTestCase(), is(\"tc4\"));\n        MatcherAssert.assertThat(result.get(5).getTestCaseBlock().getTestCase(), is(\"tc1\"));\n        MatcherAssert.assertThat(result.get(6).getTestCaseBlock().getTestCase(), is(\"tc2\"));\n        MatcherAssert.assertThat(result.get(7).getTestCaseBlock().getTestCase(), is(\"tc3\"));\n        MatcherAssert.assertThat(result.get(8).getTestCaseBlock().getTestCase(), is(\"tc1\"));\n        MatcherAssert.assertThat(result.get(9).getTestCaseBlock().getTestCase(), is(\"tc1\"));\n        MatcherAssert.assertThat(result.get(10).getTestCaseBlock().getTestCase(), is(\"tc2\"));\n        MatcherAssert.assertThat(result.get(11).getTestCaseBlock().getTestCase(), is(\"tc3\"));\n        MatcherAssert.assertThat(result.get(12).getTestCaseBlock().getTestCase(), is(\"tc4\"));\n        MatcherAssert.assertThat(result.get(13).getTestCaseBlock().getTestCase(), is(\"tc1\"));\n        MatcherAssert.assertThat(result.get(14).getTestCaseBlock().getTestCase(), is(\"tc2\"));\n        MatcherAssert.assertThat(result.get(15).getTestCaseBlock().getTestCase(), is(\"tc3\"));\n    }\n\n    @Test\n    void testOptionalBlock() {\n        /**\n         * Executing method\n         */\n        List<? extends AbstractConstraint> result = this.constraintFactory.createConstraintClones(abstractBuild, constraints2);\n        /**\n         * Checking optional blocks\n         */\n        MatcherAssert.assertThat(result.get(0).getTestCaseBlock().getTestCase(), is(\"tc1\"));\n        MatcherAssert.assertThat(result.get(1).isSpecifiedTestCase(), is(false));\n        assertNull(result.get(1).getTestCaseBlock());\n    }\n}\n"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/constraints/ConstraintTest.java",
    "content": "package hudson.plugins.performance.constraints;\n\nimport hudson.Launcher;\nimport hudson.model.AbstractBuild;\nimport hudson.model.BuildListener;\nimport hudson.model.FreeStyleBuild;\nimport hudson.model.FreeStyleProject;\nimport hudson.model.Result;\nimport hudson.plugins.performance.PerformancePublisher;\nimport hudson.plugins.performance.constraints.AbstractConstraint.Escalation;\nimport hudson.plugins.performance.constraints.AbstractConstraint.Metric;\nimport hudson.plugins.performance.constraints.AbstractConstraint.Operator;\nimport hudson.plugins.performance.constraints.blocks.TestCaseBlock;\nimport org.junit.jupiter.api.Test;\nimport org.jvnet.hudson.test.JenkinsRule;\nimport org.jvnet.hudson.test.TestBuilder;\nimport org.jvnet.hudson.test.junit.jupiter.WithJenkins;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\n\n@WithJenkins\nclass ConstraintTest {\n\n    /**\n     * Testing: Escalation.INFORMATION\n     * Build must stay successful if the value is exceeded.\n     * <p>\n     * Specified value: 1\n     * Calculated average value: 56\n     *\n     * @throws Exception if test encounters errors.\n     */\n    @Test\n    void informationModeDoesntAffectBuildStatus(JenkinsRule j) throws Exception {\n        TestCaseBlock testCaseBlock = new TestCaseBlock(\"listShows\");\n\n        // Value set to 1L to violate constraint. Due to Escalation.INFORMATION the build status must be SUCCESS.\n        AbsoluteConstraint absoluteConstraint = new AbsoluteConstraint(Metric.AVERAGE, Operator.NOT_GREATER, \"testResult.xml\", Escalation.INFORMATION, false, testCaseBlock, 1L);\n\n        List<AbstractConstraint> abstractBuildsList = new ArrayList<AbstractConstraint>();\n        abstractBuildsList.add(absoluteConstraint);\n\n        PerformancePublisher performancePublisher = new PerformancePublisher(\"\", 10, 20, \"\", 0, 0, 0, 0, 0, false, \"\", false, true, false, true,false, null);\n        performancePublisher.setModeEvaluation(true);\n        performancePublisher.setConstraints(abstractBuildsList);\n        performancePublisher.setIgnoreFailedBuilds(false);\n        performancePublisher.setIgnoreUnstableBuilds(false);\n        performancePublisher.setPersistConstraintLog(false);\n        performancePublisher.setFailBuildIfNoResultFile(false);\n\n        FreeStyleProject p = j.createFreeStyleProject(\"informationModeDoesntAffectBuildStatus\");\n        p.getPublishersList().add(performancePublisher);\n        p.getBuildersList().add(new TestBuilder() {\n            @Override\n            public boolean perform(AbstractBuild<?, ?> build,\n                                   Launcher launcher, BuildListener listener)\n                    throws InterruptedException, IOException {\n                build.getWorkspace().child(\"testResult.xml\").copyFrom(getClass().getResource(\"/constraint-test.xml\"));\n                return true;\n            }\n        });\n\n        FreeStyleBuild result = p.scheduleBuild2(0).get();\n        assertEquals(Result.SUCCESS, result.getResult());\n    }\n\n    /**\n     * Testing: Escalation.WARNING\n     * Build must be unstable if the value is exceeded.\n     * <p>\n     * Specified value: 1\n     * Calculated average value: 56\n     *\n     * @throws Exception if test encounters errors.\n     */\n    @Test\n    void warningModeMakesBuildUnstable(JenkinsRule j) throws Exception {\n        TestCaseBlock testCaseBlock = new TestCaseBlock(\"listShows\");\n\n        // Value set to 1L to violate constraint. Due to Escalation.WARNING the build status must be UNSTABLE.\n        AbsoluteConstraint absoluteConstraint = new AbsoluteConstraint(Metric.AVERAGE, Operator.NOT_GREATER, \"testResult.xml\", Escalation.WARNING, false, testCaseBlock, 1L);\n\n        List<AbstractConstraint> abstractBuildsList = new ArrayList<AbstractConstraint>();\n        abstractBuildsList.add(absoluteConstraint);\n\n\n        PerformancePublisher performancePublisher = new PerformancePublisher(\"testResult.xml\", 10, 20, \"\", 0, 0, 0, 0, 0, false, \"\", false, true, false, true,false, null);\n        performancePublisher.setModeEvaluation(true);\n        performancePublisher.setConstraints(abstractBuildsList);\n        performancePublisher.setIgnoreFailedBuilds(false);\n        performancePublisher.setIgnoreUnstableBuilds(false);\n        performancePublisher.setPersistConstraintLog(false);\n\n        FreeStyleProject p = j.createFreeStyleProject(\"warningModeMakesBuildUnstable\");\n        p.getPublishersList().add(performancePublisher);\n        p.getBuildersList().add(new TestBuilder() {\n            @Override\n            public boolean perform(AbstractBuild<?, ?> build,\n                                   Launcher launcher, BuildListener listener)\n                    throws InterruptedException, IOException {\n                build.getWorkspace().child(\"testResult.xml\").copyFrom(getClass().getResource(\"/constraint-test.xml\"));\n                return true;\n            }\n        });\n\n        FreeStyleBuild result = p.scheduleBuild2(0).get();\n        assertEquals(Result.UNSTABLE, result.getResult());\n    }\n\n    /**\n     * Testing: Escalation.ERROR\n     * Build must fail if the value is exceeded.\n     * <p>\n     * Specified value: 1\n     * Calculated average value: 56\n     *\n     * @throws Exception if test encounters errors.\n     */\n    @Test\n    void errorModeMakesBuildFail(JenkinsRule j) throws Exception {\n        TestCaseBlock testCaseBlock = new TestCaseBlock(\"listShows\");\n\n        // Value set to 1L to violate constraint. Due to Escalation.ERROR the build status must be FAILURE.\n        AbsoluteConstraint absoluteConstraint = new AbsoluteConstraint(Metric.AVERAGE, Operator.NOT_GREATER, \"constraint-test.xml\", Escalation.ERROR, false, testCaseBlock, 1L);\n\n        List<AbstractConstraint> abstractBuildsList = new ArrayList<AbstractConstraint>();\n        abstractBuildsList.add(absoluteConstraint);\n\n        PerformancePublisher performancePublisher = new PerformancePublisher(getClass().getResource(\"/constraint-test.xml\").getFile(), 10, 20, \"\", 0, 0, 0, 0, 0, false, \"\", false, true, false, true,false, null);\n        performancePublisher.setModeEvaluation(true);\n        performancePublisher.setConstraints(abstractBuildsList);\n        performancePublisher.setIgnoreFailedBuilds(false);\n        performancePublisher.setIgnoreUnstableBuilds(false);\n        performancePublisher.setPersistConstraintLog(false);\n\n        FreeStyleProject p = j.createFreeStyleProject(\"errorModeMakesBuildFail\");\n        p.getPublishersList().add(performancePublisher);\n        p.getBuildersList().add(new TestBuilder() {\n            @Override\n            public boolean perform(AbstractBuild<?, ?> build,\n                                   Launcher launcher, BuildListener listener)\n                    throws InterruptedException, IOException {\n                build.getWorkspace().child(\"testResult.xml\").copyFrom(getClass().getResource(\"/constraint-test.xml\"));\n                return true;\n            }\n        });\n\n        FreeStyleBuild result = p.scheduleBuild2(0).get();\n        assertEquals(Result.FAILURE, result.getResult());\n    }\n\n    /**\n     * Testing: Operator.NOT_GREATER\n     * Calculated value is equal to specified => Build.SUCCESS\n     * <p>\n     * Specified value: 56\n     * Calculated average value: 56\n     *\n     * @throws Exception if test encounters errors.\n     */\n    @Test\n    void equalValuesWithNotGreaterOperator(JenkinsRule j) throws Exception {\n        TestCaseBlock testCaseBlock = new TestCaseBlock(\"listShows\");\n\n        // The specified value and calculated value are equal.\n        AbsoluteConstraint absoluteConstraint = new AbsoluteConstraint(Metric.AVERAGE, Operator.NOT_GREATER, \"testResult.xml\", Escalation.ERROR, false, testCaseBlock, 56L);\n\n        List<AbstractConstraint> abstractBuildsList = new ArrayList<AbstractConstraint>();\n        abstractBuildsList.add(absoluteConstraint);\n\n        PerformancePublisher performancePublisher = new PerformancePublisher(\"\", 10, 20, \"\", 0, 0, 0, 0, 0, false, \"\", false, true, false, true,false, null);\n        performancePublisher.setModeEvaluation(true);\n        performancePublisher.setConstraints(abstractBuildsList);\n        performancePublisher.setIgnoreFailedBuilds(false);\n        performancePublisher.setIgnoreUnstableBuilds(false);\n        performancePublisher.setPersistConstraintLog(false);\n        performancePublisher.setFailBuildIfNoResultFile(false);\n\n        FreeStyleProject p = j.createFreeStyleProject(\"equalValuesWithNotGreaterOperator\");\n        p.getPublishersList().add(performancePublisher);\n        p.getBuildersList().add(new TestBuilder() {\n            @Override\n            public boolean perform(AbstractBuild<?, ?> build,\n                                   Launcher launcher, BuildListener listener)\n                    throws InterruptedException, IOException {\n                build.getWorkspace().child(\"testResult.xml\").copyFrom(getClass().getResource(\"/constraint-test.xml\"));\n                return true;\n            }\n        });\n\n        FreeStyleBuild result = p.scheduleBuild2(0).get();\n        assertEquals(Result.SUCCESS, result.getResult());\n    }\n\n    /**\n     * Testing: Operator.NOT_GREATER\n     * Calculated value is greater than specified => Build.FAILURE\n     * <p>\n     * Specified value: 55\n     * Calculated average value: 56\n     *\n     * @throws Exception if test encounters errors.\n     */\n    @Test\n    void calculatedValueGreaterWithNotGreaterOperator(JenkinsRule j) throws Exception {\n        TestCaseBlock testCaseBlock = new TestCaseBlock(\"listShows\");\n\n        // The specified should not be exceeded.\n        AbsoluteConstraint absoluteConstraint = new AbsoluteConstraint(Metric.AVERAGE, Operator.NOT_GREATER, \"constraint-test.xml\", Escalation.ERROR, false, testCaseBlock, 55L);\n\n        List<AbstractConstraint> abstractBuildsList = new ArrayList<AbstractConstraint>();\n        abstractBuildsList.add(absoluteConstraint);\n\n        PerformancePublisher performancePublisher = new PerformancePublisher(getClass().getResource(\"/constraint-test.xml\").getFile(), 10, 20, \"\", 0, 0, 0, 0, 0, false, \"\", false, true, false, true,false, null);\n        performancePublisher.setModeEvaluation(true);\n        performancePublisher.setConstraints(abstractBuildsList);\n        performancePublisher.setIgnoreFailedBuilds(false);\n        performancePublisher.setIgnoreUnstableBuilds(false);\n        performancePublisher.setPersistConstraintLog(false);\n\n        FreeStyleProject p = j.createFreeStyleProject(\"calculatedValueGreaterWithNotGreaterOperator\");\n        p.getPublishersList().add(performancePublisher);\n        p.getBuildersList().add(new TestBuilder() {\n            @Override\n            public boolean perform(AbstractBuild<?, ?> build,\n                                   Launcher launcher, BuildListener listener)\n                    throws InterruptedException, IOException {\n                build.getWorkspace().child(\"testResult.xml\").copyFrom(getClass().getResource(\"/constraint-test.xml\"));\n                return true;\n            }\n        });\n\n        FreeStyleBuild result = p.scheduleBuild2(0).get();\n        assertEquals(Result.FAILURE, result.getResult());\n    }\n\n    /**\n     * Testing: Operator.NOT_EQUAL\n     * Calculated value is equal to specified => Build.FAILURE\n     * <p>\n     * Specified value: 56\n     * Calculated average value: 56\n     *\n     * @throws Exception if test encounters errors.\n     */\n    @Test\n    void equalValuesWithNotEqualOperator(JenkinsRule j) throws Exception {\n        TestCaseBlock testCaseBlock = new TestCaseBlock(\"listShows\");\n\n        // The specified value and calculated value are equal.\n        AbsoluteConstraint absoluteConstraint = new AbsoluteConstraint(Metric.AVERAGE, Operator.NOT_EQUAL, \"constraint-test.xml\", Escalation.ERROR, false, testCaseBlock, 56L);\n\n        List<AbstractConstraint> abstractBuildsList = new ArrayList<AbstractConstraint>();\n        abstractBuildsList.add(absoluteConstraint);\n\n        PerformancePublisher performancePublisher = new PerformancePublisher(getClass().getResource(\"/constraint-test.xml\").getFile(), 10, 20, \"\", 0, 0, 0, 0, 0, false, \"\", false, true, false, true,false, null);\n        performancePublisher.setModeEvaluation(true);\n        performancePublisher.setConstraints(abstractBuildsList);\n        performancePublisher.setIgnoreFailedBuilds(false);\n        performancePublisher.setIgnoreUnstableBuilds(false);\n        performancePublisher.setPersistConstraintLog(false);\n\n        FreeStyleProject p = j.createFreeStyleProject(\"equalValuesWithNotEqualOperator\");\n        p.getPublishersList().add(performancePublisher);\n        p.getBuildersList().add(new TestBuilder() {\n            @Override\n            public boolean perform(AbstractBuild<?, ?> build,\n                                   Launcher launcher, BuildListener listener)\n                    throws InterruptedException, IOException {\n                build.getWorkspace().child(\"testResult.xml\").copyFrom(getClass().getResource(\"/constraint-test.xml\"));\n                return true;\n            }\n        });\n\n        FreeStyleBuild result = p.scheduleBuild2(0).get();\n        assertEquals(Result.FAILURE, result.getResult());\n    }\n\n    /**\n     * Testing: Operator.NOT_EQUAL\n     * Calculated value is not equal than specified => Build.SUCCESS\n     * <p>\n     * Specified value: 55\n     * Calculated average value: 56\n     *\n     * @throws Exception if test encounters errors.\n     */\n    @Test\n    void notEqualValueWithNotEqualOperator(JenkinsRule j) throws Exception {\n        TestCaseBlock testCaseBlock = new TestCaseBlock(\"listShows\");\n\n        // The specified should not be exceeded.\n        AbsoluteConstraint absoluteConstraint = new AbsoluteConstraint(Metric.AVERAGE, Operator.NOT_EQUAL, \"testResult.xml\", Escalation.ERROR, false, testCaseBlock, 55L);\n\n        List<AbstractConstraint> abstractBuildsList = new ArrayList<AbstractConstraint>();\n        abstractBuildsList.add(absoluteConstraint);\n\n        PerformancePublisher performancePublisher = new PerformancePublisher(\"\", 10, 20, \"\", 0, 0, 0, 0, 0, false, \"\", false, true, false, true,false, null);\n        performancePublisher.setModeEvaluation(true);\n        performancePublisher.setConstraints(abstractBuildsList);\n        performancePublisher.setIgnoreFailedBuilds(false);\n        performancePublisher.setIgnoreUnstableBuilds(false);\n        performancePublisher.setPersistConstraintLog(false);\n        performancePublisher.setFailBuildIfNoResultFile(false);\n\n        FreeStyleProject p = j.createFreeStyleProject(\"notEqualValueWithNotEqualOperator\");\n        p.getPublishersList().add(performancePublisher);\n        p.getBuildersList().add(new TestBuilder() {\n            @Override\n            public boolean perform(AbstractBuild<?, ?> build,\n                                   Launcher launcher, BuildListener listener)\n                    throws InterruptedException, IOException {\n                build.getWorkspace().child(\"testResult.xml\").copyFrom(getClass().getResource(\"/constraint-test.xml\"));\n                return true;\n            }\n        });\n\n        FreeStyleBuild result = p.scheduleBuild2(0).get();\n        assertEquals(Result.SUCCESS, result.getResult());\n    }\n\n    /**\n     * Testing: Operator.NOT_LESS\n     * Calculated value is equal to specified => Build.SUCCES\n     * <p>\n     * Specified value: 56\n     * Calculated average value: 56\n     *\n     * @throws Exception if test encounters errors.\n     */\n    @Test\n    void equalValuesWithNotLessOperator(JenkinsRule j) throws Exception {\n        TestCaseBlock testCaseBlock = new TestCaseBlock(\"listShows\");\n\n        // The specified value and calculated value are equal.\n        AbsoluteConstraint absoluteConstraint = new AbsoluteConstraint(Metric.AVERAGE, Operator.NOT_LESS, \"testResult.xml\", Escalation.ERROR, false, testCaseBlock, 56L);\n\n        List<AbstractConstraint> abstractBuildsList = new ArrayList<AbstractConstraint>();\n        abstractBuildsList.add(absoluteConstraint);\n\n        PerformancePublisher performancePublisher = new PerformancePublisher(\"\", 10, 20, \"\", 0, 0, 0, 0, 0, false, \"\", false, true, false, true,false, null);\n        performancePublisher.setModeEvaluation(true);\n        performancePublisher.setConstraints(abstractBuildsList);\n        performancePublisher.setIgnoreFailedBuilds(false);\n        performancePublisher.setIgnoreUnstableBuilds(false);\n        performancePublisher.setPersistConstraintLog(false);\n        performancePublisher.setFailBuildIfNoResultFile(false);\n\n        FreeStyleProject p = j.createFreeStyleProject(\"equalValuesWithNotLessOperator\");\n        p.getPublishersList().add(performancePublisher);\n        p.getBuildersList().add(new TestBuilder() {\n            @Override\n            public boolean perform(AbstractBuild<?, ?> build,\n                                   Launcher launcher, BuildListener listener)\n                    throws InterruptedException, IOException {\n                build.getWorkspace().child(\"testResult.xml\").copyFrom(getClass().getResource(\"/constraint-test.xml\"));\n                return true;\n            }\n        });\n\n        FreeStyleBuild result = p.scheduleBuild2(0).get();\n        assertEquals(Result.SUCCESS, result.getResult());\n    }\n\n    /**\n     * Testing: Operator.NOT_LESS\n     * Calculated value is less than specified => Build.FAILURE\n     * <p>\n     * Specified value: 57\n     * Calculated average value: 56\n     *\n     * @throws Exception if test encounters errors.\n     */\n    @Test\n    void calculatedValueLessWithNotLessOperator(JenkinsRule j) throws Exception {\n        TestCaseBlock testCaseBlock = new TestCaseBlock(\"listShows\");\n\n        // The specified should not be exceeded.\n        AbsoluteConstraint absoluteConstraint = new AbsoluteConstraint(Metric.AVERAGE, Operator.NOT_LESS, \"constraint-test.xml\", Escalation.ERROR, false, testCaseBlock, 57L);\n\n        List<AbstractConstraint> abstractBuildsList = new ArrayList<AbstractConstraint>();\n        abstractBuildsList.add(absoluteConstraint);\n\n        PerformancePublisher performancePublisher = new PerformancePublisher(getClass().getResource(\"/constraint-test.xml\").getFile(), 10, 20, \"\", 0, 0, 0, 0, 0, false, \"\", false, true, false, true,false, null);\n        performancePublisher.setModeEvaluation(true);\n        performancePublisher.setConstraints(abstractBuildsList);\n        performancePublisher.setIgnoreFailedBuilds(false);\n        performancePublisher.setIgnoreUnstableBuilds(false);\n        performancePublisher.setPersistConstraintLog(false);\n\n        FreeStyleProject p = j.createFreeStyleProject(\"calculatedValueLessWithNotLessOperator\");\n        p.getPublishersList().add(performancePublisher);\n        p.getBuildersList().add(new TestBuilder() {\n            @Override\n            public boolean perform(AbstractBuild<?, ?> build,\n                                   Launcher launcher, BuildListener listener)\n                    throws InterruptedException, IOException {\n                build.getWorkspace().child(\"testResult.xml\").copyFrom(getClass().getResource(\"/constraint-test.xml\"));\n                return true;\n            }\n        });\n\n        FreeStyleBuild result = p.scheduleBuild2(0).get();\n        assertEquals(Result.FAILURE, result.getResult());\n    }\n}"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/cookie/CookieHandlerTest.java",
    "content": "package hudson.plugins.performance.cookie;\n\n\nimport org.junit.jupiter.api.Test;\nimport org.kohsuke.stapler.Ancestor;\n\nimport javax.servlet.http.Cookie;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\n\nclass CookieHandlerTest {\n\n    @Test\n    void testCookieHandler() throws Exception {\n        CookieHandler cookieHandler = new CookieHandler(\"testCookie\");\n\n        final List<Ancestor> list = new ArrayList<Ancestor>();\n        list.add(new AncestorImpl(\"url1\"));\n        list.add(new AncestorImpl(\"url2\"));\n        list.add(new AncestorImpl(\"url3\"));\n        list.add(new AncestorImpl(\"url4\"));\n\n        final Cookie cookie = cookieHandler.create(list, \"Something value\");\n\n        final String testValue1 = cookieHandler.getValue(new Cookie[] {cookie});\n        assertEquals(\"Something value\", testValue1);\n\n        String testValue2 = cookieHandler.getValue(new Cookie[] {new Cookie(\"otherCookie\", \"some  other value\")});\n        assertEquals(\"\", testValue2);\n    }\n\n    private static class AncestorImpl implements Ancestor {\n        private final String url;\n\n        public AncestorImpl(String url) {\n            this.url = url;\n        }\n        public Object getObject() {\n            return null;\n        }\n        public String getUrl() {\n            return url;\n        }\n        public String getRestOfUrl() {\n            return url;\n        }\n        public String getNextToken(int n) {\n            return null;\n        }\n        public String getFullUrl() {\n            return url;\n        }\n        public String getRelativePath() {\n            return url;\n        }\n        public Ancestor getPrev() {\n            return null;\n        }\n        public Ancestor getNext() {\n            return null;\n        }\n    }\n}"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/data/PerformanceReportPositionTest.java",
    "content": "package hudson.plugins.performance.data;\n\nimport org.junit.jupiter.api.Test;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\n\nclass PerformanceReportPositionTest {\n\n    @Test\n    void test() throws Exception {\n        PerformanceReportPosition position = new PerformanceReportPosition();\n\n        position.setPerformanceReportPosition(\"test1\");\n        position.setSummarizerReportType(\"test2\");\n        position.setSummarizerTrendUri(\"test3\");\n\n        assertEquals(\"test1\", position.getPerformanceReportPosition());\n        assertEquals(\"test2\", position.getSummarizerReportType());\n        assertEquals(\"test3\", position.getSummarizerTrendUri());\n    }\n}"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/data/ReportValueSelectorTest.java",
    "content": "package hudson.plugins.performance.data;\n\nimport hudson.model.AbstractProject;\nimport hudson.plugins.performance.PerformancePublisher;\nimport hudson.plugins.performance.reports.AbstractReport;\nimport hudson.util.DescribableList;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.mockito.Mock;\nimport org.mockito.junit.jupiter.MockitoExtension;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\nimport static org.mockito.Mockito.atLeastOnce;\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.verify;\nimport static org.mockito.Mockito.when;\n\n@ExtendWith(MockitoExtension.class)\nclass ReportValueSelectorTest {\n\n    private static final long VALUE_ART = 1L;\n    private static final long VALUE_MRT = 2L;\n    private static final long VALUE_PRT = 3L;\n\n    @Mock\n    private PerformancePublisher publisher;\n    @Mock(strictness = Mock.Strictness.LENIENT)\n    private AbstractReport report;\n\n    @BeforeEach\n    void setUp() throws Exception {\n        when(report.getAverage()).thenReturn(VALUE_ART);\n        when(report.getMedian()).thenReturn(VALUE_MRT);\n        when(report.get90Line()).thenReturn(VALUE_PRT);\n    }\n\n    @Test\n    void testAverageConfiguration() throws Exception {\n        when(publisher.getGraphType()).thenReturn(PerformancePublisher.ART);\n        ReportValueSelector valueSelector = ReportValueSelector.get(publisher);\n        assertEquals(VALUE_ART, valueSelector.getValue(report));\n        assertEquals(PerformancePublisher.ART, valueSelector.getGraphType());\n    }\n\n    @Test\n    void testMedianConfiguration() throws Exception {\n        when(publisher.getGraphType()).thenReturn(PerformancePublisher.MRT);\n        ReportValueSelector valueSelector = ReportValueSelector.get(publisher);\n        assertEquals(VALUE_MRT, valueSelector.getValue(report));\n        assertEquals(PerformancePublisher.MRT, valueSelector.getGraphType());\n    }\n\n    @Test\n    void testPercentileConfiguration() throws Exception {\n        when(publisher.getGraphType()).thenReturn(PerformancePublisher.PRT);\n        ReportValueSelector valueSelector = ReportValueSelector.get(publisher);\n        assertEquals(VALUE_PRT, valueSelector.getValue(report));\n        assertEquals(PerformancePublisher.PRT, valueSelector.getGraphType());\n    }\n\n    @Test\n    void testFallbackNoPublisher() throws Exception {\n        ReportValueSelector valueSelector = ReportValueSelector.get((PerformancePublisher) null);\n        assertEquals(VALUE_ART, valueSelector.getValue(report));\n        assertEquals(PerformancePublisher.ART, valueSelector.getGraphType());\n    }\n\n    @Test\n    void testFallbackMissingGraphConfig() throws Exception {\n        when(publisher.getGraphType()).thenReturn(null);\n        ReportValueSelector valueSelector = ReportValueSelector.get(publisher);\n        assertEquals(VALUE_ART, valueSelector.getValue(report));\n        assertEquals(PerformancePublisher.ART, valueSelector.getGraphType());\n    }\n\n    @Test\n    @SuppressWarnings(\"unchecked\")\n    void testPublisherSearchedFromAbstractProject() throws Exception {\n        AbstractProject project = mock(AbstractProject.class);\n        DescribableList publishers = mock(DescribableList.class);\n        when(project.getPublishersList()).thenReturn(publishers);\n        when(publishers.get(PerformancePublisher.class)).thenReturn(publisher);\n        when(publisher.getGraphType()).thenReturn(PerformancePublisher.MRT);\n        ReportValueSelector valueSelector = ReportValueSelector.get(project);\n        assertEquals(PerformancePublisher.MRT, valueSelector.getGraphType());\n        verify(publishers, atLeastOnce()).get(PerformancePublisher.class);\n    }\n}\n"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/descriptors/ConstraintDescriptorTest.java",
    "content": "package hudson.plugins.performance.descriptors;\n\nimport hudson.plugins.performance.constraints.AbsoluteConstraint;\nimport hudson.plugins.performance.constraints.RelativeConstraint;\nimport org.junit.jupiter.api.Test;\nimport org.jvnet.hudson.test.JenkinsRule;\nimport org.jvnet.hudson.test.junit.jupiter.WithJenkins;\n\nimport static org.junit.jupiter.api.Assertions.assertInstanceOf;\nimport static org.junit.jupiter.api.Assertions.assertNotNull;\nimport static org.junit.jupiter.api.Assertions.assertNull;\n\n@WithJenkins\nclass ConstraintDescriptorTest {\n\n    @Test\n    void name(JenkinsRule j) throws Exception {\n        ConstraintDescriptor descriptor = ConstraintDescriptor.getById(AbsoluteConstraint.DescriptorImpl.class.getName());\n        assertNotNull(descriptor);\n        assertInstanceOf(AbsoluteConstraint.DescriptorImpl.class, descriptor);\n\n        ConstraintDescriptor descriptor2 = ConstraintDescriptor.getById(RelativeConstraint.DescriptorImpl.class.getName());\n        assertNotNull(descriptor2);\n        assertInstanceOf(RelativeConstraint.DescriptorImpl.class, descriptor2);\n\n        assertNull(ConstraintDescriptor.getById(\"null\"));\n    }\n}"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/descriptors/PerformanceReportParserDescriptorTest.java",
    "content": "package hudson.plugins.performance.descriptors;\n\nimport hudson.plugins.performance.parsers.IagoParser;\nimport hudson.plugins.performance.parsers.JMeterCsvParser;\nimport hudson.plugins.performance.parsers.JMeterParser;\nimport hudson.plugins.performance.parsers.JUnitParser;\nimport hudson.plugins.performance.parsers.JmeterSummarizerParser;\nimport hudson.plugins.performance.parsers.TaurusParser;\nimport hudson.plugins.performance.parsers.WrkSummarizerParser;\nimport org.junit.jupiter.api.Test;\nimport org.jvnet.hudson.test.JenkinsRule;\nimport org.jvnet.hudson.test.junit.jupiter.WithJenkins;\n\nimport static org.junit.jupiter.api.Assertions.assertInstanceOf;\nimport static org.junit.jupiter.api.Assertions.assertNotNull;\nimport static org.junit.jupiter.api.Assertions.assertNull;\n\n@WithJenkins\nclass PerformanceReportParserDescriptorTest {\n\n    @Test\n    void name(JenkinsRule j) throws Exception {\n        PerformanceReportParserDescriptor descriptor = PerformanceReportParserDescriptor.getById(IagoParser.DescriptorImpl.class.getName());\n        assertNotNull(descriptor);\n        assertInstanceOf(IagoParser.DescriptorImpl.class, descriptor);\n\n        PerformanceReportParserDescriptor descriptor2 = PerformanceReportParserDescriptor.getById(JMeterCsvParser.DescriptorImpl.class.getName());\n        assertNotNull(descriptor2);\n        assertInstanceOf(JMeterCsvParser.DescriptorImpl.class, descriptor2);\n\n        PerformanceReportParserDescriptor descriptor3 = PerformanceReportParserDescriptor.getById(JMeterParser.DescriptorImpl.class.getName());\n        assertNotNull(descriptor3);\n        assertInstanceOf(JMeterParser.DescriptorImpl.class, descriptor3);\n\n        PerformanceReportParserDescriptor descriptor4 = PerformanceReportParserDescriptor.getById(JmeterSummarizerParser.DescriptorImpl.class.getName());\n        assertNotNull(descriptor4);\n        assertInstanceOf(JmeterSummarizerParser.DescriptorImpl.class, descriptor4);\n\n        PerformanceReportParserDescriptor descriptor5 = PerformanceReportParserDescriptor.getById(JUnitParser.DescriptorImpl.class.getName());\n        assertNotNull(descriptor5);\n        assertInstanceOf(JUnitParser.DescriptorImpl.class, descriptor5);\n\n\n        PerformanceReportParserDescriptor descriptor6 = PerformanceReportParserDescriptor.getById(TaurusParser.DescriptorImpl.class.getName());\n        assertNotNull(descriptor6);\n        assertInstanceOf(TaurusParser.DescriptorImpl.class, descriptor6);\n\n        PerformanceReportParserDescriptor descriptor7 = PerformanceReportParserDescriptor.getById(WrkSummarizerParser.DescriptorImpl.class.getName());\n        assertNotNull(descriptor7);\n        assertInstanceOf(WrkSummarizerParser.DescriptorImpl.class, descriptor7);\n\n        assertNull(ConstraintDescriptor.getById(\"null\"));\n    }\n}"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/details/GraphConfigurationDetailTest.java",
    "content": "package hudson.plugins.performance.details;\n\nimport hudson.model.FreeStyleProject;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.jvnet.hudson.test.JenkinsRule;\nimport org.jvnet.hudson.test.junit.jupiter.WithJenkins;\nimport org.kohsuke.stapler.StaplerRequest;\nimport org.mockito.Mock;\nimport org.mockito.junit.jupiter.MockitoExtension;\n\nimport java.util.Calendar;\nimport java.util.GregorianCalendar;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\nimport static org.junit.jupiter.api.Assertions.assertFalse;\nimport static org.junit.jupiter.api.Assertions.assertTrue;\n\n@WithJenkins\n@ExtendWith(MockitoExtension.class)\nclass GraphConfigurationDetailTest {\n\n    @Mock\n    private StaplerRequest request;\n\n    @Test\n    void testDefault(JenkinsRule j) throws Exception {\n        FreeStyleProject project = j.createFreeStyleProject(\"testProject\");\n\n        GraphConfigurationDetail detail =\n                new GraphConfigurationDetail(project, \"testPluginName\", request);\n\n        assertEquals(GraphConfigurationDetail.NONE_CONFIG, detail.getConfigType());\n        assertTrue(detail.isNone());\n        assertFalse(detail.isBuildCount());\n        assertFalse(detail.isBuildNth());\n        assertFalse(detail.isDate());\n        assertTrue(detail.isDefaultDates());\n        assertEquals(\"Configure\", detail.getDisplayName());\n\n        assertEquals(0, detail.getBuildCount());\n        detail.setBuildCount(3);\n        assertEquals(3, detail.getBuildCount());\n\n        assertEquals(1, detail.getBuildStep());\n        detail.setBuildStep(5);\n        assertEquals(5, detail.getBuildStep());\n\n        assertEquals(GraphConfigurationDetail.DEFAULT_DATE, detail.getFirstDayCount());\n        assertEquals(GraphConfigurationDetail.DEFAULT_DATE, detail.getLastDayCount());\n        detail.setFirstDayCount(\"testDatePattern\");\n        detail.setLastDayCount(\"testDatePattern\");\n        assertEquals(\"testDatePattern\", detail.getFirstDayCount());\n        assertEquals(\"testDatePattern\", detail.getLastDayCount());\n        assertFalse(detail.isDefaultDates());\n\n        detail.setConfigType(\"TEST_CONFIG_TYPE\");\n        assertEquals(\"TEST_CONFIG_TYPE\", detail.getConfigType());\n    }\n\n    @Test\n    void testCalendar(JenkinsRule j) throws Exception {\n        GregorianCalendar calendar = GraphConfigurationDetail.getGregorianCalendarFromString(\"9/5/2001\");\n\n        assertEquals(2001, calendar.get(GregorianCalendar.YEAR));\n        assertEquals(9, calendar.get(GregorianCalendar.DAY_OF_MONTH));\n        assertEquals(Calendar.MAY, calendar.get(GregorianCalendar.MONTH));\n    }\n}"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/details/TestSuiteReportDetailTest.java",
    "content": "package hudson.plugins.performance.details;\n\nimport hudson.model.Descriptor;\nimport hudson.model.FreeStyleBuild;\nimport hudson.model.FreeStyleProject;\nimport hudson.model.Project;\nimport hudson.model.Run;\nimport hudson.plugins.performance.PerformancePublisher;\nimport hudson.plugins.performance.PerformanceReportMap;\nimport hudson.plugins.performance.actions.PerformanceBuildAction;\nimport hudson.plugins.performance.actions.PerformanceProjectAction;\nimport hudson.plugins.performance.data.HttpSample;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.reports.UriReport;\nimport hudson.tasks.Publisher;\nimport hudson.util.ChartUtil;\nimport hudson.util.DescribableList;\nimport hudson.util.RunList;\nimport org.jfree.data.category.CategoryDataset;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.jvnet.hudson.test.JenkinsRule;\nimport org.jvnet.hudson.test.junit.jupiter.WithJenkins;\nimport org.mockito.Mock;\nimport org.mockito.junit.jupiter.MockitoExtension;\nimport org.mockito.quality.Strictness;\n\nimport java.util.Collections;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\nimport static org.mockito.ArgumentMatchers.anyInt;\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.when;\nimport static org.mockito.Mockito.withSettings;\n\n@WithJenkins\n@ExtendWith(MockitoExtension.class)\npublic class TestSuiteReportDetailTest {\n\n    private static final String TEST_URI = \"myUri\";\n    private static final String FILENAME = \"perf.jtl\";\n\n    @Mock\n    FreeStyleBuild run;\n    @Mock\n    Project<?, ?> project;\n    @Mock\n    PerformancePublisher publisher;\n    @Mock\n    PerformanceReportMap reportMap;\n    @Mock\n    PerformanceBuildAction buildAction;\n    @Mock\n    PerformanceReport report;\n\n    private Map<String, UriReport> uriReportMap = new HashMap<String, UriReport>();\n\n    @BeforeEach\n    void setUp() throws Exception {\n        uriReportMap.put(TEST_URI, getUriReport());\n    }\n\n    private UriReport getUriReport() {\n        UriReport uriReport = new UriReport(report, TEST_URI, TEST_URI);\n        final HttpSample sample1 = new HttpSample();\n        sample1.setSuccessful(true);\n        sample1.setDuration(100);\n        sample1.setDate(new Date(System.currentTimeMillis() - 1000));\n        final HttpSample sample2 = new HttpSample();\n        sample2.setSuccessful(true);\n        sample2.setDuration(1000);\n        sample2.setDate(new Date());\n        uriReport.addHttpSample(sample1);\n        uriReport.addHttpSample(sample2);\n        return uriReport;\n    }\n\n    @Test\n    void chartDatasetHasAverageOfSamples(JenkinsRule j) throws Exception {\n        when(publisher.getGraphType()).thenReturn(PerformancePublisher.ART);\n        assertEquals(550L, getDatasetValue());\n    }\n\n    @Test\n    void chartDatasetHasMedianOfSamples(JenkinsRule j) throws Exception {\n        when(publisher.getGraphType()).thenReturn(PerformancePublisher.MRT);\n        assertEquals(100L, getDatasetValue());\n    }\n\n    private Number getDatasetValue() {\n        DescribableList<Publisher, Descriptor<Publisher>> publishers = new DescribableList<>(project);\n        publishers.add(publisher);\n        run.number = 1;\n        when(run.getAction(PerformanceBuildAction.class)).thenReturn(buildAction);\n        when(project.getPublishersList()).thenReturn(publishers);\n        when(buildAction.getPerformanceReportMap()).thenReturn(reportMap);\n        when(reportMap.getPerformanceReport(FILENAME)).thenReturn(report);\n        when(report.getUriReportMap()).thenReturn(uriReportMap);\n\n        final TestSuiteReportDetail reportDetail = new TestSuiteReportDetail(project, FILENAME, alwaysInRangeMock());\n        final CategoryDataset dataset = reportDetail.getChartDatasetBuilderForBuilds(TEST_URI, RunList.fromRuns(Collections.singletonList(run))).build();\n        return dataset.getValue(TEST_URI, new ChartUtil.NumberOnlyBuildLabel((Run<?, ?>) run));\n    }\n\n    public static PerformanceProjectAction.Range alwaysInRangeMock() {\n        final PerformanceProjectAction.Range mock = mock(PerformanceProjectAction.Range.class, withSettings().strictness(Strictness.LENIENT));\n        when(mock.in(anyInt())).thenReturn(true);\n        when(mock.includedByStep(anyInt())).thenReturn(true);\n        return mock;\n    }\n\n    @Test\n    void testFlow(JenkinsRule j) throws Exception {\n        FreeStyleProject project = j.createFreeStyleProject();\n        project.createExecutable();\n\n        TestSuiteReportDetail reportDetail = new TestSuiteReportDetail(project, \"testFilename\", alwaysInRangeMock());\n\n        assertEquals(\"Test Suite report\", reportDetail.getDisplayName());\n        assertEquals(\"testFilename\", reportDetail.getFilename());\n        assertEquals(project, reportDetail.getProject());\n\n        List<String> list = reportDetail.getPerformanceReportTestCaseList();\n        assertEquals(0, list.size());\n    }\n}"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/parsers/AbstractParserTest.java",
    "content": "package hudson.plugins.performance.parsers;\n\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport org.junit.jupiter.api.Test;\n\nimport java.io.File;\nimport java.util.Map;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\nimport static org.junit.jupiter.api.Assertions.assertNotNull;\n\nclass AbstractParserTest {\n\n    @Test\n    void testDeserialized() throws Exception {\n        File serializedFile = new File(getClass().getResource(\"/results.v.2.0.jtl.serialized\").toURI());\n        String reportFilePath = serializedFile.getAbsolutePath().replace(\".serialized\", \"\");\n        File reportFile = new File(reportFilePath);\n        PerformanceReport report = AbstractParser.loadSerializedReport(reportFile);\n        assertNotNull(report);\n        report = AbstractParser.loadSerializedReport(reportFile); // subsequent calls should be cached\n        assertNotNull(report);\n        assertEquals(2030.47, report.getTotalTrafficInKb(), 0.001, \"totalDuration\");\n        assertEquals(200, report.samplesCount(), \"samples count\");\n    }\n\n    @Test\n    void testUploadOldReport() throws Exception {\n        File serializedFile = new File(getClass().getResource(\"/result.csv.serialized\").toURI());\n        String reportFilePath = serializedFile.getAbsolutePath().replace(\".serialized\", \"\");\n\n        PerformanceReport report = AbstractParser.loadSerializedReport(new File(reportFilePath));\n        assertNotNull(report);\n        Map<Double, Long> percentilesValues = report.getPercentilesValues();\n        assertEquals(5, percentilesValues.size());\n        assertEquals(Long.valueOf(320), percentilesValues.get(50d));\n        assertEquals(Long.valueOf(449), percentilesValues.get(90d));\n        assertEquals(Long.valueOf(455), percentilesValues.get(95d));\n        assertEquals(Long.valueOf(100), percentilesValues.get(0d));\n        assertEquals(Long.valueOf(468), percentilesValues.get(100d));\n\n        assertEquals(320, report.getMedian());\n        assertEquals(449, report.get90Line());\n        assertEquals(455, report.get95Line());\n        assertEquals(100, report.getMin());\n        assertEquals(468, report.getMax());\n    }\n}"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/parsers/IagoParserTest.java",
    "content": "package hudson.plugins.performance.parsers;\n\nimport com.google.gson.Gson;\nimport com.google.gson.GsonBuilder;\nimport hudson.model.FreeStyleBuild;\nimport hudson.plugins.performance.data.HttpSample;\nimport hudson.plugins.performance.parsers.IagoParser.Stats;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.reports.PerformanceReportTest;\nimport org.junit.jupiter.api.Test;\nimport org.jvnet.hudson.test.JenkinsRule;\nimport org.jvnet.hudson.test.junit.jupiter.WithJenkins;\n\nimport java.io.BufferedWriter;\nimport java.io.File;\nimport java.io.FileWriter;\nimport java.io.IOException;\nimport java.text.ParseException;\nimport java.util.Arrays;\nimport java.util.Collection;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\nimport static org.junit.jupiter.api.Assertions.assertFalse;\nimport static org.junit.jupiter.api.Assertions.assertTrue;\n\n@WithJenkins\nclass IagoParserTest {\n\n    @Test\n    void testParseValidLine(JenkinsRule jenkinsRule) throws Exception {\n        IagoParser parser = new IagoParser(null, PerformanceReportTest.DEFAULT_PERCENTILES);\n\n        // Line to parse\n        String line = \"INF [20140611-21:34:01.224] stats: {\\\"400\\\":84,\\\"client\\\\/request_latency_ms_average\\\":3,\\\"client\\\\/request_latency_ms_count\\\":85,\\\"client\\\\/request_latency_ms_maximum\\\":105,\\\"client\\\\/request_latency_ms_minimum\\\":1,\\\"client\\\\/request_latency_ms_p50\\\":2,\\\"client\\\\/request_latency_ms_p90\\\":4,\\\"client\\\\/request_latency_ms_p95\\\":4,\\\"client\\\\/request_latency_ms_p99\\\":105,\\\"client\\\\/request_latency_ms_p999\\\":105,\\\"client\\\\/request_latency_ms_p9999\\\":105,\\\"client\\\\/request_latency_ms_sum\\\":276,\\\"client\\\\/requests\\\":85,\\\"client\\\\/sent_bytes\\\":11919,\\\"client\\\\/socket_unwritable_ms\\\":0,\\\"client\\\\/socket_writable_ms\\\":207,\\\"client\\\\/success\\\":84}\";\n        String key = \"TEST\";\n\n        HttpSample sample = parser.getSample(line, key);\n        assertEquals(105, sample.getSummarizerMax());\n        assertEquals(1, sample.getSummarizerMin());\n        assertEquals(85, sample.getSummarizerSamples());\n        assertEquals((float) 1.0, sample.getSummarizerErrors(), 0.0);\n        assertEquals(3, sample.getDuration());\n        assertEquals(key, sample.getUri());\n    }\n\n    @Test\n    void testParseInvalidLine(JenkinsRule jenkinsRule) throws Exception {\n        IagoParser parser = new IagoParser(\"\", PerformanceReportTest.DEFAULT_PERCENTILES);\n\n        // Valid line to parse\n        String line = \"[20140611-21:34:01.224] stats: {\\\"400\\\":84,\\\"client\\\\/available\\\":1,\\\"client\\\\/cancelled_connects\\\":0,\\\"client\\\\/closechans\\\":85,\\\"client\\\\/closed\\\":85,\\\"client\\\\/closes\\\":84,\\\"client\\\\/codec_connection_preparation_latency_ms_average\\\":3,\\\"client\\\\/codec_connection_preparation_latency_ms_count\\\":85,\\\"client\\\\/codec_connection_preparation_latency_ms_maximum\\\":142,\\\"client\\\\/codec_connection_preparation_latency_ms_minimum\\\":1,\\\"client\\\\/codec_connection_preparation_latency_ms_p50\\\":2,\\\"client\\\\/codec_connection_preparation_latency_ms_p90\\\":4,\\\"client\\\\/codec_connection_preparation_latency_ms_p95\\\":4,\\\"client\\\\/codec_connection_preparation_latency_ms_p99\\\":142,\\\"client\\\\/codec_connection_preparation_latency_ms_p999\\\":142,\\\"client\\\\/codec_connection_preparation_latency_ms_p9999\\\":142,\\\"client\\\\/codec_connection_preparation_latency_ms_sum\\\":316,\\\"client\\\\/connect_latency_ms_average\\\":2,\\\"client\\\\/connect_latency_ms_count\\\":85,\\\"client\\\\/connect_latency_ms_maximum\\\":142,\\\"client\\\\/connect_latency_ms_minimum\\\":0,\\\"client\\\\/connect_latency_ms_p50\\\":1,\\\"client\\\\/connect_latency_ms_p90\\\":2,\\\"client\\\\/connect_latency_ms_p95\\\":4,\\\"client\\\\/connect_latency_ms_p99\\\":142,\\\"client\\\\/connect_latency_ms_p999\\\":142,\\\"client\\\\/connect_latency_ms_p9999\\\":142,\\\"client\\\\/connect_latency_ms_sum\\\":238,\\\"client\\\\/connection_duration_average\\\":5,\\\"client\\\\/connection_duration_count\\\":85,\\\"client\\\\/connection_duration_maximum\\\":173,\\\"client\\\\/connection_duration_minimum\\\":2,\\\"client\\\\/connection_duration_p50\\\":3,\\\"client\\\\/connection_duration_p90\\\":6,\\\"client\\\\/connection_duration_p95\\\":7,\\\"client\\\\/connection_duration_p99\\\":173,\\\"client\\\\/connection_duration_p999\\\":173,\\\"client\\\\/connection_duration_p9999\\\":173,\\\"client\\\\/connection_duration_sum\\\":477,\\\"client\\\\/connection_received_bytes_average\\\":604,\\\"client\\\\/connection_received_bytes_count\\\":85,\\\"client\\\\/connection_received_bytes_maximum\\\":576,\\\"client\\\\/connection_received_bytes_minimum\\\":576,\\\"client\\\\/connection_received_bytes_p50\\\":576,\\\"client\\\\/connection_received_bytes_p90\\\":576,\\\"client\\\\/connection_received_bytes_p95\\\":576,\\\"client\\\\/connection_received_bytes_p99\\\":576,\\\"client\\\\/connection_received_bytes_p999\\\":576,\\\"client\\\\/connection_received_bytes_p9999\\\":576,\\\"client\\\\/connection_received_bytes_sum\\\":51340,\\\"client\\\\/connection_requests_average\\\":1,\\\"client\\\\/connection_requests_count\\\":85,\\\"client\\\\/connection_requests_maximum\\\":1,\\\"client\\\\/connection_requests_minimum\\\":1,\\\"client\\\\/connection_requests_p50\\\":1,\\\"client\\\\/connection_requests_p90\\\":1,\\\"client\\\\/connection_requests_p95\\\":1,\\\"client\\\\/connection_requests_p99\\\":1,\\\"client\\\\/connection_requests_p999\\\":1,\\\"client\\\\/connection_requests_p9999\\\":1,\\\"client\\\\/connection_requests_sum\\\":85,\\\"client\\\\/connection_sent_bytes_average\\\":140,\\\"client\\\\/connection_sent_bytes_count\\\":85,\\\"client\\\\/connection_sent_bytes_maximum\\\":142,\\\"client\\\\/connection_sent_bytes_minimum\\\":142,\\\"client\\\\/connection_sent_bytes_p50\\\":142,\\\"client\\\\/connection_sent_bytes_p90\\\":142,\\\"client\\\\/connection_sent_bytes_p95\\\":142,\\\"client\\\\/connection_sent_bytes_p99\\\":142,\\\"client\\\\/connection_sent_bytes_p999\\\":142,\\\"client\\\\/connection_sent_bytes_p9999\\\":142,\\\"client\\\\/connection_sent_bytes_sum\\\":11919,\\\"client\\\\/connections\\\":0,\\\"client\\\\/connects\\\":85,\\\"client\\\\/failed_connect_latency_ms_count\\\":0,\\\"client\\\\/failfast\\\":0,\\\"client\\\\/failfast\\\\/unhealthy_for_ms\\\":0,\\\"client\\\\/failfast\\\\/unhealthy_num_tries\\\":0,\\\"client\\\\/failures\\\":1,\\\"client\\\\/failures\\\\/com.twitter.finagle.ChannelClosedException\\\":1,\\\"client\\\\/idle\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/available\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/cancelled_connects\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/closechans\\\":85,\\\"client\\\\/jonatstr-dt-otc_80\\\\/closed\\\":85,\\\"client\\\\/jonatstr-dt-otc_80\\\\/closes\\\":84,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connect_latency_ms_average\\\":2,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connect_latency_ms_count\\\":85,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connect_latency_ms_maximum\\\":142,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connect_latency_ms_minimum\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connect_latency_ms_p50\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connect_latency_ms_p90\\\":2,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connect_latency_ms_p95\\\":4,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connect_latency_ms_p99\\\":142,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connect_latency_ms_p999\\\":142,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connect_latency_ms_p9999\\\":142,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connect_latency_ms_sum\\\":238,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_duration_average\\\":5,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_duration_count\\\":85,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_duration_maximum\\\":173,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_duration_minimum\\\":2,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_duration_p50\\\":3,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_duration_p90\\\":6,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_duration_p95\\\":7,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_duration_p99\\\":173,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_duration_p999\\\":173,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_duration_p9999\\\":173,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_duration_sum\\\":477,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_received_bytes_average\\\":604,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_received_bytes_count\\\":85,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_received_bytes_maximum\\\":576,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_received_bytes_minimum\\\":576,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_received_bytes_p50\\\":576,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_received_bytes_p90\\\":576,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_received_bytes_p95\\\":576,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_received_bytes_p99\\\":576,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_received_bytes_p999\\\":576,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_received_bytes_p9999\\\":576,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_received_bytes_sum\\\":51340,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_requests_average\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_requests_count\\\":85,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_requests_maximum\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_requests_minimum\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_requests_p50\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_requests_p90\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_requests_p95\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_requests_p99\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_requests_p999\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_requests_p9999\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_requests_sum\\\":85,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_sent_bytes_average\\\":140,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_sent_bytes_count\\\":85,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_sent_bytes_maximum\\\":142,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_sent_bytes_minimum\\\":142,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_sent_bytes_p50\\\":142,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_sent_bytes_p90\\\":142,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_sent_bytes_p95\\\":142,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_sent_bytes_p99\\\":142,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_sent_bytes_p999\\\":142,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_sent_bytes_p9999\\\":142,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_sent_bytes_sum\\\":11919,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connections\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connects\\\":85,\\\"client\\\\/jonatstr-dt-otc_80\\\\/failed_connect_latency_ms_count\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/failfast\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/failfast\\\\/unhealthy_for_ms\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/failfast\\\\/unhealthy_num_tries\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/failures\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/failures\\\\/com.twitter.finagle.ChannelClosedException\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/idle\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/lifetime\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/load\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/pending\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/pool_cached\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/pool_num_waited\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/pool_size\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/pool_waiters\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/received_bytes\\\":51340,\\\"client\\\\/jonatstr-dt-otc_80\\\\/request_latency_ms_average\\\":3,\\\"client\\\\/jonatstr-dt-otc_80\\\\/request_latency_ms_count\\\":85,\\\"client\\\\/jonatstr-dt-otc_80\\\\/request_latency_ms_maximum\\\":105,\\\"client\\\\/jonatstr-dt-otc_80\\\\/request_latency_ms_minimum\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/request_latency_ms_p50\\\":2,\\\"client\\\\/jonatstr-dt-otc_80\\\\/request_latency_ms_p90\\\":4,\\\"client\\\\/jonatstr-dt-otc_80\\\\/request_latency_ms_p95\\\":4,\\\"client\\\\/jonatstr-dt-otc_80\\\\/request_latency_ms_p99\\\":105,\\\"client\\\\/jonatstr-dt-otc_80\\\\/request_latency_ms_p999\\\":105,\\\"client\\\\/jonatstr-dt-otc_80\\\\/request_latency_ms_p9999\\\":105,\\\"client\\\\/jonatstr-dt-otc_80\\\\/request_latency_ms_sum\\\":276,\\\"client\\\\/jonatstr-dt-otc_80\\\\/requests\\\":85,\\\"client\\\\/jonatstr-dt-otc_80\\\\/sent_bytes\\\":11919,\\\"client\\\\/jonatstr-dt-otc_80\\\\/socket_unwritable_ms\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/socket_writable_ms\\\":207,\\\"client\\\\/jonatstr-dt-otc_80\\\\/success\\\":84,\\\"client\\\\/lifetime\\\":0,\\\"client\\\\/load\\\":0,\\\"client\\\\/loadbalancer\\\\/adds\\\":0,\\\"client\\\\/loadbalancer\\\\/available\\\":1,\\\"client\\\\/loadbalancer\\\\/load\\\":0,\\\"client\\\\/loadbalancer\\\\/removes\\\":0,\\\"client\\\\/loadbalancer\\\\/size\\\":1,\\\"client\\\\/pending\\\":0,\\\"client\\\\/pool_cached\\\":0,\\\"client\\\\/pool_num_waited\\\":0,\\\"client\\\\/pool_size\\\":0,\\\"client\\\\/pool_waiters\\\":0,\\\"client\\\\/received_bytes\\\":51340,\\\"client\\\\/request_latency_ms_average\\\":3,\\\"client\\\\/request_latency_ms_count\\\":85,\\\"client\\\\/request_latency_ms_maximum\\\":105,\\\"client\\\\/request_latency_ms_minimum\\\":1,\\\"client\\\\/request_latency_ms_p50\\\":2,\\\"client\\\\/request_latency_ms_p90\\\":4,\\\"client\\\\/request_latency_ms_p95\\\":4,\\\"client\\\\/request_latency_ms_p99\\\":105,\\\"client\\\\/request_latency_ms_p999\\\":105,\\\"client\\\\/request_latency_ms_p9999\\\":105,\\\"client\\\\/request_latency_ms_sum\\\":276,\\\"client\\\\/requests\\\":85,\\\"client\\\\/sent_bytes\\\":11919,\\\"client\\\\/socket_unwritable_ms\\\":0,\\\"client\\\\/socket_writable_ms\\\":207,\\\"client\\\\/success\\\":84,\\\"clock_error\\\":0,\\\"jvm_buffer_direct_count\\\":4,\\\"jvm_buffer_direct_max\\\":133120,\\\"jvm_buffer_direct_used\\\":133120,\\\"jvm_buffer_mapped_count\\\":0,\\\"jvm_buffer_mapped_max\\\":0,\\\"jvm_buffer_mapped_used\\\":0,\\\"jvm_current_mem_CMS_Old_Gen_max\\\":3657433088,\\\"jvm_current_mem_CMS_Old_Gen_used\\\":12173984,\\\"jvm_current_mem_CMS_Perm_Gen_max\\\":85983232,\\\"jvm_current_mem_CMS_Perm_Gen_used\\\":44355376,\\\"jvm_current_mem_Code_Cache_max\\\":50331648,\\\"jvm_current_mem_Code_Cache_used\\\":2425792,\\\"jvm_current_mem_Eden_Space_max\\\":429522944,\\\"jvm_current_mem_Eden_Space_used\\\":169518376,\\\"jvm_current_mem_Survivor_Space_max\\\":53673984,\\\"jvm_current_mem_Survivor_Space_used\\\":53673984,\\\"jvm_current_mem_used\\\":282147512,\\\"jvm_fd_count\\\":142,\\\"jvm_fd_limit\\\":4096,\\\"jvm_gc_ConcurrentMarkSweep_cycles\\\":0,\\\"jvm_gc_ConcurrentMarkSweep_msec\\\":0,\\\"jvm_gc_Copy_cycles\\\":0,\\\"jvm_gc_Copy_msec\\\":0,\\\"jvm_gc_cycles\\\":0,\\\"jvm_gc_msec\\\":0,\\\"jvm_heap_committed\\\":4140630016,\\\"jvm_heap_max\\\":4140630016,\\\"jvm_heap_used\\\":235366344,\\\"jvm_nonheap_committed\\\":47120384,\\\"jvm_nonheap_max\\\":136314880,\\\"jvm_nonheap_used\\\":46777704,\\\"jvm_num_cpus\\\":1,\\\"jvm_post_gc_CMS_Old_Gen_max\\\":3657433088,\\\"jvm_post_gc_CMS_Old_Gen_used\\\":0,\\\"jvm_post_gc_CMS_Perm_Gen_max\\\":85983232,\\\"jvm_post_gc_CMS_Perm_Gen_used\\\":0,\\\"jvm_post_gc_Eden_Space_max\\\":429522944,\\\"jvm_post_gc_Eden_Space_used\\\":0,\\\"jvm_post_gc_Survivor_Space_max\\\":53673984,\\\"jvm_post_gc_Survivor_Space_used\\\":53673984,\\\"jvm_post_gc_used\\\":53673984,\\\"jvm_start_time\\\":1402536778818,\\\"jvm_thread_count\\\":18,\\\"jvm_thread_daemon_count\\\":12,\\\"jvm_thread_peak_count\\\":18,\\\"jvm_uptime\\\":62216,\\\"queue_depth\\\":41,\\\"records-read\\\":126,\\\"requests_sent\\\":85,\\\"service\\\":\\\"parrot_web\\\",\\\"source\\\":\\\"jonatstr-dt-oneconnector\\\",\\\"timestamp\\\":1402536841,\\\"unexpected_error\\\":1,\\\"unexpected_error\\\\/com.twitter.finagle.ChannelClosedException\\\":1}\";\n        String key = \"TEST\";\n\n        boolean exceptionFound = false;\n        try {\n            parser.getSample(line, key);\n        } catch (ParseException e) {\n            exceptionFound = true;\n        }\n\n        assertTrue(exceptionFound);\n\n    }\n\n    @Test\n    void testParseInvalidDate(JenkinsRule jenkinsRule) throws Exception {\n        IagoParser parser = new IagoParser(\"\", PerformanceReportTest.DEFAULT_PERCENTILES);\n\n        // Line to parse\n        String line = \"INF [20140611+21:34:01.224] stats: {\\\"400\\\":84,\\\"client\\\\/available\\\":1,\\\"client\\\\/cancelled_connects\\\":0,\\\"client\\\\/closechans\\\":85,\\\"client\\\\/closed\\\":85,\\\"client\\\\/closes\\\":84,\\\"client\\\\/codec_connection_preparation_latency_ms_average\\\":3,\\\"client\\\\/codec_connection_preparation_latency_ms_count\\\":85,\\\"client\\\\/codec_connection_preparation_latency_ms_maximum\\\":142,\\\"client\\\\/codec_connection_preparation_latency_ms_minimum\\\":1,\\\"client\\\\/codec_connection_preparation_latency_ms_p50\\\":2,\\\"client\\\\/codec_connection_preparation_latency_ms_p90\\\":4,\\\"client\\\\/codec_connection_preparation_latency_ms_p95\\\":4,\\\"client\\\\/codec_connection_preparation_latency_ms_p99\\\":142,\\\"client\\\\/codec_connection_preparation_latency_ms_p999\\\":142,\\\"client\\\\/codec_connection_preparation_latency_ms_p9999\\\":142,\\\"client\\\\/codec_connection_preparation_latency_ms_sum\\\":316,\\\"client\\\\/connect_latency_ms_average\\\":2,\\\"client\\\\/connect_latency_ms_count\\\":85,\\\"client\\\\/connect_latency_ms_maximum\\\":142,\\\"client\\\\/connect_latency_ms_minimum\\\":0,\\\"client\\\\/connect_latency_ms_p50\\\":1,\\\"client\\\\/connect_latency_ms_p90\\\":2,\\\"client\\\\/connect_latency_ms_p95\\\":4,\\\"client\\\\/connect_latency_ms_p99\\\":142,\\\"client\\\\/connect_latency_ms_p999\\\":142,\\\"client\\\\/connect_latency_ms_p9999\\\":142,\\\"client\\\\/connect_latency_ms_sum\\\":238,\\\"client\\\\/connection_duration_average\\\":5,\\\"client\\\\/connection_duration_count\\\":85,\\\"client\\\\/connection_duration_maximum\\\":173,\\\"client\\\\/connection_duration_minimum\\\":2,\\\"client\\\\/connection_duration_p50\\\":3,\\\"client\\\\/connection_duration_p90\\\":6,\\\"client\\\\/connection_duration_p95\\\":7,\\\"client\\\\/connection_duration_p99\\\":173,\\\"client\\\\/connection_duration_p999\\\":173,\\\"client\\\\/connection_duration_p9999\\\":173,\\\"client\\\\/connection_duration_sum\\\":477,\\\"client\\\\/connection_received_bytes_average\\\":604,\\\"client\\\\/connection_received_bytes_count\\\":85,\\\"client\\\\/connection_received_bytes_maximum\\\":576,\\\"client\\\\/connection_received_bytes_minimum\\\":576,\\\"client\\\\/connection_received_bytes_p50\\\":576,\\\"client\\\\/connection_received_bytes_p90\\\":576,\\\"client\\\\/connection_received_bytes_p95\\\":576,\\\"client\\\\/connection_received_bytes_p99\\\":576,\\\"client\\\\/connection_received_bytes_p999\\\":576,\\\"client\\\\/connection_received_bytes_p9999\\\":576,\\\"client\\\\/connection_received_bytes_sum\\\":51340,\\\"client\\\\/connection_requests_average\\\":1,\\\"client\\\\/connection_requests_count\\\":85,\\\"client\\\\/connection_requests_maximum\\\":1,\\\"client\\\\/connection_requests_minimum\\\":1,\\\"client\\\\/connection_requests_p50\\\":1,\\\"client\\\\/connection_requests_p90\\\":1,\\\"client\\\\/connection_requests_p95\\\":1,\\\"client\\\\/connection_requests_p99\\\":1,\\\"client\\\\/connection_requests_p999\\\":1,\\\"client\\\\/connection_requests_p9999\\\":1,\\\"client\\\\/connection_requests_sum\\\":85,\\\"client\\\\/connection_sent_bytes_average\\\":140,\\\"client\\\\/connection_sent_bytes_count\\\":85,\\\"client\\\\/connection_sent_bytes_maximum\\\":142,\\\"client\\\\/connection_sent_bytes_minimum\\\":142,\\\"client\\\\/connection_sent_bytes_p50\\\":142,\\\"client\\\\/connection_sent_bytes_p90\\\":142,\\\"client\\\\/connection_sent_bytes_p95\\\":142,\\\"client\\\\/connection_sent_bytes_p99\\\":142,\\\"client\\\\/connection_sent_bytes_p999\\\":142,\\\"client\\\\/connection_sent_bytes_p9999\\\":142,\\\"client\\\\/connection_sent_bytes_sum\\\":11919,\\\"client\\\\/connections\\\":0,\\\"client\\\\/connects\\\":85,\\\"client\\\\/failed_connect_latency_ms_count\\\":0,\\\"client\\\\/failfast\\\":0,\\\"client\\\\/failfast\\\\/unhealthy_for_ms\\\":0,\\\"client\\\\/failfast\\\\/unhealthy_num_tries\\\":0,\\\"client\\\\/failures\\\":1,\\\"client\\\\/failures\\\\/com.twitter.finagle.ChannelClosedException\\\":1,\\\"client\\\\/idle\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/available\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/cancelled_connects\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/closechans\\\":85,\\\"client\\\\/jonatstr-dt-otc_80\\\\/closed\\\":85,\\\"client\\\\/jonatstr-dt-otc_80\\\\/closes\\\":84,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connect_latency_ms_average\\\":2,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connect_latency_ms_count\\\":85,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connect_latency_ms_maximum\\\":142,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connect_latency_ms_minimum\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connect_latency_ms_p50\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connect_latency_ms_p90\\\":2,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connect_latency_ms_p95\\\":4,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connect_latency_ms_p99\\\":142,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connect_latency_ms_p999\\\":142,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connect_latency_ms_p9999\\\":142,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connect_latency_ms_sum\\\":238,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_duration_average\\\":5,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_duration_count\\\":85,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_duration_maximum\\\":173,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_duration_minimum\\\":2,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_duration_p50\\\":3,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_duration_p90\\\":6,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_duration_p95\\\":7,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_duration_p99\\\":173,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_duration_p999\\\":173,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_duration_p9999\\\":173,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_duration_sum\\\":477,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_received_bytes_average\\\":604,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_received_bytes_count\\\":85,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_received_bytes_maximum\\\":576,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_received_bytes_minimum\\\":576,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_received_bytes_p50\\\":576,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_received_bytes_p90\\\":576,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_received_bytes_p95\\\":576,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_received_bytes_p99\\\":576,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_received_bytes_p999\\\":576,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_received_bytes_p9999\\\":576,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_received_bytes_sum\\\":51340,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_requests_average\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_requests_count\\\":85,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_requests_maximum\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_requests_minimum\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_requests_p50\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_requests_p90\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_requests_p95\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_requests_p99\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_requests_p999\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_requests_p9999\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_requests_sum\\\":85,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_sent_bytes_average\\\":140,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_sent_bytes_count\\\":85,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_sent_bytes_maximum\\\":142,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_sent_bytes_minimum\\\":142,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_sent_bytes_p50\\\":142,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_sent_bytes_p90\\\":142,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_sent_bytes_p95\\\":142,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_sent_bytes_p99\\\":142,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_sent_bytes_p999\\\":142,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_sent_bytes_p9999\\\":142,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connection_sent_bytes_sum\\\":11919,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connections\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/connects\\\":85,\\\"client\\\\/jonatstr-dt-otc_80\\\\/failed_connect_latency_ms_count\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/failfast\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/failfast\\\\/unhealthy_for_ms\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/failfast\\\\/unhealthy_num_tries\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/failures\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/failures\\\\/com.twitter.finagle.ChannelClosedException\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/idle\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/lifetime\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/load\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/pending\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/pool_cached\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/pool_num_waited\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/pool_size\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/pool_waiters\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/received_bytes\\\":51340,\\\"client\\\\/jonatstr-dt-otc_80\\\\/request_latency_ms_average\\\":3,\\\"client\\\\/jonatstr-dt-otc_80\\\\/request_latency_ms_count\\\":85,\\\"client\\\\/jonatstr-dt-otc_80\\\\/request_latency_ms_maximum\\\":105,\\\"client\\\\/jonatstr-dt-otc_80\\\\/request_latency_ms_minimum\\\":1,\\\"client\\\\/jonatstr-dt-otc_80\\\\/request_latency_ms_p50\\\":2,\\\"client\\\\/jonatstr-dt-otc_80\\\\/request_latency_ms_p90\\\":4,\\\"client\\\\/jonatstr-dt-otc_80\\\\/request_latency_ms_p95\\\":4,\\\"client\\\\/jonatstr-dt-otc_80\\\\/request_latency_ms_p99\\\":105,\\\"client\\\\/jonatstr-dt-otc_80\\\\/request_latency_ms_p999\\\":105,\\\"client\\\\/jonatstr-dt-otc_80\\\\/request_latency_ms_p9999\\\":105,\\\"client\\\\/jonatstr-dt-otc_80\\\\/request_latency_ms_sum\\\":276,\\\"client\\\\/jonatstr-dt-otc_80\\\\/requests\\\":85,\\\"client\\\\/jonatstr-dt-otc_80\\\\/sent_bytes\\\":11919,\\\"client\\\\/jonatstr-dt-otc_80\\\\/socket_unwritable_ms\\\":0,\\\"client\\\\/jonatstr-dt-otc_80\\\\/socket_writable_ms\\\":207,\\\"client\\\\/jonatstr-dt-otc_80\\\\/success\\\":84,\\\"client\\\\/lifetime\\\":0,\\\"client\\\\/load\\\":0,\\\"client\\\\/loadbalancer\\\\/adds\\\":0,\\\"client\\\\/loadbalancer\\\\/available\\\":1,\\\"client\\\\/loadbalancer\\\\/load\\\":0,\\\"client\\\\/loadbalancer\\\\/removes\\\":0,\\\"client\\\\/loadbalancer\\\\/size\\\":1,\\\"client\\\\/pending\\\":0,\\\"client\\\\/pool_cached\\\":0,\\\"client\\\\/pool_num_waited\\\":0,\\\"client\\\\/pool_size\\\":0,\\\"client\\\\/pool_waiters\\\":0,\\\"client\\\\/received_bytes\\\":51340,\\\"client\\\\/request_latency_ms_average\\\":3,\\\"client\\\\/request_latency_ms_count\\\":85,\\\"client\\\\/request_latency_ms_maximum\\\":105,\\\"client\\\\/request_latency_ms_minimum\\\":1,\\\"client\\\\/request_latency_ms_p50\\\":2,\\\"client\\\\/request_latency_ms_p90\\\":4,\\\"client\\\\/request_latency_ms_p95\\\":4,\\\"client\\\\/request_latency_ms_p99\\\":105,\\\"client\\\\/request_latency_ms_p999\\\":105,\\\"client\\\\/request_latency_ms_p9999\\\":105,\\\"client\\\\/request_latency_ms_sum\\\":276,\\\"client\\\\/requests\\\":85,\\\"client\\\\/sent_bytes\\\":11919,\\\"client\\\\/socket_unwritable_ms\\\":0,\\\"client\\\\/socket_writable_ms\\\":207,\\\"client\\\\/success\\\":84,\\\"clock_error\\\":0,\\\"jvm_buffer_direct_count\\\":4,\\\"jvm_buffer_direct_max\\\":133120,\\\"jvm_buffer_direct_used\\\":133120,\\\"jvm_buffer_mapped_count\\\":0,\\\"jvm_buffer_mapped_max\\\":0,\\\"jvm_buffer_mapped_used\\\":0,\\\"jvm_current_mem_CMS_Old_Gen_max\\\":3657433088,\\\"jvm_current_mem_CMS_Old_Gen_used\\\":12173984,\\\"jvm_current_mem_CMS_Perm_Gen_max\\\":85983232,\\\"jvm_current_mem_CMS_Perm_Gen_used\\\":44355376,\\\"jvm_current_mem_Code_Cache_max\\\":50331648,\\\"jvm_current_mem_Code_Cache_used\\\":2425792,\\\"jvm_current_mem_Eden_Space_max\\\":429522944,\\\"jvm_current_mem_Eden_Space_used\\\":169518376,\\\"jvm_current_mem_Survivor_Space_max\\\":53673984,\\\"jvm_current_mem_Survivor_Space_used\\\":53673984,\\\"jvm_current_mem_used\\\":282147512,\\\"jvm_fd_count\\\":142,\\\"jvm_fd_limit\\\":4096,\\\"jvm_gc_ConcurrentMarkSweep_cycles\\\":0,\\\"jvm_gc_ConcurrentMarkSweep_msec\\\":0,\\\"jvm_gc_Copy_cycles\\\":0,\\\"jvm_gc_Copy_msec\\\":0,\\\"jvm_gc_cycles\\\":0,\\\"jvm_gc_msec\\\":0,\\\"jvm_heap_committed\\\":4140630016,\\\"jvm_heap_max\\\":4140630016,\\\"jvm_heap_used\\\":235366344,\\\"jvm_nonheap_committed\\\":47120384,\\\"jvm_nonheap_max\\\":136314880,\\\"jvm_nonheap_used\\\":46777704,\\\"jvm_num_cpus\\\":1,\\\"jvm_post_gc_CMS_Old_Gen_max\\\":3657433088,\\\"jvm_post_gc_CMS_Old_Gen_used\\\":0,\\\"jvm_post_gc_CMS_Perm_Gen_max\\\":85983232,\\\"jvm_post_gc_CMS_Perm_Gen_used\\\":0,\\\"jvm_post_gc_Eden_Space_max\\\":429522944,\\\"jvm_post_gc_Eden_Space_used\\\":0,\\\"jvm_post_gc_Survivor_Space_max\\\":53673984,\\\"jvm_post_gc_Survivor_Space_used\\\":53673984,\\\"jvm_post_gc_used\\\":53673984,\\\"jvm_start_time\\\":1402536778818,\\\"jvm_thread_count\\\":18,\\\"jvm_thread_daemon_count\\\":12,\\\"jvm_thread_peak_count\\\":18,\\\"jvm_uptime\\\":62216,\\\"queue_depth\\\":41,\\\"records-read\\\":126,\\\"requests_sent\\\":85,\\\"service\\\":\\\"parrot_web\\\",\\\"source\\\":\\\"jonatstr-dt-oneconnector\\\",\\\"timestamp\\\":1402536841,\\\"unexpected_error\\\":1,\\\"unexpected_error\\\\/com.twitter.finagle.ChannelClosedException\\\":1}\";\n        String key = \"TEST\";\n\n        boolean exceptionFound = false;\n        try {\n            parser.getSample(line, key);\n        } catch (ParseException e) {\n            exceptionFound = true;\n        }\n\n        assertTrue(exceptionFound);\n\n    }\n\n    @Test\n    void testParseValidFile(JenkinsRule jenkinsRule) throws Exception {\n\n        Stats stats1 = new IagoParser.Stats();\n        stats1.setClientRequestLatencyMsAverage((long) 4);\n        stats1.setClientRequestLatencyMsMaximum((long) 5);\n        stats1.setClientRequestLatencyMsMinimum((long) 1);\n        stats1.setClientSuccess((long) 10);\n        stats1.setClientRequests((long) 10);\n        stats1.setClientSendBytes((long) 9000);\n\n        Stats stats2 = new IagoParser.Stats();\n        stats2.setClientRequestLatencyMsAverage((long) 3);\n        stats2.setClientRequestLatencyMsMaximum((long) 4);\n        stats2.setClientRequestLatencyMsMinimum((long) 2);\n        stats2.setClientSuccess((long) 12);\n        stats2.setClientRequests((long) 13);\n        stats2.setClientSendBytes((long) 12000);\n\n        // Create a temp file.\n        // We can move this to resources, but allow flexibility in\n        // unit test to create on the fly\n        File temp = File.createTempFile(\"parrot-server-stats\", \".log\");\n        // Delete the file when program exits.\n        temp.deleteOnExit();\n\n        GsonBuilder objGsonBuilder = new GsonBuilder();\n        Gson gson = objGsonBuilder.create();\n        boolean exceptionOccured = false;\n\n        // Write to temp file\n        BufferedWriter out = null;\n        try {\n            out = new BufferedWriter(new FileWriter(temp));\n\n            System.out.println(gson.toJson(stats1));\n\n            out.write(\"INF [20140611-21:34:01.224] stats: \" + gson.toJson(stats1));\n            out.write(\"INF [20140611-21:35:01.111] stats: \" + gson.toJson(stats2));\n        } catch (IOException e) {\n            exceptionOccured = true;\n        } finally {\n            if (out != null) {\n                out.close();\n            }\n        }\n        assertFalse(exceptionOccured);\n\n        IagoParser parser = new IagoParser(\"\", PerformanceReportTest.DEFAULT_PERCENTILES);\n        Collection<PerformanceReport> reports = parser.parse(new FreeStyleBuild(jenkinsRule.createFreeStyleProject()),\n                Arrays.asList(temp), jenkinsRule.createTaskListener());\n        assertEquals(1, reports.size());\n\n        PerformanceReport report = (PerformanceReport) reports.toArray()[0];\n\n        assertEquals((stats1.getClientRequestLatencyMsAverage() + stats2.getClientRequestLatencyMsAverage()) / 2,\n                report.getAverage());\n    }\n\n    @Test\n    void testUserRegexNoValidationErrors(JenkinsRule jenkinsRule) throws Exception {\n\n        IagoParser parser = new IagoParser(null, PerformanceReportTest.DEFAULT_PERCENTILES);// , \"4[0-9]+,5[0-9]+\",\n                                                                                            // \",\");\n\n        // Line to parse\n        String line = \"INF [20140611-21:34:01.224] stats: {\\\"client\\\\/request_latency_ms_average\\\":3,\\\"client\\\\/request_latency_ms_count\\\":85,\\\"client\\\\/request_latency_ms_maximum\\\":105,\\\"client\\\\/request_latency_ms_minimum\\\":1,\\\"client\\\\/request_latency_ms_p50\\\":2,\\\"client\\\\/request_latency_ms_p90\\\":4,\\\"client\\\\/request_latency_ms_p95\\\":4,\\\"client\\\\/request_latency_ms_p99\\\":105,\\\"client\\\\/request_latency_ms_p999\\\":105,\\\"client\\\\/request_latency_ms_p9999\\\":105,\\\"client\\\\/request_latency_ms_sum\\\":276,\\\"client\\\\/requests\\\":85,\\\"client\\\\/sent_bytes\\\":11919,\\\"client\\\\/socket_unwritable_ms\\\":0,\\\"client\\\\/socket_writable_ms\\\":207,\\\"client\\\\/success\\\":84}\";\n        String key = \"TEST\";\n\n        HttpSample sample = parser.getSample(line, key);\n        assertEquals(105, sample.getSummarizerMax());\n        assertEquals(1, sample.getSummarizerMin());\n        assertEquals(85, sample.getSummarizerSamples());\n        assertEquals((float) 1.0, sample.getSummarizerErrors(), 0.0);\n        assertEquals(3, sample.getDuration());\n        assertEquals(key, sample.getUri());\n\n    }\n\n    @Test\n    void testNoErrors(JenkinsRule jenkinsRule) throws Exception {\n        IagoParser parser = new IagoParser(null, PerformanceReportTest.DEFAULT_PERCENTILES);// , \"4[0-9]+,5[0-9]+\",\n                                                                                            // \",\");\n\n        // Line to parse\n        String line = \"INF [20140611-21:34:01.224] stats: {\\\"client\\\\/request_latency_ms_average\\\":3,\\\"client\\\\/request_latency_ms_count\\\":85,\\\"client\\\\/request_latency_ms_maximum\\\":105,\\\"client\\\\/request_latency_ms_minimum\\\":1,\\\"client\\\\/request_latency_ms_p50\\\":2,\\\"client\\\\/request_latency_ms_p90\\\":4,\\\"client\\\\/request_latency_ms_p95\\\":4,\\\"client\\\\/request_latency_ms_p99\\\":105,\\\"client\\\\/request_latency_ms_p999\\\":105,\\\"client\\\\/request_latency_ms_p9999\\\":105,\\\"client\\\\/request_latency_ms_sum\\\":276,\\\"client\\\\/requests\\\":85,\\\"client\\\\/sent_bytes\\\":11919,\\\"client\\\\/socket_unwritable_ms\\\":0,\\\"client\\\\/socket_writable_ms\\\":207,\\\"client\\\\/success\\\":85}\";\n        String key = \"TEST\";\n\n        HttpSample sample = parser.getSample(line, key);\n        assertEquals(105, sample.getSummarizerMax());\n        assertEquals(1, sample.getSummarizerMin());\n        assertEquals(85, sample.getSummarizerSamples());\n        assertEquals((float) 0.0, sample.getSummarizerErrors(), 0.0);\n        assertEquals(3, sample.getDuration());\n        assertEquals(key, sample.getUri());\n    }\n\n}\n"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/parsers/JMeterCsvParserTest.java",
    "content": "package hudson.plugins.performance.parsers;\n\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.reports.PerformanceReportTest;\nimport hudson.plugins.performance.reports.UriReport;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\n\nimport java.io.File;\nimport java.util.Map;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\nimport static org.junit.jupiter.api.Assertions.assertNotNull;\nimport static org.junit.jupiter.api.Assertions.fail;\n\nclass JMeterCsvParserTest {\n    private static final String NO_GLOB = null;\n    private File reportFile;\n    private File reportFile2;\n    private File reportFile3;\n\n    @BeforeEach\n    void beforeMethod() throws Exception {\n        reportFile = new File(getClass().getResource(\"/JMeterCsvResults.csv\").toURI());\n        reportFile2 = new File(getClass().getResource(\"/JMeterCsvResults2.csv\").toURI());\n        reportFile3 = new File(getClass().getResource(\"/JMeterCsvResults3.csv\").toURI());\n    }\n\n\n    @Test\n    void canParseCsvFile() throws Exception {\n        final JMeterCsvParser parser = new JMeterCsvParser(NO_GLOB, PerformanceReportTest.DEFAULT_PERCENTILES);\n        parseAndVerifyResult(parser, reportFile);\n    }\n\n    @Test\n    void testDateDateFormats() throws Exception {\n        final JMeterCsvParser parser = new JMeterCsvParser(NO_GLOB, PerformanceReportTest.DEFAULT_PERCENTILES);\n        PerformanceReport performanceReport = parseAndVerifyResult(parser, reportFile);\n        assertEquals(41.9, performanceReport.getTotalTrafficInKb(), 0.01);\n        performanceReport = parseAndVerifyResult(parser, reportFile2);\n        assertEquals(41.9, performanceReport.getTotalTrafficInKb(), 0.01);\n        performanceReport = parseAndVerifyResult(parser, reportFile3);\n        assertEquals(41.9, performanceReport.getTotalTrafficInKb(), 0.01);\n    }\n\n    private PerformanceReport parseAndVerifyResult(JMeterCsvParser parser, File file) throws Exception {\n        final PerformanceReport result = parser.parse(file);\n        // Verify results.\n        assertNotNull(result);\n        assertEquals(3, result.samplesCount(), \"The source file contains three samples. These should all have been added to the performance report.\");\n        return result;\n    }\n\n    @Test\n    void testLookingForDelimeter() throws Exception {\n        assertEquals(',', JMeterCsvParser.lookingForDelimiter(\"acaaAZSZAzzafergc,adzxcAZZAAZ\"));\n        assertEquals('\\t', JMeterCsvParser.lookingForDelimiter(\"acaaAZSZAzzafergc\\tadzxcAZZAAZ\"));\n        assertEquals(';', JMeterCsvParser.lookingForDelimiter(\"acaaAZSZAzzafergc;adzxcAZZAAZ\"));\n        assertEquals('^', JMeterCsvParser.lookingForDelimiter(\"acaaAZSZAzzafergc^adzxcAZZAAZ\"));\n        assertEquals(':', JMeterCsvParser.lookingForDelimiter(\"acaaAZSZAzzafergc:tadzxcAZZAAZ\"));\n\n        try {\n            JMeterCsvParser.lookingForDelimiter(\"asdadadadasd\");\n            fail(\"Can not find delimiter in this string\");\n        } catch (Exception ex) {\n            assertEquals(\"Cannot find delimiter in header asdadadadasd\", ex.getMessage());\n        }\n    }\n\n    @Test\n    void testMultiLineCSV() throws Exception {\n\n        // Setup fixture.\n        final JMeterCsvParser parser = new JMeterCsvParser(null, PerformanceReportTest.DEFAULT_PERCENTILES);\n        final File reportFile = new File(getClass().getResource(\"/multiLineCSV.jtl\").toURI());\n\n        // Execute system under test.\n        PerformanceReport performanceReport = parser.parse(reportFile);\n\n        Map<String, UriReport> reportMap = performanceReport.getUriReportMap();\n\n        assertEquals(2, reportMap.size());\n        for (UriReport report : reportMap.values()) {\n            if (report.getHttpCode().equals(\"200\")) {\n                assertEquals(\"Preparation: Login\", report.getUri());\n            } else if (report.getHttpCode().equals(\"500\")) {\n                assertEquals(\"no such element: Unable to locate element: {\\\"method\\\":\\\"id\\\",\\\"selector\\\":\\\"reviewBAD\\\"}\\n\" +\n                        \"                  Session ID: 89a1a36b52e184afb01963257d8739e8\\n\" +\n                        \"                  *** Element info: {Using=id, value=reviewBAD}\", report.getUri());\n            } else {\n                fail(\"Wrong uri sampler\");\n            }\n        }\n    }\n\n    @Test\n    void testCSVWithRegex() throws Exception {\n        final JMeterCsvParser parser = new JMeterCsvParser(\n                null, PerformanceReportTest.DEFAULT_PERCENTILES, \"^(HP|Scenario|Search)(-success|-failure)?$\");\n        final File reportFile = new File(getClass().getResource(\"/filewithtransactions.csv\").toURI());\n\n        // Execute system under test.\n        PerformanceReport performanceReport = parser.parse(reportFile);\n\n        Map<String, UriReport> reportMap = performanceReport.getUriReportMap();\n\n        assertEquals(3, reportMap.size());\n        assertEquals(\"Search\", reportMap.get(\"Search\").getUri());\n        assertEquals(\"Scenario\", reportMap.get(\"Scenario\").getUri());\n        assertEquals(\"HP\", reportMap.get(\"HP\").getUri());\n\n        assertEquals(37, reportMap.get(\"HP\").samplesCount());\n        assertEquals(33, reportMap.get(\"Search\").samplesCount());\n        assertEquals(33, reportMap.get(\"Scenario\").samplesCount());\n    }\n}"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/parsers/JMeterParserTest.java",
    "content": "package hudson.plugins.performance.parsers;\n\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.reports.PerformanceReportTest;\nimport org.junit.jupiter.api.Test;\n\nimport java.io.File;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\nimport static org.junit.jupiter.api.Assertions.assertFalse;\nimport static org.junit.jupiter.api.Assertions.assertNotNull;\nimport static org.junit.jupiter.api.Assertions.assertTrue;\nimport static org.junit.jupiter.api.Assertions.fail;\n\n/**\n * This class contains basic tests that verify the parsing behavior of\n * {@link JMeterParser}.\n *\n * @author Guus der Kinderen, guus.der.kinderen@gmail.com\n */\nclass JMeterParserTest {\n    /**\n     * Verifies that {@link JMeterParser#isXmlFile(File)} correctly identifies an\n     * XML file.\n     */\n    @Test\n    void testIsXml() throws Exception {\n        // Setup fixture.\n        final File xmlFile = new File(getClass().getResource(\"/JMeterResults.jtl\").toURI());\n\n        // Execute system under test.\n        final boolean result = JMeterParser.isXmlFile(xmlFile);\n\n        // Verify results.\n        assertTrue(result);\n    }\n\n    /**\n     * Verifies that {@link JMeterParser#isXmlFile(File)} returns false when the\n     * provided data is CSV.\n     */\n    @Test\n    void testIsCsv() throws Exception {\n        // Setup fixture.\n        final File csvFile = new File(getClass().getResource(\"/JENKINS-16627_CSV_instead_of_XML.jtl\").toURI());\n\n        // Execute system under test.\n        final boolean result = JMeterParser.isXmlFile(csvFile);\n\n        // Verify results.\n        assertFalse(result);\n    }\n\n    /**\n     * Verifies that {@link JMeterParser#isXmlFile(File)} returns false when the\n     * provided data is CSV.\n     */\n    @Test\n    void testIsEmpty() throws Exception {\n        // Setup fixture.\n        final File emptyFile = new File(getClass().getResource(\"/emptyfile.jtl\").toURI());\n\n        // Execute system under test.\n        final boolean result = JMeterParser.isXmlFile(emptyFile);\n\n        // Verify results.\n        assertFalse(result);\n    }\n\n    /**\n     * Verifies that {@link JMeterParser#isXmlFile(File)} returns true when the\n     * XML data is preceded by whitespace.\n     */\n    @Test\n    void testIsWhitespaceXml() throws Exception {\n        // Setup fixture.\n        final File xml = new File(getClass().getResource(\"/whitespace-followed-by-xml.jtl\").toURI());\n\n        // Execute system under test.\n        final boolean result = JMeterParser.isXmlFile(xml);\n\n        // Verify results.\n        assertTrue(result);\n    }\n\n    /**\n     * JMeter can generate JTL files that contain XML data. This test verifies\n     * that such a file can be parsed by {@link JMeterParser#parse(File)} without\n     * incident.\n     * <p>\n     * Note that this tests verifies that the file can be parsed. It does not\n     * verify the correctness of the parsed data.\n     */\n    @Test\n    void testParseXmlJtlFile() throws Exception {\n        // Setup fixture.\n        final AbstractParser parser = new JMeterParser(null, PerformanceReportTest.DEFAULT_PERCENTILES);\n        final File reportFile = new File(getClass().getResource(\"/JMeterResults.jtl\").toURI());\n\n        // Execute system under test.\n        final PerformanceReport result = parser.parse(reportFile);\n\n        // Verify results.\n        assertNotNull(result);\n        assertEquals(8, result.samplesCount(), \"The source file contains eight samples. These should all have been added to the performance report.\");\n    }\n\n    /**\n     * JMeter can generate JTL files that contain XML data. This test verifies\n     * that such a file can be parsed by {@link JMeterParser#parse(File)} without\n     * incident.\n     * <p>\n     * Note that this tests verifies that the file can be parsed. It does not\n     * verify the correctness of the parsed data.\n     */\n    @Test\n    void testParseCsvJtlFile() throws Exception {\n        // Setup fixture.\n        final AbstractParser parser = new JMeterParser(null, PerformanceReportTest.DEFAULT_PERCENTILES);\n        final File reportFile = new File(getClass().getResource(\"/JENKINS-16627_CSV_instead_of_XML.jtl\").toURI());\n\n        // Execute system under test.\n        try {\n            parser.parse(reportFile);\n            fail(\"cannot parse CSV file without header\");\n        } catch (Exception ex) {\n            assertEquals(\"Missing required column\", ex.getMessage());\n        }\n    }\n\n\n  /*\n  @Test\n  public void parseXmlTest() throws Exception\n  {\n    // Setup fixture.\n\n    // Execute system under test.\n\n    // Verify results.\n  }\n\n   */\n}\n"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/parsers/JMeterTestHelper.java",
    "content": "package hudson.plugins.performance.parsers;\n\nimport java.io.File;\n\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.reports.PerformanceReportTest;\n\n/**\n * Allows tests in other packages to call parse(File)\n */\npublic class JMeterTestHelper {\n\n    public static PerformanceReport parse(String resourceName) throws Exception {\n        File xmlFile = new File(JMeterTestHelper.class.getResource(resourceName).toURI());\n        return new JMeterParser(null, PerformanceReportTest.DEFAULT_PERCENTILES).parse(xmlFile);\n    }\n}\n"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/parsers/JUnitParserTest.java",
    "content": "package hudson.plugins.performance.parsers;\n\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.reports.PerformanceReportTest;\nimport org.junit.jupiter.api.Test;\n\nimport java.io.File;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\nimport static org.junit.jupiter.api.Assertions.assertNotNull;\n\nclass JUnitParserTest {\n\n    /**\n     * Test parsing a test with a long duration (ie. over 999 seconds) will work.\n     * Previously this was causing a NumberFormatException since it puts commas\n     * in for over 999 seconds, causing system to complain.\n     */\n    @Test\n    void testParseDurationLongRunningTest() {\n        assertEquals((long) 34953254, JUnitParser.parseDuration(\"34,953.254\"), \"Test having a time with commas will work.\");\n        assertEquals((long) 1134953254, JUnitParser.parseDuration(\"1,134,953.254\"), \"Test having a time with multiple commas will work.\");\n        assertEquals((long) 999999, JUnitParser.parseDuration(\"999.999\"), \"Test that time with no commas still work.\");\n    }\n\n    @Test\n    void testCanParseFileWithoutTimeAtrribute() throws Exception {\n        final JUnitParser parser = new JUnitParser(null, PerformanceReportTest.DEFAULT_PERCENTILES);\n        final File reportFile = new File(getClass().getResource(\"/TEST-JUnitResults-noTimeAttribute.xml\").toURI());\n\n        // Execute system under test.\n        final PerformanceReport result = parser.parse(reportFile);\n\n        // Verify results.\n        assertNotNull(result);\n        assertEquals(4, result.samplesCount(), \"The source file contains four samples. These should all have been added to the performance report.\");\n    }\n\n    @Test\n    void testCanParseJunitResultFileWithSuccessErrorAndFailure() throws Exception {\n        final JUnitParser parser = new JUnitParser(null, PerformanceReportTest.DEFAULT_PERCENTILES);\n        final File reportFile = new File(getClass().getResource(\"/TEST-JUnitResults-success-failure-error.xml\").toURI());\n\n        // Execute system under test.\n        final PerformanceReport result = parser.parse(reportFile);\n\n        // Verify results.\n        assertNotNull(result);\n        assertEquals(3, result.samplesCount(), \"The source file contains 3 samples. These should all have been added to the performance report.\");\n        assertEquals(2, result.countErrors(), \"The source file contains 2 failed samples. 1 test failure and 1 runtime error sample.\");\n    }\n}\n"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/parsers/JmeterSummarizerParserTest.java",
    "content": "package hudson.plugins.performance.parsers;\n\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.reports.PerformanceReportTest;\nimport org.junit.jupiter.api.Test;\n\nimport java.io.File;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\n\nclass JmeterSummarizerParserTest {\n\n    @Test\n    void testParse() throws Exception {\n        JmeterSummarizerParser jmeterSummarizerParser = new JmeterSummarizerParser(null, PerformanceReportTest.DEFAULT_PERCENTILES);\n        File summaryLogFile = new File(getClass().getResource(\"/summary.log\").toURI());\n        PerformanceReport performanceReport = jmeterSummarizerParser.parse(summaryLogFile);\n\n        assertEquals(1257, performanceReport.getSummarizerSize());\n        assertEquals(333, performanceReport.getSummarizerAvg());\n        assertEquals(3, performanceReport.getSummarizerMin());\n        assertEquals(5630, performanceReport.getSummarizerMax());\n        assertEquals(\"4.56\", performanceReport.getSummarizerErrors());\n    }\n\n\n    @Test\n    void testParseNewLog() throws Exception {\n\n        String path = getClass().getResource(\"/jmeter.log\").getPath();\n        String parser = ParserDetector.detect(path);\n        assertEquals(JmeterSummarizerParser.class.getSimpleName(), parser);\n\n        JmeterSummarizerParser jmeterSummarizerParser = new JmeterSummarizerParser(path, PerformanceReportTest.DEFAULT_PERCENTILES);\n        PerformanceReport performanceReport = jmeterSummarizerParser.parse(new File(path));\n\n        assertEquals(1000, performanceReport.getSummarizerSize());\n        assertEquals(276, performanceReport.getSummarizerAvg());\n        assertEquals(50, performanceReport.getSummarizerMin());\n        assertEquals(500, performanceReport.getSummarizerMax());\n        assertEquals(\"0.00\", performanceReport.getSummarizerErrors());\n    }\n}\n"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/parsers/LoadRunnerParserTest.java",
    "content": "package hudson.plugins.performance.parsers;\n\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.reports.PerformanceReportTest;\nimport hudson.plugins.performance.reports.UriReport;\nimport org.junit.jupiter.api.Test;\n\nimport java.io.File;\nimport java.util.Map;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\nimport static org.junit.jupiter.api.Assertions.assertNotNull;\n\nclass LoadRunnerParserTest {\n    private static final String NO_GLOB = null;\n\n    /* Simple test scenario  with 2 VUsers x 1 iteration (until completion),\n     * no rampup, 2 transactions as below:\n        Action()\n        {\tint i;\n            for (i = 0; i < 10; i++) {\n                lr_set_transaction(\"transaction1\", 1, LR_PASS); // 1 second\n                lr_think_time(1); // 1 second\n                lr_set_transaction(\"transaction2\", i%2+1, i%5? LR_PASS: LR_FAIL); 1 or 2 seconds, fail every 5th\n            }\n            return 0;\n        }\n    */\n    @Test\n    void test() throws Exception {\n        final LoadRunnerParser parser = new LoadRunnerParser(NO_GLOB, PerformanceReportTest.DEFAULT_PERCENTILES);\n        final PerformanceReport result = parser.parse(new File(getClass().getResource(\"/lr-session.mdb\").toURI()));\n        assertNotNull(result);\n\n        Map<String, UriReport> uriReportMap = result.getUriReportMap();\n        UriReport report = uriReportMap.get(\"transaction1\");\n        assertNotNull(report);\n        assertEquals(\"transaction1\", report.getDisplayName());\n        assertEquals(20, report.samplesCount());\n        assertEquals(1000, report.getAverage());\n        assertEquals(0, report.countErrors());\n        assertEquals(10043, report.getEnd().getTime()-report.getStart().getTime());\n\n        report = uriReportMap.get(\"transaction2\");\n        assertNotNull(report);\n        assertEquals(\"transaction2\", report.getDisplayName());\n        assertEquals(20, report.samplesCount());\n        assertEquals(1500, report.getAverage());\n        assertEquals(4, report.countErrors());\n        assertEquals(10043, report.getEnd().getTime()-report.getStart().getTime());\n    }\n}"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/parsers/LocustParserTest.java",
    "content": "package hudson.plugins.performance.parsers;\n\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.reports.PerformanceReportTest;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\n\nimport java.io.File;\n\nimport static org.junit.jupiter.api.Assertions.assertArrayEquals;\nimport static org.junit.jupiter.api.Assertions.assertEquals;\nimport static org.junit.jupiter.api.Assertions.assertFalse;\nimport static org.junit.jupiter.api.Assertions.assertNotNull;\nimport static org.junit.jupiter.api.Assertions.assertTrue;\n\nclass LocustParserTest {\n    static final String FILE_NAME = \"test_results_stats.csv\";\n    File requestReportFile;\n    LocustParser locustParser;\n    PerformanceReport report;\n\n    @BeforeEach\n    void setUp() throws Exception {\n        requestReportFile = new File(getClass().getResource(String.format(\"/%s\", FILE_NAME)).toURI());\n        locustParser = new LocustParser(null, PerformanceReportTest.DEFAULT_PERCENTILES);\n        report = locustParser.parse(requestReportFile);\n    }\n\n    @Test\n    void shouldCreateParser() throws Exception {\n        assertNotNull(locustParser);\n    }\n\n    @Test\n    void parserShouldReturnGlobPattern() throws Exception {\n        assertEquals(\"**/*_stats.csv\", locustParser.getDefaultGlobPattern());\n    }\n\n    @Test\n    void reportShouldContainSummarizedValues() throws Exception {\n        assertEquals(4, report.getSummarizerSize());\n        assertEquals(1993, report.getSummarizerMax());\n        assertEquals(196, report.getSummarizerMin());\n        assertEquals(223, report.getSummarizerAvg());\n    }\n\n    @Test\n    void reportShouldContainAllReports() throws Exception {\n        String[] reportUris = new String[]{\"big\", \"huge\", \"medium\", \"small\"};\n        assertArrayEquals(reportUris, report.getUriReportMap().keySet().toArray(new String[0]));\n\n        for (String uri : reportUris) {\n            assertTrue(report.getUriReportMap().get(uri).hasSamples());\n        }\n    }\n\n    @Test\n    void reportHasValuesInUriReport() {\n        assertFalse(report.getUriReportMap().get(\"big\").isExcludeResponseTime());\n        assertEquals(370, report.getUriReportMap().get(\"big\").getAverage());\n        assertEquals(1, report.getUriReportMap().get(\"big\").samplesCount());\n        assertEquals(638.0, report.getUriReportMap().get(\"big\").getAverageSizeInKb(), 0.001);\n    }\n\n    @Test\n    void reportShouldContainTrafficSize() {\n        assertEquals(71464.0, report.getTotalTrafficInKb(), 0.001);\n    }\n\n    @Test\n    void reportShouldReturnProperFileName() throws Exception {\n        assertEquals(FILE_NAME, report.getReportFileName());\n    }\n}\n"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/parsers/ParserDetectorTest.java",
    "content": "package hudson.plugins.performance.parsers;\n\nimport org.junit.jupiter.api.Test;\nimport org.jvnet.hudson.test.Issue;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.SequenceInputStream;\nimport java.nio.charset.StandardCharsets;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\n\n\npublic class ParserDetectorTest {\n\n    @Test\n    void testFlow() throws Exception {\n        String filePath;\n\n        filePath = getClass().getResource(\"/TaurusXMLReport.xml\").toURI().getPath();\n        assertEquals(TaurusParser.class.getSimpleName(), ParserDetector.detect(filePath));\n\n        filePath = getClass().getResource(\"/JMeterResults.jtl\").toURI().getPath();\n        assertEquals(JMeterParser.class.getSimpleName(), ParserDetector.detect(filePath));\n\n        filePath = getClass().getResource(\"/TEST-JUnitResults.xml\").toURI().getPath();\n        assertEquals(JUnitParser.class.getSimpleName(), ParserDetector.detect(filePath));\n\n        filePath = getClass().getResource(\"/IagoResults.log\").toURI().getPath();\n        assertEquals(IagoParser.class.getSimpleName(), ParserDetector.detect(filePath));\n\n        filePath = getClass().getResource(\"/WrkResultsQuick.wrk\").toURI().getPath();\n        assertEquals(WrkSummarizerParser.class.getSimpleName(), ParserDetector.detect(filePath));\n\n        filePath = getClass().getResource(\"/JMeterCsvResults.csv\").toURI().getPath();\n        assertEquals(JMeterCsvParser.class.getSimpleName(), ParserDetector.detect(filePath));\n\n        filePath = getClass().getResource(\"/summary.log\").toURI().getPath();\n        assertEquals(JmeterSummarizerParser.class.getSimpleName(), ParserDetector.detect(filePath));\n\n        filePath = getClass().getResource(\"/lr-session.mdb\").toURI().getPath();\n        assertEquals(LoadRunnerParser.class.getSimpleName(), ParserDetector.detect(filePath));\n\n        filePath = getClass().getResource(\"/test_results_stats.csv\").toURI().getPath();\n        assertEquals(LocustParser.class.getSimpleName(), ParserDetector.detect(filePath));\n    }\n\n    @Issue(\"JENKINS-44317\")\n    @Test\n    void testIssue44317() throws Exception {\n        String filePath = getClass().getResource(\"/TEST-results.xml\").toURI().getPath();\n        assertEquals(JUnitParser.class.getSimpleName(), ParserDetector.detect(filePath));\n    }\n\n    @Issue(\"JENKINS-45723\")\n    @Test\n    void testIssue45723() throws Exception {\n        String filePath = getClass().getResource(\"/TEST-JUnitResults-success-failure-error.xml\").toURI().getPath();\n        assertEquals(JUnitParser.class.getSimpleName(), ParserDetector.detect(filePath));\n    }\n\n    @Issue(\"JENKINS-47808\")\n    @Test\n    void testIssue() throws Exception {\n        assertEquals(JMeterParser.class.getSimpleName(), ParserDetector.detectXMLFileType(getHugeJMeterInputStream()));\n    }\n\n    public static InputStream getHugeJMeterInputStream() {\n        return new SequenceInputStream(getPrefixInputStream(), getInfiniteSampleInputStream());\n    }\n\n    private static ByteArrayInputStream getPrefixInputStream() {\n        return new ByteArrayInputStream(\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n<testResults version=\\\"1.2\\\">\".getBytes(\n                StandardCharsets.UTF_8));\n    }\n\n    private static InputStream getInfiniteSampleInputStream() {\n        return repeat(\"<httpSample t=\\\"289\\\" lt=\\\"289\\\" ts=\\\"1509447454646\\\" s=\\\"true\\\" lb=\\\"test\\\" rc=\\\"200\\\" rm=\\\"OK\\\" tn=\\\"test\\\" dt=\\\"text\\\" by=\\\"1410\\\"/>\".getBytes(\n                StandardCharsets.UTF_8), Integer.MAX_VALUE);\n    }\n\n    public static InputStream repeat(final byte[] sample, final int times) {\n        return new InputStream() {\n            private long pos = 0;\n            private final long total = (long)sample.length * times;\n\n            public int read() throws IOException {\n                return pos < total ? sample[(int)(pos++ % sample.length)] : -1;\n            }\n        };\n    }\n}"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/parsers/ParserFactoryTest.java",
    "content": "package hudson.plugins.performance.parsers;\n\nimport edu.umd.cs.findbugs.annotations.NonNull;\nimport hudson.EnvVars;\nimport hudson.FilePath;\nimport hudson.model.FreeStyleBuild;\nimport hudson.model.FreeStyleProject;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.reports.PerformanceReportTest;\nimport org.junit.jupiter.api.Test;\nimport org.jvnet.hudson.test.Issue;\nimport org.jvnet.hudson.test.JenkinsRule;\nimport org.jvnet.hudson.test.junit.jupiter.WithJenkins;\n\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.util.HashMap;\n\nimport static org.junit.jupiter.api.Assertions.assertInstanceOf;\n\n@WithJenkins\nclass ParserFactoryTest {\n\n    @Test\n    void testFlow(JenkinsRule j) throws Exception {\n        EnvVars envVars = new EnvVars(new HashMap<String, String>());\n        FreeStyleProject project = j.createFreeStyleProject();\n        FreeStyleBuildExt build = new FreeStyleBuildExt(project);\n\n        FilePath workspace = new FilePath(Files.createTempDirectory(null).toFile());\n        build.setWorkspace(workspace);\n        String filePath;\n\n        filePath = getClass().getResource(\"/TaurusXMLReport.xml\").toURI().getPath();\n        assertInstanceOf(TaurusParser.class, ParserFactory.getParser(build, workspace, null, filePath, envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0));\n\n        filePath = getClass().getResource(\"/JMeterResults.jtl\").toURI().getPath();\n        assertInstanceOf(JMeterParser.class, ParserFactory.getParser(build, workspace, null, filePath, envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0));\n\n        filePath = getClass().getResource(\"/TEST-JUnitResults.xml\").toURI().getPath();\n        assertInstanceOf(JUnitParser.class, ParserFactory.getParser(build, workspace, null, filePath, envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0));\n\n        filePath = getClass().getResource(\"/IagoResults.log\").toURI().getPath();\n        assertInstanceOf(IagoParser.class, ParserFactory.getParser(build, workspace, null, filePath, envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0));\n\n        filePath = getClass().getResource(\"/WrkResultsQuick.wrk\").toURI().getPath();\n        assertInstanceOf(WrkSummarizerParser.class, ParserFactory.getParser(build, workspace, null, filePath, envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0));\n\n        filePath = getClass().getResource(\"/JMeterCsvResults.csv\").toURI().getPath();\n        assertInstanceOf(JMeterCsvParser.class, ParserFactory.getParser(build, workspace, null, filePath, envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0));\n\n        filePath = getClass().getResource(\"/summary.log\").toURI().getPath();\n        assertInstanceOf(JmeterSummarizerParser.class, ParserFactory.getParser(build, workspace, null, filePath, envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0));\n\n        filePath = getClass().getResource(\"/test_results_stats.csv\").toURI().getPath();\n        assertInstanceOf(LocustParser.class, ParserFactory.getParser(build, workspace, null, filePath, envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0));\n    }\n\n    @Test\n    void testFlowWithGlob(JenkinsRule j) throws Exception {\n        EnvVars envVars = new EnvVars(new HashMap<String, String>());\n        assertInstanceOf(TaurusParser.class, ParserFactory.getParser(null, null, null, \"**/*.xml\", envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0));\n        assertInstanceOf(JMeterParser.class, ParserFactory.getParser(null, null, null, \"**/*.jtl\", envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0));\n        assertInstanceOf(JUnitParser.class, ParserFactory.getParser(null, null, null, \"**/TEST-*.xml\", envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0));\n        assertInstanceOf(IagoParser.class, ParserFactory.getParser(null, null, null, \"parrot-server-stats.log\", envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0));\n        assertInstanceOf(WrkSummarizerParser.class, ParserFactory.getParser(null, null, null, \"**/*.wrk\", envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0));\n        assertInstanceOf(JMeterCsvParser.class, ParserFactory.getParser(null, null, null, \"**/*.csv\", envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0));\n        assertInstanceOf(JmeterSummarizerParser.class, ParserFactory.getParser(null, null, null, \"**/*.log\", envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0));\n        assertInstanceOf(LocustParser.class, ParserFactory.getParser(null, null, null, \"**/*_stats.csv\", envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0));\n    }\n\n    @Test\n    @Issue(\"JENKINS-43503\")\n    void test43503(JenkinsRule j) throws Exception {\n        FreeStyleProject project = j.createFreeStyleProject();\n        FreeStyleBuildExt build = new FreeStyleBuildExt(project);\n        EnvVars envVars = new EnvVars(new HashMap<String, String>());\n\n        FilePath workspace = new FilePath(Files.createTempDirectory(null).toFile());\n        build.setWorkspace(workspace);\n\n        FilePath results = workspace.child(\"results\");\n        results.mkdirs();\n\n        FilePath child = results.child(\"result.wrk\");\n        child.copyFrom(getClass().getResourceAsStream(\"/WrkResultsQuick.wrk\"));\n        String glob = \"**/results/*.wrk\";\n        assertInstanceOf(WrkSummarizerParser.class, ParserFactory.getParser(build, build.getWorkspace(), null, glob, envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0));\n\n        FilePath child2 = results.child(\"result.jtl\");\n        child2.copyFrom(getClass().getResourceAsStream(\"/JMeterResults.jtl\"));\n        String glob2 = \"**/results/*.jtl\";\n        assertInstanceOf(JMeterParser.class, ParserFactory.getParser(build, build.getWorkspace(), null, glob2, envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0));\n    }\n\n\n    @Test\n    @Issue(\"JENKINS-45119\")\n    void test45119(JenkinsRule j) throws Exception {\n        FreeStyleProject project = j.createFreeStyleProject();\n        FreeStyleBuildExt build = new FreeStyleBuildExt(project);\n        EnvVars envVars = new EnvVars(new HashMap<String, String>());\n\n        FilePath workspace = new FilePath(Files.createTempDirectory(null).toFile());\n        build.setWorkspace(workspace);\n\n        String absPath1 = getClass().getResource(\"/WrkResultsQuick.wrk\").getPath();\n\n        assertInstanceOf(WrkSummarizerParser.class, ParserFactory.getParser(build, build.getWorkspace(), null, absPath1, envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0));\n\n        String absPath2 = getClass().getResource(\"/JMeterResults.jtl\").getPath();\n        assertInstanceOf(JMeterParser.class, ParserFactory.getParser(build, build.getWorkspace(), null, absPath2, envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0));\n\n        FilePath results = workspace.child(\"results\");\n        results.mkdirs();\n\n        FilePath child = results.child(\"result.wrk\");\n        child.copyFrom(getClass().getResourceAsStream(\"/WrkResultsQuick.wrk\"));\n        assertInstanceOf(WrkSummarizerParser.class, ParserFactory.getParser(build, build.getWorkspace(), null, \"results/result.wrk\", envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0));\n\n        FilePath child2 = results.child(\"result.jtl\");\n        child2.copyFrom(getClass().getResourceAsStream(\"/JMeterResults.jtl\"));\n        assertInstanceOf(JMeterParser.class, ParserFactory.getParser(build, build.getWorkspace(), null, \"results/result.jtl\", envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0));\n    }\n\n    @Test\n    @Issue(\"JENKINS-45119\")\n    void testAntAbsolutePath(JenkinsRule j) throws Exception {\n        FreeStyleProject project = j.createFreeStyleProject();\n        FreeStyleBuildExt build = new FreeStyleBuildExt(project);\n        EnvVars envVars = new EnvVars(new HashMap<String, String>());\n\n        FilePath workspace = new FilePath(Files.createTempDirectory(null).toFile());\n        build.setWorkspace(workspace);\n\n        String path = getClass().getResource(\"/single_result/res.csv\").getPath();\n        path = path.replace(\"res.\", \"*.\");\n        assertInstanceOf(JMeterCsvParser.class, ParserFactory.getParser(build, build.getWorkspace(), null, path, envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0));\n\n        String path2 = getClass().getResource(\"/single_result/nested/res.jtl\").getPath();\n        path2 = path2.replace(\"nested/res\", \"**/*\");\n        assertInstanceOf(JMeterParser.class, ParserFactory.getParser(build, build.getWorkspace(), null, path2, envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0));\n\n        String path3 = getClass().getResource(\"/single_result/nested/res.jtl\").getPath();\n        path3 = path3.replace(\"single_result\", \"**\");\n        path3 = path3.replace(\"res.\", \"*.\");\n        assertInstanceOf(JMeterParser.class, ParserFactory.getParser(build, build.getWorkspace(), null, path3, envVars, PerformanceReportTest.DEFAULT_PERCENTILES, PerformanceReport.INCLUDE_ALL).get(0));\n    }\n\n\n    public static class FreeStyleBuildExt extends FreeStyleBuild {\n\n        public FreeStyleBuildExt(FreeStyleProject project) throws IOException {\n            super(project);\n        }\n\n        @Override\n        protected void setWorkspace(@NonNull FilePath ws) {\n            super.setWorkspace(ws);\n        }\n    }\n}"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/parsers/TaurusParserTest.java",
    "content": "package hudson.plugins.performance.parsers;\n\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.reports.PerformanceReportTest;\nimport hudson.plugins.performance.reports.UriReport;\nimport org.junit.jupiter.api.Test;\n\nimport java.io.File;\nimport java.util.Map;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\nimport static org.junit.jupiter.api.Assertions.assertNotNull;\nimport static org.junit.jupiter.api.Assertions.fail;\n\npublic class TaurusParserTest {\n\n    public static final double DELTA = 0.000001;\n\n    @Test\n    void testReadXML() throws Exception {\n        TaurusParser parser = new TaurusParser(\"xml report\", PerformanceReportTest.DEFAULT_PERCENTILES);\n\n        PerformanceReport report = parser.parse(new File(getClass().getResource(\"/TaurusXMLReport.xml\").toURI()));\n        PerformanceReport prevReport = parser.parse(new File(getClass().getResource(\"/TaurusPreviousBuildReport.xml\").toURI()));\n        assertNotNull(report);\n        checkPerformanceReport(report);\n\n        assertNotNull(prevReport);\n        report.setLastBuildReport(prevReport);\n        checkReportDiff(report);\n\n        Map<String, UriReport> uriReportMap = report.getUriReportMap();\n        assertEquals(2, uriReportMap.size());\n\n        for (String key : uriReportMap.keySet()) {\n            if (\"__test_url1.org_\".equals(key)) {\n                checkUriReport1(uriReportMap.get(key));\n            } else if (\"__test_url2.com_\".equals(key)) {\n                checkUriReport2(uriReportMap.get(key));\n            } else {\n                fail(\"There is not such key in test file: TaurusXMLReport.xml\");\n            }\n        }\n\n    }\n\n    private void checkUriReport1(UriReport report) {\n        // Check values for __test_url1.org_\n        assertEquals(0.15600 * 1000, report.getMin(), DELTA, \"Check min\");\n        assertEquals(0.84300 * 1000, report.getMedian(), DELTA, \"Check median\");\n        assertEquals(1.29300 * 1000, report.get90Line(), DELTA, \"Check line 90\");\n        assertEquals(1.42000 * 1000, report.get95Line(), DELTA, \"Check line 95\");\n        assertEquals(1.71800 * 1000, report.getMax(), DELTA, \"Check max\");\n        assertEquals((long) (0.80638 * 1000), report.getAverage(), \"Check average\");\n        assertEquals(326 + 11, report.samplesCount(), DELTA, \"Check samples count\");\n        assertEquals(3.264, report.errorPercent(), DELTA, \"Check errors\");\n    }\n\n    private void checkUriReport2(UriReport report) {\n        // Check values for __test_url2.com_\n        assertEquals(0.06400 * 1000, report.getMin(), DELTA, \"Check min\");\n        assertEquals(0.07200 * 1000, report.getMedian(), DELTA, \"Check median\");\n        assertEquals(0.18900 * 1000, report.get90Line(), DELTA, \"Check line 90\");\n        assertEquals(0.20400 * 1000, report.get95Line(), DELTA, \"Check line 95\");\n        assertEquals(0.52200 * 1000, report.getMax(), DELTA, \"Check max\");\n        assertEquals((long) (0.11568 * 1000), report.getAverage(), \"Check average\");\n        assertEquals(340, report.samplesCount(), DELTA, \"Check samples count\");\n        assertEquals(0.0, report.errorPercent(), DELTA, \"Check errors\");\n    }\n\n    private void checkPerformanceReport(PerformanceReport report) {\n        // Check summary values\n        assertEquals(0.06400 * 1000, report.getMin(), DELTA, \"Check min\");\n        assertEquals(0.18700 * 1000, report.getMedian(), DELTA, \"Check median\");\n        assertEquals(1.15800 * 1000, report.get90Line(), DELTA, \"Check line 90\");\n        assertEquals(1.29300 * 1000, report.get95Line(), DELTA, \"Check line 95\");\n        assertEquals(1.71800 * 1000, report.getMax(), DELTA, \"Check max\");\n        assertEquals((long) (0.45950 * 1000), report.getAverage(), \"Check average\");\n        assertEquals(666 + 11, report.samplesCount(), DELTA, \"Check samples count\");\n        assertEquals(6946463, report.getTotalTrafficInKb(), DELTA, \"Check total KB\");\n    }\n\n    private void checkReportDiff(PerformanceReport report) {\n        // Check summary values\n        assertEquals(-14.0, report.getMedianDiff(), DELTA, \"Check diff median\");\n        assertEquals(-400, report.getAverageDiff(), \"Check diff average\");\n        assertEquals(213, report.get90LineDiff(), \"Check diff line 90\");\n        assertEquals(348, report.get95LineDiff(), \"Check diff line 95\");\n        assertEquals(232, report.getSamplesCountDiff(), \"Check diff samples count\");\n    }\n\n    @Test\n    void testGlobPattern() throws Exception {\n        assertEquals(\"**/*.xml\", new TaurusParser(\"\", PerformanceReportTest.DEFAULT_PERCENTILES).getDefaultGlobPattern());\n    }\n}"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/parsers/WrkSummarizerParserTest.java",
    "content": "package hudson.plugins.performance.parsers;\n\nimport hudson.model.TaskListener;\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson.plugins.performance.reports.PerformanceReportTest;\nimport hudson.util.StreamTaskListener;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\n\nimport java.io.File;\nimport java.nio.charset.StandardCharsets;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\n\nimport static org.junit.jupiter.api.Assertions.assertDoesNotThrow;\nimport static org.junit.jupiter.api.Assertions.assertEquals;\nimport static org.junit.jupiter.api.Assertions.assertFalse;\nimport static org.junit.jupiter.api.Assertions.assertTrue;\n\nclass WrkSummarizerParserTest {\n\n    private WrkSummarizerParser parser;\n    private TaskListener listener;\n\n    @BeforeEach\n    void before() {\n        parser = new WrkSummarizerParser(null, PerformanceReportTest.DEFAULT_PERCENTILES);\n        listener = new StreamTaskListener((java.io.OutputStream) System.out, StandardCharsets.UTF_8);\n    }\n\n    @Test\n    void testParseResultsWithMilliSecondResponseTimes() {\n        List<File> files = new ArrayList<File>(1);\n        files.add(new File(getClass().getResource(\"/WrkResultsQuick.wrk\").getFile()));\n\n        assertDoesNotThrow(() -> {\n            Collection<PerformanceReport> reports = parser.parse(null, files,\n                    listener);\n            assertFalse(reports.isEmpty());\n            for (PerformanceReport report : reports) {\n                // should not have average time >= 1s\n                assertTrue(report.getAverage() < 1000);\n            }\n        });\n    }\n\n    @Test\n    void testParseResultsWithSecondResponseTimes() {\n        List<File> files = new ArrayList<File>(1);\n        files.add(new File(getClass().getResource(\"/WrkResultsLong.wrk\").getFile()));\n\n        assertDoesNotThrow(() -> {\n            Collection<PerformanceReport> reports = parser.parse(null, files, listener);\n            assertFalse(reports.isEmpty());\n            for (PerformanceReport report : reports) {\n                // should have average time >= 1s\n                assertTrue(report.getAverage() >= 1000);\n            }\n        });\n    }\n\n    @Test\n    void testParseWithLatencyDistributionBuckets() {\n        List<File> files = new ArrayList<File>(1);\n        files.add(new File(getClass().getResource(\"/WrkResultsWithLatencyFlag.wrk\").getFile()));\n\n        assertDoesNotThrow(() -> {\n            Collection<PerformanceReport> reports = parser.parse(null, files, listener);\n            assertFalse(reports.isEmpty());\n        });\n    }\n\n    @Test\n    void testParseWithErrors() {\n        List<File> files = new ArrayList<File>(1);\n        files.add(new File(getClass().getResource(\"/WrkResultsWithErrors.wrk\").getFile()));\n\n        assertDoesNotThrow(() -> {\n            Collection<PerformanceReport> reports = parser.parse(null, files, listener);\n            assertFalse(reports.isEmpty());\n\n            // NOTE: uncomment once this is intentionally supported. Currently some\n            //       refactoring is needed with summarized reports.\n            // for(PerformanceReport report: reports) {\n            //   assertTrue(report.countErrors() > 0);\n            // }\n        });\n    }\n\n    @Test\n    void testParseTimeMeasurements() {\n        // milliseconds\n        assertEquals(5, parser.getTime(\"5ms\", WrkSummarizerParser.TimeUnit.MILLISECOND));\n        assertEquals(5000, parser.getTime(\"5s\", WrkSummarizerParser.TimeUnit.MILLISECOND));\n        assertEquals(5000 * 60, parser.getTime(\"5m\", WrkSummarizerParser.TimeUnit.MILLISECOND));\n        assertEquals(1000 * 60 * 60, parser.getTime(\"1h\", WrkSummarizerParser.TimeUnit.MILLISECOND));\n\n        // seconds\n        assertEquals(1, parser.getTime(\"1005ms\", WrkSummarizerParser.TimeUnit.SECOND));\n        assertEquals(5, parser.getTime(\"5s\", WrkSummarizerParser.TimeUnit.SECOND));\n        assertEquals(5 * 60, parser.getTime(\"5m\", WrkSummarizerParser.TimeUnit.SECOND));\n        assertEquals(60 * 60, parser.getTime(\"1h\", WrkSummarizerParser.TimeUnit.SECOND));\n\n        // minute\n        assertEquals(0, parser.getTime(\"5ms\", WrkSummarizerParser.TimeUnit.MINUTE));\n        assertEquals((int) Math.floor(5 / 60.0), parser.getTime(\"5s\", WrkSummarizerParser.TimeUnit.MINUTE));\n        assertEquals((int) Math.floor((5 * 60) / 60.0), parser.getTime(\"5m\", WrkSummarizerParser.TimeUnit.MINUTE));\n        assertEquals((int) Math.floor((60 * 60) / 60.0), parser.getTime(\"1h\", WrkSummarizerParser.TimeUnit.MINUTE));\n\n        // hour\n        assertEquals(0, parser.getTime(\"5ms\", WrkSummarizerParser.TimeUnit.HOUR));\n        assertEquals((int) Math.floor(5 / (60.0 * 60.0)), parser.getTime(\"5s\", WrkSummarizerParser.TimeUnit.HOUR));\n        assertEquals((int) Math.floor((5 * 60) / (60.0 * 60.0)), parser.getTime(\"5m\", WrkSummarizerParser.TimeUnit.HOUR));\n        assertEquals((int) Math.floor((60 * 60) / (60.0 * 60.0)), parser.getTime(\"1h\", WrkSummarizerParser.TimeUnit.HOUR));\n    }\n}\n"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/reports/ConstraintReportTest.java",
    "content": "package hudson.plugins.performance.reports;\n\nimport hudson.FilePath;\nimport hudson.model.AbstractBuild;\nimport hudson.model.Result;\nimport hudson.plugins.performance.constraints.AbsoluteConstraint;\nimport hudson.plugins.performance.constraints.AbstractConstraint.Escalation;\nimport hudson.plugins.performance.constraints.AbstractConstraint.Metric;\nimport hudson.plugins.performance.constraints.AbstractConstraint.Operator;\nimport hudson.plugins.performance.constraints.ConstraintEvaluation;\nimport hudson.plugins.performance.constraints.RelativeConstraint;\nimport jenkins.model.Jenkins;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.mockito.Mock;\nimport org.mockito.MockedStatic;\nimport org.mockito.Mockito;\nimport org.mockito.junit.jupiter.MockitoExtension;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Calendar;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\nimport static org.junit.jupiter.api.Assertions.assertTrue;\nimport static org.mockito.Mockito.when;\n\n@ExtendWith(MockitoExtension.class)\nclass ConstraintReportTest {\n\n    @Mock\n    ArrayList<ConstraintEvaluation> ceList;\n\n    @Mock\n    ConstraintEvaluation ce0;\n    @Mock\n    ConstraintEvaluation ce1;\n    @Mock\n    ConstraintEvaluation ce2;\n    @Mock\n    ConstraintEvaluation ce3;\n    @Mock\n    ConstraintEvaluation ce4;\n    @Mock\n    ConstraintEvaluation ce5;\n\n    @Mock\n    RelativeConstraint rc0;\n    @Mock\n    RelativeConstraint rc1;\n    @Mock\n    RelativeConstraint rc2;\n    @Mock\n    AbsoluteConstraint ac3;\n    @Mock\n    AbsoluteConstraint ac4;\n    @Mock\n    AbsoluteConstraint ac5;\n\n    @Mock\n    Calendar calendar;\n\n    @Mock\n    FilePath filePath;\n\n    @SuppressWarnings(\"rawtypes\")\n    @Mock\n    AbstractBuild globBuild;\n\n    //Result Messages\n    String resultMsgRc0 = \"Relative constraint failed! - Report: Result.xml \\n\" +\n            \"The constraint says: Average of all test cases must not be greater than 110 \\n\" +\n            \"Measured value for Average: 120 \\n\" +\n            \"Included builds: 3 builds \\n\" +\n            \"Escalation Level: Warning\";\n    String resultMsgRc1 = \"Relative constraint successful! - Report: Result.xml \\n\" +\n            \"The constraint says: Average of all test cases must not be less than 1 \\n\" +\n            \"Measured value for Average: 120 \\n\" +\n            \"Included builds: 3 builds \\n\" +\n            \"Escalation Level: Warning\";\n    String resultMsgRc2 = \"Relative constraint failed! - Report: Result.xml \\n\" +\n            \"The constraint says: Maximum of all test cases must not be greater than 990 \\n\" +\n            \"Measured value for Maximum: 1000 \\n\" +\n            \"Included builds: 3 builds \\n\" +\n            \"Escalation Level: Warning\";\n    String resultMsgAc3 = \"Absolute constraint successful! - Report: Result.xml \\n \" +\n            \"The constraint says: Average of checkTickets must not be greater than 100 \\n \" +\n            \"Measured value for Average: 9 \\n \" +\n            \"Escalation Level: Error\";\n    String resultMsgAc4 = \"Absolute constraint failed! - Report: Result.xml \\n \" +\n            \"The constraint says: Average of checkTickets must not be less than 100 \\n \" +\n            \"Measured value for Average: 9 \\n \" +\n            \"Escalation Level: Information\";\n    String resultMsgAc5 = \"Absolute constraint successful! - Report: Result.xml \\n \" +\n            \"The constraint says: Average of checkTickets must not be equal than 9 \\n \" +\n            \"Measured value for Average: 9 \\n \" +\n            \"Escalation Level: Warning\";\n\n    final MockedStatic<Jenkins> staticJenkins = Mockito.mockStatic(Jenkins.class);\n\n    @BeforeEach\n    void setUp() throws IOException, InterruptedException {\n        when(ce0.getAbstractConstraint()).thenReturn(rc0);\n        when(ce1.getAbstractConstraint()).thenReturn(rc1);\n        when(ce2.getAbstractConstraint()).thenReturn(rc2);\n        when(ce3.getAbstractConstraint()).thenReturn(ac3);\n        when(ce4.getAbstractConstraint()).thenReturn(ac4);\n        when(ce5.getAbstractConstraint()).thenReturn(ac5);\n\n        when(rc0.getEscalationLevel()).thenReturn(Escalation.WARNING);\n        when(rc1.getEscalationLevel()).thenReturn(Escalation.WARNING);\n        when(rc2.getEscalationLevel()).thenReturn(Escalation.WARNING);\n        when(ac3.getEscalationLevel()).thenReturn(Escalation.ERROR);\n        when(ac4.getEscalationLevel()).thenReturn(Escalation.INFORMATION);\n        when(ac5.getEscalationLevel()).thenReturn(Escalation.WARNING);\n\n        when(rc0.getSuccess()).thenReturn(false);\n        when(rc1.getSuccess()).thenReturn(true);\n        when(rc2.getSuccess()).thenReturn(false);\n        when(ac3.getSuccess()).thenReturn(true);\n        when(ac4.getSuccess()).thenReturn(false);\n        when(ac5.getSuccess()).thenReturn(true);\n\n        when(rc0.getResultMessage()).thenReturn(resultMsgRc0);\n        when(rc1.getResultMessage()).thenReturn(resultMsgRc1);\n        when(rc2.getResultMessage()).thenReturn(resultMsgRc2);\n        when(ac3.getResultMessage()).thenReturn(resultMsgAc3);\n        when(ac4.getResultMessage()).thenReturn(resultMsgAc4);\n        when(ac5.getResultMessage()).thenReturn(resultMsgAc5);\n\n        when(rc0.getRelatedPerfReport()).thenReturn(\"Result.xml\");\n        when(rc1.getRelatedPerfReport()).thenReturn(\"Result.xml\");\n        when(rc2.getRelatedPerfReport()).thenReturn(\"Result.xml\");\n        when(ac3.getRelatedPerfReport()).thenReturn(\"Result.xml\");\n        when(ac4.getRelatedPerfReport()).thenReturn(\"Result.xml\");\n        when(ac5.getRelatedPerfReport()).thenReturn(\"Result.xml\");\n\n        when(rc0.getOperator()).thenReturn(Operator.NOT_GREATER);\n        when(rc2.getOperator()).thenReturn(Operator.NOT_GREATER);\n        when(ac4.getOperator()).thenReturn(Operator.NOT_LESS);\n\n        when(rc0.getMeteredValue()).thenReturn(Metric.AVERAGE);\n        when(rc2.getMeteredValue()).thenReturn(Metric.MAXIMUM);\n        when(ac4.getMeteredValue()).thenReturn(Metric.AVERAGE);\n\n        when(globBuild.getNumber()).thenReturn(42);\n        when(globBuild.getTimestamp()).thenReturn(calendar);\n\n        filePath = Mockito.mock(FilePath.class);\n\n        final Jenkins jenkins = Mockito.mock(Jenkins.class);\n        staticJenkins.when(Jenkins::get).thenReturn(jenkins);\n        when(jenkins.getRootUrl()).thenReturn(\"test-jenkins-rooturl\");\n    }\n\n    @AfterEach\n    void tearDown() {\n        staticJenkins.closeOnDemand();\n    }\n\n    @Test\n    void happyPathWithoutConstraintLog() throws IOException, InterruptedException {\n\n        ceList = new ArrayList<ConstraintEvaluation>();\n        ceList.add(ce0);\n        ceList.add(ce1);\n        ceList.add(ce2);\n        ceList.add(ce3);\n        ceList.add(ce4);\n        ceList.add(ce5);\n\n        ConstraintReport result = new ConstraintReport(ceList, globBuild, false);\n\n        assertEquals(6, result.getAllConstraints());\n        assertEquals(3, result.getAbsoluteConstraints());\n        assertEquals(3, result.getRelativeConstraints());\n        assertEquals(3, result.getSuccessfulConstraints());\n        assertEquals(3, result.getViolatedConstraints());\n        assertEquals(0, result.getViolatedError());\n        assertEquals(2, result.getViolatedUnstable());\n        assertEquals(1, result.getViolatedInformation());\n        assertEquals(result.getAllConstraints(), result.getSuccessfulConstraints() + result.getViolatedConstraints());\n        assertEquals(result.getAllConstraints(), result.getAbsoluteConstraints() + result.getRelativeConstraints());\n        assertEquals(result.getViolatedConstraints(), result.getViolatedError() + result.getViolatedUnstable() + result.getViolatedInformation());\n        assertEquals(Result.UNSTABLE, result.getBuildResult());\n        assertEquals(42, result.getBuildNumber());\n    }\n\n    @Test\n    void happyPathWithConstraintLog() throws IOException, InterruptedException {\n        ceList = new ArrayList<ConstraintEvaluation>();\n        ceList.add(ce0);\n        ceList.add(ce1);\n        ceList.add(ce2);\n        ceList.add(ce3);\n        ceList.add(ce4);\n        ceList.add(ce5);\n\n        ConstraintReport result = new ConstraintReport(ceList, globBuild, true);\n        File f = result.getPerformanceLog();\n        //checking existence of file\n        assertTrue(f.exists());\n\n        String s = result.getLoggerMsgAdv();\n        //checking content of loggerMsg\n        assertTrue(s.contains(\"Number of all constraints: 6\\nRelative constraints: 3\\nAbsolute constraints: 3\\nSuccessful constraints: 3\\nViolated constraints: 3\\n->INFORMATION: 1\\n->UNSTABLE: 2\\n->ERROR: 0\\n-------------- \\n----------------------------------------------------------- \\nEvaluating all relative constraints! \\n-------------- \\nRelative constraint failed! - Report: Result.xml \\nThe constraint says: Average of all test cases must not be greater than 110 \\nMeasured value for Average: 120 \\nIncluded builds: 3 builds \\nEscalation Level: Warning\\n-------------- \\nRelative constraint successful! - Report: Result.xml \\nThe constraint says: Average of all test cases must not be less than 1 \\nMeasured value for Average: 120 \\nIncluded builds: 3 builds \\nEscalation Level: Warning\\n-------------- \\nRelative constraint failed! - Report: Result.xml \\nThe constraint says: Maximum of all test cases must not be greater than 990 \\nMeasured value for Maximum: 1000 \\nIncluded builds: 3 builds \\nEscalation Level: Warning\\n-------------- \\nEvaluating all absolute constraints! \\n-------------- \\nAbsolute constraint successful! - Report: Result.xml \\n The constraint says: Average of checkTickets must not be greater than 100 \\n Measured value for Average: 9 \\n Escalation Level: Error\\n-------------- \\nAbsolute constraint failed! - Report: Result.xml \\n The constraint says: Average of checkTickets must not be less than 100 \\n Measured value for Average: 9 \\n Escalation Level: Information\\n-------------- \\nAbsolute constraint successful! - Report: Result.xml \\n The constraint says: Average of checkTickets must not be equal than 9 \\n Measured value for Average: 9 \\n Escalation Level: Warning\\n-------------- \\nThe highest escalation: Warning! The build will be marked as UNSTABLE\\n\\n\"));\n\n        // remove 'null' directory and including folders\n        f.delete();\n        f.getParentFile().delete();\n        f.getParentFile().getParentFile().delete();\n\n        assertTrue(result.getJunitReport().contains(\"<testsuite tests=\\\"6\\\" failures=\\\"3\\\" >\"));\n    }\n\n}\n"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/reports/PerformanceReportTest.java",
    "content": "package hudson.plugins.performance.reports;\n\nimport hudson.plugins.performance.actions.PerformanceBuildAction;\nimport hudson.plugins.performance.data.HttpSample;\nimport hudson.plugins.performance.data.TaurusFinalStats;\nimport hudson.plugins.performance.parsers.JMeterParser;\nimport hudson.plugins.performance.parsers.JUnitParser;\nimport hudson.util.StreamTaskListener;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.PrintStream;\nimport java.net.URISyntaxException;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Collections;\nimport java.util.Date;\nimport java.util.List;\nimport java.util.Map;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\nimport static org.junit.jupiter.api.Assertions.assertFalse;\nimport static org.junit.jupiter.api.Assertions.assertNotNull;\nimport static org.junit.jupiter.api.Assertions.assertThrows;\nimport static org.junit.jupiter.api.Assertions.assertTrue;\n\npublic class PerformanceReportTest {\n    public static final String DEFAULT_PERCENTILES = \"0,50,90,95,100\";\n\n    private PerformanceReport performanceReport;\n\n    @BeforeEach\n    void setUp() throws Exception {\n        PerformanceBuildAction buildAction = Mockito.mock(PerformanceBuildAction.class);\n        performanceReport = new PerformanceReport(DEFAULT_PERCENTILES);\n        performanceReport.setBuildAction(buildAction);\n    }\n\n    @Test\n    void testAddSample() throws Exception {\n        PrintStream printStream = Mockito.mock(PrintStream.class);\n        Mockito.when(\n                performanceReport.getBuildAction().getHudsonConsoleWriter())\n                .thenReturn(printStream);\n        printStream\n                .println(\"label cannot be empty, please ensure your jmx file specifies name properly for each http sample: skipping sample\");\n\n        HttpSample sample1 = new HttpSample();\n        sample1.setDate(new Date());\n        performanceReport.addSample(sample1);\n\n        sample1.setUri(\"invalidCharacter/\");\n        performanceReport.addSample(sample1);\n        UriReport uriReport = performanceReport.getUriReportMap().get(\n                \"invalidCharacter_\");\n        assertNotNull(uriReport);\n\n        String uri = \"uri\";\n        sample1.setUri(uri);\n        performanceReport.addSample(sample1);\n        Map<String, UriReport> uriReportMap = performanceReport\n                .getUriReportMap();\n        uriReport = uriReportMap.get(uri);\n        assertNotNull(uriReport);\n        List<Long> durations = uriReport.getDurations();\n        assertEquals(1, durations.size());\n        assertEquals(sample1.getUri(), uriReport.getUri());\n    }\n\n    @Test\n    void testAddTaurusSample() throws Exception {\n        PrintStream printStream = Mockito.mock(PrintStream.class);\n        Mockito.when(\n                performanceReport.getBuildAction().getHudsonConsoleWriter())\n                .thenReturn(printStream);\n        printStream\n                .println(\"label cannot be empty, please ensure your jmx file specifies name properly for each http sample: skipping sample\");\n\n        TaurusFinalStats sample = new TaurusFinalStats();\n        performanceReport.addSample(sample, true);\n        assertEquals(0, performanceReport.countErrors());\n    }\n\n    @Test\n    void testPerformanceReport() throws IOException, URISyntaxException {\n        PerformanceReport performanceReport = parseOneJMeter(new File(getClass().getResource(\"/JMeterResults.jtl\").toURI()));\n        Map<String, UriReport> uriReportMap = performanceReport\n                .getUriReportMap();\n        assertEquals(2, uriReportMap.size());\n        String loginUri = \"Home\";\n        UriReport firstUriReport = uriReportMap.get(loginUri);\n        assertEquals(loginUri, firstUriReport.getUri());\n        assertEquals(14720, firstUriReport.getDurations().get(0).longValue());\n        assertEquals(1296846792004L, firstUriReport.getStart().getTime());\n        assertFalse(firstUriReport.isFailed());\n        String logoutUri = \"Workgroup\";\n        UriReport secondUriReport = uriReportMap.get(logoutUri);\n        assertEquals(logoutUri, secondUriReport.getUri());\n        assertEquals(278, secondUriReport.getDurations().get(0).longValue());\n        assertEquals(1296846969096L + 58L, secondUriReport.getEnd().getTime());\n        assertFalse(secondUriReport.isFailed());\n    }\n\n    private PerformanceReport parseOneJMeter(File f) throws IOException {\n        return new JMeterParser(\"\", DEFAULT_PERCENTILES).parse(null, Collections.singleton(f),\n                new StreamTaskListener(System.out, StandardCharsets.UTF_8)).iterator().next();\n    }\n\n    private PerformanceReport parseOneJUnit(File f) throws IOException {\n        return new JUnitParser(\"\", PerformanceReportTest.DEFAULT_PERCENTILES).parse(null, Collections.singleton(f),\n                new StreamTaskListener(System.out, StandardCharsets.UTF_8)).iterator().next();\n    }\n\n    @Test\n    void testPerformanceNonHTTPSamplesMultiThread() throws IOException, URISyntaxException {\n        PerformanceReport performanceReport = parseOneJMeter(new File(getClass().getResource(\"/JMeterResultsMultiThread.jtl\").toURI()));\n\n        Map<String, UriReport> uriReportMap = performanceReport\n                .getUriReportMap();\n        assertEquals(1, uriReportMap.size());\n\n        String uri = \"WebService(SOAP) Request\";\n        UriReport report = uriReportMap.get(uri);\n        assertNotNull(report);\n\n        int[] expectedDurations = {894, 1508, 1384, 1581, 996};\n        for (int i = 0; i < expectedDurations.length; i++) {\n            final Long duration = report.getDurations().get(i);\n            assertEquals(expectedDurations[i], duration.intValue());\n        }\n    }\n\n    @Test\n    void testPerformanceReportJUnit() throws IOException, URISyntaxException {\n        PerformanceReport performanceReport = parseOneJUnit(new File(getClass().getResource(\"/TEST-JUnitResults.xml\").toURI()));\n        Map<String, UriReport> uriReportMap = performanceReport\n                .getUriReportMap();\n        assertEquals(5, uriReportMap.size());\n        String firstUri = \"hudson.plugins.performance.UriReportTest.testGetMin\";\n        UriReport firstUriReport = uriReportMap.get(firstUri);\n        assertEquals(firstUri, firstUriReport.getUri());\n        assertEquals(31, firstUriReport.getDurations().get(0).longValue());\n        assertEquals(0L, firstUriReport.getStart().getTime());\n        assertFalse(firstUriReport.isFailed());\n        String lastUri = \"hudson.plugins.performance.UriReportTest.testGetMax\";\n        UriReport secondUriReport = uriReportMap.get(lastUri);\n        assertEquals(lastUri, secondUriReport.getUri());\n        assertEquals(26, secondUriReport.getDurations().get(0).longValue());\n        assertEquals(0L, secondUriReport.getStart().getTime());\n        assertTrue(secondUriReport.isFailed());\n    }\n\n    @Test\n    void testIssue5571() throws IOException, URISyntaxException {\n        PerformanceReport performanceReport = parseOneJUnit(new File(getClass().getResource(\"/jUnitIssue5571.xml\").toURI()));\n\n        Map<String, UriReport> uriReportMap = performanceReport\n                .getUriReportMap();\n        assertEquals(1, uriReportMap.size());\n        String uri = \"junit.framework.JUnit4TestCaseFacade.unknown\";\n        UriReport report = uriReportMap.get(uri);\n        assertEquals(uri, report.getUri());\n        assertEquals(890, report.getDurations().get(0).longValue());\n        assertEquals(50, report.getDurations().get(1).longValue());\n        assertEquals(0L, report.getStart().getTime());\n        assertFalse(report.isFailed());\n        assertEquals(33, report.getMedian());\n    }\n\n    @Test\n    void testPerformanceReportMultiLevel() throws IOException, URISyntaxException {\n        PerformanceReport performanceReport = parseOneJMeter(new File(getClass().getResource(\"/JMeterResultsMultiLevel.jtl\").toURI()));\n        Map<String, UriReport> uriReportMap = performanceReport\n                .getUriReportMap();\n        assertEquals(2, uriReportMap.size());\n        UriReport report = uriReportMap.get(\"Home\");\n        assertNotNull(report);\n    }\n\n    @Test\n    void testGetUriListOrdered() throws IOException, URISyntaxException {\n        PerformanceReport performanceReport = parseOneJMeter(new File(getClass().getResource(\"/JMeterResultsRandomUri.jtl\").toURI()));\n        List<UriReport> uriReports = performanceReport.getUriListOrdered();\n        assertEquals(\"Ant\", uriReports.get(0).getUri());\n    }\n\n    @Test\n    void testCanGetCorrect90LineValue() throws IOException, URISyntaxException {\n        PerformanceReport performanceReport = parseOneJMeter(new File(getClass().getResource(\"/JMeterResultsTenSamples.jtl\").toURI()));\n        assertEquals(9L, performanceReport.get90Line());\n    }\n\n    @Test\n    void testCanGetCorrect95LineValue() throws IOException, URISyntaxException {\n        PerformanceReport performanceReport = parseOneJMeter(new File(getClass().getResource(\"/JMeterResultsTenSamples.jtl\").toURI()));\n        assertEquals(9L, performanceReport.get95Line());\n    }\n\n    @Test\n    void testCanGetCorrect90LineValueWithThreeSamples() throws IOException, URISyntaxException {\n        PerformanceReport performanceReport = parseOneJMeter(new File(getClass().getResource(\"/JMeterResultsThreeSamples.jtl\").toURI()));\n        assertEquals(2L, performanceReport.get90Line());\n    }\n\n    @Test\n    void testCanGetCorrect95LineValueWithThreeSamples() throws IOException, URISyntaxException {\n        PerformanceReport performanceReport = parseOneJMeter(new File(getClass().getResource(\"/JMeterResultsThreeSamples.jtl\").toURI()));\n        assertEquals(2L, performanceReport.get95Line());\n    }\n\n    @Test\n    void testCanGetCorrectMaxValueWithThreeSamples() throws IOException, URISyntaxException {\n        PerformanceReport performanceReport = parseOneJMeter(new File(getClass().getResource(\"/JMeterResultsThreeSamples.jtl\").toURI()));\n        assertEquals(3L, performanceReport.getMax());\n    }\n\n    @Test\n    void testCanGetCorrectMinValueWithThreeSamples() throws IOException, URISyntaxException {\n        PerformanceReport performanceReport = parseOneJMeter(new File(getClass().getResource(\"/JMeterResultsThreeSamples.jtl\").toURI()));\n        assertEquals(1L, performanceReport.getMin());\n    }\n\n    @Test\n    void testCanGetZeroPercentileDurationForEmptySampleFile() throws IOException, URISyntaxException {\n        PerformanceReport performanceReport = parseOneJMeter(new File(getClass().getResource(\"/emptyfile.jtl\").toURI()));\n        assertEquals(0L, performanceReport.getMin());\n    }\n\n    @Test\n    void testCanGetZeroPercentileDurationFromOneSampleFile() throws IOException, URISyntaxException {\n        PerformanceReport performanceReport = parseOneJMeter(new File(getClass().getResource(\"/JMeterResultsOneSample.jtl\").toURI()));\n        assertEquals(2L, performanceReport.getDurationAt(0));\n    }\n\n    @Test\n    void testCanGetOneHundredPercentileDurationFromOneSampleFile() throws IOException, URISyntaxException {\n        PerformanceReport performanceReport = parseOneJMeter(new File(getClass().getResource(\"/JMeterResultsOneSample.jtl\").toURI()));\n        assertEquals(2L, performanceReport.getDurationAt(100));\n    }\n\n    @Test\n    void testCannotGetDurationForNegativePercentile() throws IOException, URISyntaxException {\n        PerformanceReport performanceReport = parseOneJMeter(new File(getClass().getResource(\"/JMeterResultsThreeSamples.jtl\").toURI()));\n        assertThrows(IllegalArgumentException.class, () ->\n            performanceReport.getDurationAt(-1));\n    }\n\n    @Test\n    void testCannotGetDurationForMoreThan100Percentile() throws IOException, URISyntaxException {\n        PerformanceReport performanceReport = parseOneJMeter(new File(getClass().getResource(\"/JMeterResultsThreeSamples.jtl\").toURI()));\n        assertThrows(IllegalArgumentException.class, () ->\n            performanceReport.getDurationAt(101));\n    }\n\n    @Test\n    void testCompare() {\n        PerformanceReport report = new PerformanceReport(DEFAULT_PERCENTILES);\n        report.setReportFileName(\"aaaaaa\");\n        PerformanceReport report1 = new PerformanceReport(DEFAULT_PERCENTILES);\n        report1.setReportFileName(\"bbbbb\");\n        assertEquals(-1, report.compareTo(report1));\n        assertEquals(1, report1.compareTo(report));\n        assertEquals(0, report1.compareTo(report1));\n    }\n\n    @Test\n    void testExcludeResponseTimeOfErroredSamples() throws Exception {\n        PerformanceReport report = new PerformanceReport(DEFAULT_PERCENTILES);\n        report.setExcludeResponseTime(false);\n\n        HttpSample sample1 = new HttpSample();\n        sample1.setUri(\"\");\n        sample1.setDate(new Date());\n        sample1.setDuration(100);\n        sample1.setSuccessful(true);\n        report.addSample(sample1);\n\n        HttpSample sample2 = new HttpSample();\n        sample2.setUri(\"\");\n        sample2.setDate(new Date());\n        sample2.setDuration(100);\n        sample2.setSuccessful(false);\n        report.addSample(sample2);\n\n        assertEquals(100, report.getAverage());\n        assertEquals(100, report.getUriReportMap().get(\"\").getAverage());\n\n\n        report = new PerformanceReport(DEFAULT_PERCENTILES);\n        report.setExcludeResponseTime(true);\n        report.addSample(sample1);\n        report.addSample(sample2);\n\n        HttpSample sample3 = new HttpSample();\n        sample3.setUri(\"\");\n        sample3.setDate(new Date());\n        sample3.setDuration(300);\n        sample3.setSuccessful(true);\n        report.addSample(sample3);\n\n        HttpSample sample4 = new HttpSample();\n        sample4.setUri(\"\");\n        sample4.setDate(new Date());\n        sample4.setDuration(100000);\n        sample4.setSuccessful(false);\n        report.addSample(sample4);\n\n        assertEquals(100, report.getAverage());\n        assertEquals(100, report.getUriReportMap().get(\"\").getAverage());\n\n        report = new PerformanceReport(DEFAULT_PERCENTILES);\n        report.setExcludeResponseTime(true);\n        report.addSample(sample2);\n        report.addSample(sample4);\n        assertEquals(0, report.getAverage());\n    }\n\n    @Test\n    void testDivisionByZero() throws Exception {\n        PerformanceReport report = new PerformanceReport(DEFAULT_PERCENTILES);\n        report.setExcludeResponseTime(false);\n\n        TaurusFinalStats stats = new TaurusFinalStats();\n        stats.setLabel(\"aaaa\");\n        stats.setFail(5);\n        stats.setSucc(5);\n        stats.setTestDuration(10d);\n\n        report.addSample(stats, true);\n        assertEquals(10, report.getThroughput().longValue());\n    }\n}\n"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/reports/ThroughputReportTest.java",
    "content": "package hudson.plugins.performance.reports;\n\nimport hudson.plugins.performance.data.HttpSample;\nimport hudson.plugins.performance.data.TaurusFinalStats;\nimport hudson.plugins.performance.parsers.TaurusParser;\nimport hudson.util.StreamTaskListener;\nimport org.junit.jupiter.api.Test;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.net.URISyntaxException;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Collections;\nimport java.util.Date;\nimport java.util.Map;\n\nimport static hudson.plugins.performance.reports.PerformanceReportTest.DEFAULT_PERCENTILES;\nimport static org.junit.jupiter.api.Assertions.assertEquals;\n\n/**\n * @author Artem Stasiuk (artem.stasuk@gmail.com)\n */\nclass ThroughputReportTest {\n\n    private static final double DELTA = 0.000001;\n    private PerformanceReport performanceReport = new PerformanceReport(DEFAULT_PERCENTILES);\n\n    private ThroughputReport throughputReport = new ThroughputReport(performanceReport);\n\n    @Test\n    void shouldReturnZeroIfNoUri() {\n        assertEquals(0.0, throughputReport.get(), DELTA);\n    }\n\n    @Test\n    void shouldSummarizeThroughputByDifferentUri() {\n        HttpSample httpSample1 = new HttpSample();\n        Date date = new Date();\n        httpSample1.setDate(date);\n\n        UriReport uriReport1 = new UriReport(performanceReport, \"f\", \"url1\");\n        uriReport1.addHttpSample(httpSample1);\n\n        HttpSample httpSample2 = new HttpSample();\n        httpSample2.setDate(date);\n\n        UriReport uriReport2 = new UriReport(performanceReport, \"f\", \"url2\");\n        uriReport2.addHttpSample(httpSample2);\n\n        performanceReport.getUriReportMap().clear();\n        performanceReport.getUriReportMap().put(uriReport1.getUri(), uriReport1);\n        performanceReport.getUriReportMap().put(uriReport2.getUri(), uriReport2);\n\n        assertEquals(2.0, throughputReport.get(), DELTA);\n    }\n\n    @Test\n    void shouldSummarizeThroughputUnder1ByDifferentUri() {\n        HttpSample httpSample1 = new HttpSample();\n        Date date = new Date();\n        httpSample1.setDate(date);\n        httpSample1.setDuration(1100);\n\n        PerformanceReport report = new PerformanceReport(DEFAULT_PERCENTILES);\n\n        UriReport uriReport1 = new UriReport(report, \"f\", \"url1\");\n        uriReport1.addHttpSample(httpSample1);\n\n        HttpSample httpSample2 = new HttpSample();\n        httpSample2.setDate(date);\n        httpSample2.setDuration(1100);\n\n        UriReport uriReport2 = new UriReport(report, \"f\", \"url2\");\n        uriReport2.addHttpSample(httpSample2);\n\n        performanceReport.getUriReportMap().clear();\n        performanceReport.getUriReportMap().put(uriReport1.getUri(), uriReport1);\n        performanceReport.getUriReportMap().put(uriReport2.getUri(), uriReport2);\n\n        assertEquals(2.0 / 1100 * 1000, throughputReport.get(), DELTA);\n    }\n\n    @Test\n    void testThroughputJMeterReport() throws Exception {\n        long time = System.currentTimeMillis();\n\n        HttpSample firstSample = new HttpSample();\n        firstSample.setDate(new Date(time));\n        firstSample.setDuration(1000);\n\n        HttpSample secondSample = new HttpSample();\n        secondSample.setDate(new Date(time + 2000));\n        secondSample.setDuration(1000);\n\n        HttpSample thirdSample = new HttpSample();\n        thirdSample.setDate(new Date(time + 3000));\n        thirdSample.setDuration(1000);\n\n        HttpSample lastSample = new HttpSample();\n        lastSample.setDate(new Date(time + 8000));\n        lastSample.setDuration(1000);\n\n\n        PerformanceReport report = new PerformanceReport(DEFAULT_PERCENTILES);\n\n        UriReport uriReport1 = new UriReport(report, \"f\", \"url1\");\n        uriReport1.addHttpSample(firstSample);\n        uriReport1.addHttpSample(thirdSample);\n\n\n        UriReport uriReport2 = new UriReport(report, \"f\", \"url2\");\n        uriReport2.addHttpSample(secondSample);\n        uriReport2.addHttpSample(lastSample);\n\n        performanceReport.getUriReportMap().clear();\n        performanceReport.getUriReportMap().put(uriReport1.getUri(), uriReport1);\n        performanceReport.getUriReportMap().put(uriReport2.getUri(), uriReport2);\n\n        assertEquals((4 / (9000.0 / 1000)), throughputReport.get(), DELTA);\n    }\n\n    @Test\n    void testThroughputTaurusReport() throws Exception {\n        performanceReport.getUriReportMap().clear();\n\n        TaurusFinalStats stats = new TaurusFinalStats();\n        stats.setThroughput(777);\n        stats.setLabel(\"777\");\n        performanceReport.addSample(stats, true);\n\n        assertEquals(777, throughputReport.get(), DELTA);\n    }\n\n    @Test\n    void testDuration() throws IOException, URISyntaxException {\n        File report = new File(getClass().getResource(\"/TaurusXmlWithDuration.xml\").getPath());\n        TaurusParser parser = new TaurusParser(report.getAbsolutePath(), DEFAULT_PERCENTILES);\n        PerformanceReport performanceReport = parser.parse(null, Collections.singleton(report), new StreamTaskListener(System.out, StandardCharsets.UTF_8)).iterator().next();\n        ThroughputReport throughputReport = new ThroughputReport(performanceReport);\n\n        Map<String, UriReport> uriReportMap = performanceReport.getUriReportMap();\n        assertEquals(3, uriReportMap.size());\n\n        int samplesCount = 29658 + 29656;\n        long duration = (long) Math.ceil((float)3141 / 1000);\n        assertEquals(samplesCount/ duration, throughputReport.get(), DELTA);\n    }\n\n    @Test\n    void testDurationBackwardCompatibility() throws IOException, URISyntaxException {\n        PerformanceReport performanceReport = new PerformanceReport(DEFAULT_PERCENTILES);\n\n        UriReport report1 = new UriReport(performanceReport, \"f1\", \"uri1\");\n        report1.setThroughput(111L);\n        UriReport report2 = new UriReport(performanceReport, \"f2\", \"uri2\");\n        report2.setThroughput(666L);\n\n        performanceReport.getUriReportMap().put(\"f1\", report1);\n        performanceReport.getUriReportMap().put(\"f2\", report2);\n\n        performanceReport.readResolve();\n        ThroughputReport throughputReport = new ThroughputReport(performanceReport);\n\n        assertEquals(777.0, throughputReport.get(), DELTA);\n    }\n}\n"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/reports/UriReportTest.java",
    "content": "package hudson.plugins.performance.reports;\n\nimport hudson.plugins.performance.data.HttpSample;\nimport hudson.plugins.performance.reports.UriReport.Sample;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Date;\nimport java.util.Iterator;\nimport java.util.List;\n\nimport static org.junit.jupiter.api.Assertions.assertDoesNotThrow;\nimport static org.junit.jupiter.api.Assertions.assertEquals;\nimport static org.junit.jupiter.api.Assertions.assertTrue;\n\nclass UriReportTest {\n\n    private static final String HTTP_200 = \"200\";\n    private static final long AVERAGE = 5;\n    private static final long MIN = 0;\n    private static final long MAX = 10;\n    private UriReport uriReport;\n\n    @BeforeEach\n    void setUp() {\n        PerformanceReport performanceReport = new PerformanceReport(PerformanceReportTest.DEFAULT_PERCENTILES);\n        uriReport = new UriReport(performanceReport, null, null);\n        HttpSample httpSample1 = new HttpSample();\n        httpSample1.setDuration(MAX);\n        Date date = new Date();\n        httpSample1.setDate(date);\n        httpSample1.setSuccessful(false);\n        HttpSample httpSample2 = new HttpSample();\n        httpSample2.setDuration(AVERAGE);\n        httpSample2.setDate(date);\n        httpSample2.setSuccessful(true);\n        HttpSample httpSample3 = new HttpSample();\n        httpSample3.setDuration(MIN);\n        httpSample3.setDate(date);\n        httpSample3.setSuccessful(false);\n        uriReport.addHttpSample(httpSample1);\n        uriReport.addHttpSample(httpSample2);\n        uriReport.addHttpSample(httpSample3);\n    }\n\n    @Test\n    void testHasSamples() throws Exception {\n        assertTrue(uriReport.hasSamples());\n    }\n\n    @Test\n    void testCountErrors() {\n        assertEquals(2, uriReport.countErrors());\n    }\n\n    @Test\n    void testGetAverage() {\n        assertEquals(AVERAGE, uriReport.getAverage());\n    }\n\n    @Test\n    void testGetMax() {\n\t\tassertEquals(MAX, uriReport.getMax());\n\t}\n\n    @Test\n    void testGetMin() {\n\t\tassertEquals(MIN, uriReport.getMin());\n\t}\n\n    @Test\n    void testIsFailed() {\n        assertTrue(uriReport.isFailed());\n    }\n\n    /**\n     * Same dates, different duration. Shortest duration should be ordered first.\n     */\n    @Test\n    void testCompareSameDateDifferentDuration() {\n        // setup fixture\n        final List<Sample> samples = new ArrayList<Sample>();\n        samples.add(new Sample(new Date(1), 2, HTTP_200, true, false));\n        samples.add(new Sample(new Date(1), 1, HTTP_200, true, false));\n\n        // execute system under test\n        Collections.sort(samples);\n\n        // verify result\n        final Iterator<Sample> iter = samples.iterator();\n        assertEquals(1, iter.next().duration);\n        assertEquals(2, iter.next().duration);\n    }\n\n    /**\n     * Different dates, same duration. Oldest date should be ordered first.\n     */\n    @Test\n    void testCompareDifferentDateSameDuration() {\n        // setup fixture\n        final List<Sample> samples = new ArrayList<Sample>();\n        samples.add(new Sample(new Date(2), 1, HTTP_200, true, false));\n        samples.add(new Sample(new Date(1), 1, HTTP_200, true, false));\n\n        // execute system under test\n        Collections.sort(samples);\n\n        // verify result\n        final Iterator<Sample> iter = samples.iterator();\n        assertEquals(1, iter.next().date.getTime());\n        assertEquals(2, iter.next().date.getTime());\n    }\n\n    /**\n     * Different dates, different duration. Shortest duration should be ordered first.\n     */\n    @Test\n    void testCompareDifferentDateDifferentDuration() {\n        // setup fixture\n        final List<Sample> samples = new ArrayList<Sample>();\n        samples.add(new Sample(new Date(1), 2, HTTP_200, true, false));\n        samples.add(new Sample(new Date(2), 1, HTTP_200, true, false));\n\n        // execute system under test\n        Collections.sort(samples);\n\n        // verify result\n        final Iterator<Sample> iter = samples.iterator();\n        assertEquals(1, iter.next().duration);\n        assertEquals(2, iter.next().duration);\n    }\n\n    /**\n     * Null dates. Ordering is unspecified, but should not cause exceptions.\n     */\n    @Test\n    void testCompareNullDateSameDuration() {\n        // setup fixture\n        final List<Sample> samples = new ArrayList<Sample>();\n        samples.add(new Sample(null, 1, HTTP_200, true, false));\n        samples.add(new Sample(null, 1, HTTP_200, true, false));\n\n        assertDoesNotThrow(() -> {\n            // execute system under test\n            Collections.sort(samples);\n        }, \"A NullPointerException was thrown (which should not have happened).\");\n    }\n}\n"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/tools/SafeMathsTest.java",
    "content": "package hudson.plugins.performance.tools;\n\nimport org.junit.jupiter.api.Test;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\n\nclass SafeMathsTest {\n\n    @Test\n    void safeDivideDividendIsNaN() {\n\t\tfinal double expected = Double.NaN;\n\t\tfinal double actual = SafeMaths.safeDivide(Double.NaN, 10);\n\t\tassertEquals(expected, actual, 0);\n\t}\n\n    @Test\n    void safeDivideDivisorIsNaN() {\n\t\tfinal double expected = Double.NaN;\n\t\tfinal double actual = SafeMaths.safeDivide(10, Double.NaN);\n\t\tassertEquals(expected, actual, 0);\n\t}\n\n    @Test\n    void safeDivideDivisorIsNullPositivePositive() {\n\t\tfinal double expected = Double.POSITIVE_INFINITY;\n\t\tfinal double actual = SafeMaths.safeDivide(10, 0);\n\t\tassertEquals(expected, actual, 0);\n\t}\n\n    @Test\n    void safeDivideDivisorIsNullNegativePositive() {\n\t\tfinal double expected = Double.NEGATIVE_INFINITY;\n\t\tfinal double actual = SafeMaths.safeDivide(-10, 0);\n\t\tassertEquals(expected, actual, 0);\n\t}\n\n    @Test\n    void safeDivideHappyPath() {\n\t\tfinal double expected = 2;\n\t\tfinal double actual = SafeMaths.safeDivide(10, 5);\n\t\tassertEquals(expected, actual, 0);\n\t}\n}\n"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/workflow/WorkflowActionsFactoryTest.java",
    "content": "package hudson.plugins.performance.workflow;\n\nimport hudson.model.Action;\nimport hudson.model.Job;\nimport hudson.model.Result;\nimport hudson.plugins.performance.actions.PerformanceProjectAction;\nimport hudson.slaves.DumbSlave;\nimport org.apache.commons.io.IOUtils;\nimport org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;\nimport org.jenkinsci.plugins.workflow.job.WorkflowJob;\nimport org.jenkinsci.plugins.workflow.job.WorkflowRun;\nimport org.junit.jupiter.api.Test;\nimport org.jvnet.hudson.test.JenkinsRule;\nimport org.jvnet.hudson.test.junit.jupiter.WithJenkins;\n\nimport java.net.URL;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Collection;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\n\n@WithJenkins\nclass WorkflowActionsFactoryTest {\n    private final WorkflowActionsFactory factory = new WorkflowActionsFactory();\n\n    @Test\n    void testFlow(JenkinsRule rule) throws Exception {\n        assertEquals(Job.class, factory.type());\n\n        DumbSlave s = rule.createOnlineSlave();\n        s.setLabelString(\"test performance report DSL function\");\n        WorkflowJob p = rule.jenkins.createProject(WorkflowJob.class, \"demo\");\n        p.setDefinition(new CpsFlowDefinition(\n                \"node{ echo 'hi, world!' }\", true));\n        WorkflowRun r = p.scheduleBuild2(0).waitForStart();\n        rule.assertBuildStatus(Result.SUCCESS, rule.waitForCompletion(r));\n        r = p.scheduleBuild2(1).waitForStart();\n        rule.assertBuildStatus(Result.SUCCESS, rule.waitForCompletion(r));\n        Collection<? extends Action> actions = factory.createFor(p);\n        assertEquals(0, actions.size());\n    }\n\n    @Test\n    void testFlowWithProjectAction(JenkinsRule rule) throws Exception {\n        String fileContents = null;\n\n        URL url = getClass().getResource(\"/TaurusXMLReport.xml\");\n        if (url != null) {\n            fileContents = IOUtils.toString(url, StandardCharsets.UTF_8);\n        }\n        final String report = fileContents;\n\n        DumbSlave s = rule.createOnlineSlave();\n        s.setLabelString(\"test performance report DSL function\");\n        WorkflowJob p = rule.createProject(WorkflowJob.class, \"demo2\");\n        p.setDefinition(new CpsFlowDefinition(\n                \"node{ writeFile file: 'test.xml', text: '''\" + report\n                        + \"'''; perfReport errorFailedThreshold: 2, errorUnstableThreshold: 2, sourceDataFiles: 'test.xml' }\",\n                true));\n        WorkflowRun r = p.scheduleBuild2(0).waitForStart();\n        rule.assertBuildStatus(Result.SUCCESS, rule.waitForCompletion(r));\n        r = p.scheduleBuild2(1).waitForStart();\n        rule.assertBuildStatus(Result.SUCCESS, rule.waitForCompletion(r));\n        Collection<? extends Action> actions = factory.createFor(p);\n        assertEquals(1, actions.size());\n        assertEquals(PerformanceProjectAction.class, actions.toArray()[0].getClass());\n    }\n}"
  },
  {
    "path": "src/test/resources/IagoResults.log",
    "content": "INF [20140611-21:34:01.224] stats: {\"400\":84,\"client\\/available\":1,\"client\\/cancelled_connects\":0,\"client\\/closechans\":85,\"client\\/closed\":85,\"client\\/closes\":84,\"client\\/codec_connection_preparation_latency_ms_average\":3,\"client\\/codec_connection_preparation_latency_ms_count\":85,\"client\\/codec_connection_preparation_latency_ms_maximum\":142,\"client\\/codec_connection_preparation_latency_ms_minimum\":1,\"client\\/codec_connection_preparation_latency_ms_p50\":2,\"client\\/codec_connection_preparation_latency_ms_p90\":4,\"client\\/codec_connection_preparation_latency_ms_p95\":4,\"client\\/codec_connection_preparation_latency_ms_p99\":142,\"client\\/codec_connection_preparation_latency_ms_p999\":142,\"client\\/codec_connection_preparation_latency_ms_p9999\":142,\"client\\/codec_connection_preparation_latency_ms_sum\":316,\"client\\/connect_latency_ms_average\":2,\"client\\/connect_latency_ms_count\":85,\"client\\/connect_latency_ms_maximum\":142,\"client\\/connect_latency_ms_minimum\":0,\"client\\/connect_latency_ms_p50\":1,\"client\\/connect_latency_ms_p90\":2,\"client\\/connect_latency_ms_p95\":4,\"client\\/connect_latency_ms_p99\":142,\"client\\/connect_latency_ms_p999\":142,\"client\\/connect_latency_ms_p9999\":142,\"client\\/connect_latency_ms_sum\":238,\"client\\/connection_duration_average\":5,\"client\\/connection_duration_count\":85,\"client\\/connection_duration_maximum\":173,\"client\\/connection_duration_minimum\":2,\"client\\/connection_duration_p50\":3,\"client\\/connection_duration_p90\":6,\"client\\/connection_duration_p95\":7,\"client\\/connection_duration_p99\":173,\"client\\/connection_duration_p999\":173,\"client\\/connection_duration_p9999\":173,\"client\\/connection_duration_sum\":477,\"client\\/connection_received_bytes_average\":604,\"client\\/connection_received_bytes_count\":85,\"client\\/connection_received_bytes_maximum\":576,\"client\\/connection_received_bytes_minimum\":576,\"client\\/connection_received_bytes_p50\":576,\"client\\/connection_received_bytes_p90\":576,\"client\\/connection_received_bytes_p95\":576,\"client\\/connection_received_bytes_p99\":576,\"client\\/connection_received_bytes_p999\":576,\"client\\/connection_received_bytes_p9999\":576,\"client\\/connection_received_bytes_sum\":51340,\"client\\/connection_requests_average\":1,\"client\\/connection_requests_count\":85,\"client\\/connection_requests_maximum\":1,\"client\\/connection_requests_minimum\":1,\"client\\/connection_requests_p50\":1,\"client\\/connection_requests_p90\":1,\"client\\/connection_requests_p95\":1,\"client\\/connection_requests_p99\":1,\"client\\/connection_requests_p999\":1,\"client\\/connection_requests_p9999\":1,\"client\\/connection_requests_sum\":85,\"client\\/connection_sent_bytes_average\":140,\"client\\/connection_sent_bytes_count\":85,\"client\\/connection_sent_bytes_maximum\":142,\"client\\/connection_sent_bytes_minimum\":142,\"client\\/connection_sent_bytes_p50\":142,\"client\\/connection_sent_bytes_p90\":142,\"client\\/connection_sent_bytes_p95\":142,\"client\\/connection_sent_bytes_p99\":142,\"client\\/connection_sent_bytes_p999\":142,\"client\\/connection_sent_bytes_p9999\":142,\"client\\/connection_sent_bytes_sum\":11919,\"client\\/connections\":0,\"client\\/connects\":85,\"client\\/failed_connect_latency_ms_count\":0,\"client\\/failfast\":0,\"client\\/failfast\\/unhealthy_for_ms\":0,\"client\\/failfast\\/unhealthy_num_tries\":0,\"client\\/failures\":1,\"client\\/failures\\/com.twitter.finagle.ChannelClosedException\":1,\"client\\/idle\":0,\"client\\/jonatstr-dt-otc_80\\/available\":1,\"client\\/jonatstr-dt-otc_80\\/cancelled_connects\":0,\"client\\/jonatstr-dt-otc_80\\/closechans\":85,\"client\\/jonatstr-dt-otc_80\\/closed\":85,\"client\\/jonatstr-dt-otc_80\\/closes\":84,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_average\":2,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_count\":85,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_maximum\":142,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_minimum\":0,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_p50\":1,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_p90\":2,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_p95\":4,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_p99\":142,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_p999\":142,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_p9999\":142,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_sum\":238,\"client\\/jonatstr-dt-otc_80\\/connection_duration_average\":5,\"client\\/jonatstr-dt-otc_80\\/connection_duration_count\":85,\"client\\/jonatstr-dt-otc_80\\/connection_duration_maximum\":173,\"client\\/jonatstr-dt-otc_80\\/connection_duration_minimum\":2,\"client\\/jonatstr-dt-otc_80\\/connection_duration_p50\":3,\"client\\/jonatstr-dt-otc_80\\/connection_duration_p90\":6,\"client\\/jonatstr-dt-otc_80\\/connection_duration_p95\":7,\"client\\/jonatstr-dt-otc_80\\/connection_duration_p99\":173,\"client\\/jonatstr-dt-otc_80\\/connection_duration_p999\":173,\"client\\/jonatstr-dt-otc_80\\/connection_duration_p9999\":173,\"client\\/jonatstr-dt-otc_80\\/connection_duration_sum\":477,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_average\":604,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_count\":85,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_maximum\":576,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_minimum\":576,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_p50\":576,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_p90\":576,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_p95\":576,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_p99\":576,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_p999\":576,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_p9999\":576,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_sum\":51340,\"client\\/jonatstr-dt-otc_80\\/connection_requests_average\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_count\":85,\"client\\/jonatstr-dt-otc_80\\/connection_requests_maximum\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_minimum\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_p50\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_p90\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_p95\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_p99\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_p999\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_p9999\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_sum\":85,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_average\":140,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_count\":85,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_maximum\":142,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_minimum\":142,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_p50\":142,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_p90\":142,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_p95\":142,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_p99\":142,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_p999\":142,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_p9999\":142,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_sum\":11919,\"client\\/jonatstr-dt-otc_80\\/connections\":0,\"client\\/jonatstr-dt-otc_80\\/connects\":85,\"client\\/jonatstr-dt-otc_80\\/failed_connect_latency_ms_count\":0,\"client\\/jonatstr-dt-otc_80\\/failfast\":0,\"client\\/jonatstr-dt-otc_80\\/failfast\\/unhealthy_for_ms\":0,\"client\\/jonatstr-dt-otc_80\\/failfast\\/unhealthy_num_tries\":0,\"client\\/jonatstr-dt-otc_80\\/failures\":1,\"client\\/jonatstr-dt-otc_80\\/failures\\/com.twitter.finagle.ChannelClosedException\":1,\"client\\/jonatstr-dt-otc_80\\/idle\":0,\"client\\/jonatstr-dt-otc_80\\/lifetime\":0,\"client\\/jonatstr-dt-otc_80\\/load\":0,\"client\\/jonatstr-dt-otc_80\\/pending\":0,\"client\\/jonatstr-dt-otc_80\\/pool_cached\":0,\"client\\/jonatstr-dt-otc_80\\/pool_num_waited\":0,\"client\\/jonatstr-dt-otc_80\\/pool_size\":0,\"client\\/jonatstr-dt-otc_80\\/pool_waiters\":0,\"client\\/jonatstr-dt-otc_80\\/received_bytes\":51340,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_average\":3,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_count\":85,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_maximum\":105,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_minimum\":1,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_p50\":2,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_p90\":4,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_p95\":4,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_p99\":105,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_p999\":105,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_p9999\":105,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_sum\":276,\"client\\/jonatstr-dt-otc_80\\/requests\":85,\"client\\/jonatstr-dt-otc_80\\/sent_bytes\":11919,\"client\\/jonatstr-dt-otc_80\\/socket_unwritable_ms\":0,\"client\\/jonatstr-dt-otc_80\\/socket_writable_ms\":207,\"client\\/jonatstr-dt-otc_80\\/success\":84,\"client\\/lifetime\":0,\"client\\/load\":0,\"client\\/loadbalancer\\/adds\":0,\"client\\/loadbalancer\\/available\":1,\"client\\/loadbalancer\\/load\":0,\"client\\/loadbalancer\\/removes\":0,\"client\\/loadbalancer\\/size\":1,\"client\\/pending\":0,\"client\\/pool_cached\":0,\"client\\/pool_num_waited\":0,\"client\\/pool_size\":0,\"client\\/pool_waiters\":0,\"client\\/received_bytes\":51340,\"client\\/request_latency_ms_average\":3,\"client\\/request_latency_ms_count\":85,\"client\\/request_latency_ms_maximum\":105,\"client\\/request_latency_ms_minimum\":1,\"client\\/request_latency_ms_p50\":2,\"client\\/request_latency_ms_p90\":4,\"client\\/request_latency_ms_p95\":4,\"client\\/request_latency_ms_p99\":105,\"client\\/request_latency_ms_p999\":105,\"client\\/request_latency_ms_p9999\":105,\"client\\/request_latency_ms_sum\":276,\"client\\/requests\":85,\"client\\/sent_bytes\":11919,\"client\\/socket_unwritable_ms\":0,\"client\\/socket_writable_ms\":207,\"client\\/success\":84,\"clock_error\":0,\"jvm_buffer_direct_count\":4,\"jvm_buffer_direct_max\":133120,\"jvm_buffer_direct_used\":133120,\"jvm_buffer_mapped_count\":0,\"jvm_buffer_mapped_max\":0,\"jvm_buffer_mapped_used\":0,\"jvm_current_mem_CMS_Old_Gen_max\":3657433088,\"jvm_current_mem_CMS_Old_Gen_used\":12173984,\"jvm_current_mem_CMS_Perm_Gen_max\":85983232,\"jvm_current_mem_CMS_Perm_Gen_used\":44355376,\"jvm_current_mem_Code_Cache_max\":50331648,\"jvm_current_mem_Code_Cache_used\":2425792,\"jvm_current_mem_Eden_Space_max\":429522944,\"jvm_current_mem_Eden_Space_used\":169518376,\"jvm_current_mem_Survivor_Space_max\":53673984,\"jvm_current_mem_Survivor_Space_used\":53673984,\"jvm_current_mem_used\":282147512,\"jvm_fd_count\":142,\"jvm_fd_limit\":4096,\"jvm_gc_ConcurrentMarkSweep_cycles\":0,\"jvm_gc_ConcurrentMarkSweep_msec\":0,\"jvm_gc_Copy_cycles\":0,\"jvm_gc_Copy_msec\":0,\"jvm_gc_cycles\":0,\"jvm_gc_msec\":0,\"jvm_heap_committed\":4140630016,\"jvm_heap_max\":4140630016,\"jvm_heap_used\":235366344,\"jvm_nonheap_committed\":47120384,\"jvm_nonheap_max\":136314880,\"jvm_nonheap_used\":46777704,\"jvm_num_cpus\":1,\"jvm_post_gc_CMS_Old_Gen_max\":3657433088,\"jvm_post_gc_CMS_Old_Gen_used\":0,\"jvm_post_gc_CMS_Perm_Gen_max\":85983232,\"jvm_post_gc_CMS_Perm_Gen_used\":0,\"jvm_post_gc_Eden_Space_max\":429522944,\"jvm_post_gc_Eden_Space_used\":0,\"jvm_post_gc_Survivor_Space_max\":53673984,\"jvm_post_gc_Survivor_Space_used\":53673984,\"jvm_post_gc_used\":53673984,\"jvm_start_time\":1402536778818,\"jvm_thread_count\":18,\"jvm_thread_daemon_count\":12,\"jvm_thread_peak_count\":18,\"jvm_uptime\":62216,\"queue_depth\":41,\"records-read\":126,\"requests_sent\":85,\"service\":\"parrot_web\",\"source\":\"jonatstr-dt-oneconnector\",\"timestamp\":1402536841,\"unexpected_error\":1,\"unexpected_error\\/com.twitter.finagle.ChannelClosedException\":1}\nINF [20140611-21:35:01.077] stats: {\"400\":119,\"client\\/available\":1,\"client\\/cancelled_connects\":0,\"client\\/closechans\":119,\"client\\/closed\":119,\"client\\/closes\":119,\"client\\/codec_connection_preparation_latency_ms_average\":1,\"client\\/codec_connection_preparation_latency_ms_count\":119,\"client\\/codec_connection_preparation_latency_ms_maximum\":8,\"client\\/codec_connection_preparation_latency_ms_minimum\":1,\"client\\/codec_connection_preparation_latency_ms_p50\":1,\"client\\/codec_connection_preparation_latency_ms_p90\":2,\"client\\/codec_connection_preparation_latency_ms_p95\":3,\"client\\/codec_connection_preparation_latency_ms_p99\":6,\"client\\/codec_connection_preparation_latency_ms_p999\":8,\"client\\/codec_connection_preparation_latency_ms_p9999\":8,\"client\\/codec_connection_preparation_latency_ms_sum\":176,\"client\\/connect_latency_ms_average\":0,\"client\\/connect_latency_ms_count\":119,\"client\\/connect_latency_ms_maximum\":7,\"client\\/connect_latency_ms_minimum\":0,\"client\\/connect_latency_ms_p50\":0,\"client\\/connect_latency_ms_p90\":1,\"client\\/connect_latency_ms_p95\":1,\"client\\/connect_latency_ms_p99\":6,\"client\\/connect_latency_ms_p999\":7,\"client\\/connect_latency_ms_p9999\":7,\"client\\/connect_latency_ms_sum\":65,\"client\\/connection_duration_average\":2,\"client\\/connection_duration_count\":119,\"client\\/connection_duration_maximum\":12,\"client\\/connection_duration_minimum\":2,\"client\\/connection_duration_p50\":2,\"client\\/connection_duration_p90\":4,\"client\\/connection_duration_p95\":5,\"client\\/connection_duration_p99\":7,\"client\\/connection_duration_p999\":12,\"client\\/connection_duration_p9999\":12,\"client\\/connection_duration_sum\":295,\"client\\/connection_received_bytes_average\":604,\"client\\/connection_received_bytes_count\":119,\"client\\/connection_received_bytes_maximum\":576,\"client\\/connection_received_bytes_minimum\":576,\"client\\/connection_received_bytes_p50\":576,\"client\\/connection_received_bytes_p90\":576,\"client\\/connection_received_bytes_p95\":576,\"client\\/connection_received_bytes_p99\":576,\"client\\/connection_received_bytes_p999\":576,\"client\\/connection_received_bytes_p9999\":576,\"client\\/connection_received_bytes_sum\":71876,\"client\\/connection_requests_average\":1,\"client\\/connection_requests_count\":119,\"client\\/connection_requests_maximum\":1,\"client\\/connection_requests_minimum\":1,\"client\\/connection_requests_p50\":1,\"client\\/connection_requests_p90\":1,\"client\\/connection_requests_p95\":1,\"client\\/connection_requests_p99\":1,\"client\\/connection_requests_p999\":1,\"client\\/connection_requests_p9999\":1,\"client\\/connection_requests_sum\":119,\"client\\/connection_sent_bytes_average\":140,\"client\\/connection_sent_bytes_count\":119,\"client\\/connection_sent_bytes_maximum\":142,\"client\\/connection_sent_bytes_minimum\":142,\"client\\/connection_sent_bytes_p50\":142,\"client\\/connection_sent_bytes_p90\":142,\"client\\/connection_sent_bytes_p95\":142,\"client\\/connection_sent_bytes_p99\":142,\"client\\/connection_sent_bytes_p999\":142,\"client\\/connection_sent_bytes_p9999\":142,\"client\\/connection_sent_bytes_sum\":16699,\"client\\/connections\":0,\"client\\/connects\":119,\"client\\/failed_connect_latency_ms_count\":0,\"client\\/failfast\":0,\"client\\/failfast\\/unhealthy_for_ms\":0,\"client\\/failfast\\/unhealthy_num_tries\":0,\"client\\/failures\":0,\"client\\/failures\\/com.twitter.finagle.ChannelClosedException\":0,\"client\\/idle\":0,\"client\\/jonatstr-dt-otc_80\\/available\":1,\"client\\/jonatstr-dt-otc_80\\/cancelled_connects\":0,\"client\\/jonatstr-dt-otc_80\\/closechans\":119,\"client\\/jonatstr-dt-otc_80\\/closed\":119,\"client\\/jonatstr-dt-otc_80\\/closes\":119,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_average\":0,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_count\":119,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_maximum\":7,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_minimum\":0,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_p50\":0,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_p90\":1,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_p95\":1,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_p99\":6,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_p999\":7,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_p9999\":7,\"client\\/jonatstr-dt-otc_80\\/connect_latency_ms_sum\":65,\"client\\/jonatstr-dt-otc_80\\/connection_duration_average\":2,\"client\\/jonatstr-dt-otc_80\\/connection_duration_count\":119,\"client\\/jonatstr-dt-otc_80\\/connection_duration_maximum\":12,\"client\\/jonatstr-dt-otc_80\\/connection_duration_minimum\":2,\"client\\/jonatstr-dt-otc_80\\/connection_duration_p50\":2,\"client\\/jonatstr-dt-otc_80\\/connection_duration_p90\":4,\"client\\/jonatstr-dt-otc_80\\/connection_duration_p95\":5,\"client\\/jonatstr-dt-otc_80\\/connection_duration_p99\":7,\"client\\/jonatstr-dt-otc_80\\/connection_duration_p999\":12,\"client\\/jonatstr-dt-otc_80\\/connection_duration_p9999\":12,\"client\\/jonatstr-dt-otc_80\\/connection_duration_sum\":295,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_average\":604,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_count\":119,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_maximum\":576,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_minimum\":576,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_p50\":576,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_p90\":576,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_p95\":576,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_p99\":576,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_p999\":576,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_p9999\":576,\"client\\/jonatstr-dt-otc_80\\/connection_received_bytes_sum\":71876,\"client\\/jonatstr-dt-otc_80\\/connection_requests_average\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_count\":119,\"client\\/jonatstr-dt-otc_80\\/connection_requests_maximum\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_minimum\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_p50\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_p90\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_p95\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_p99\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_p999\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_p9999\":1,\"client\\/jonatstr-dt-otc_80\\/connection_requests_sum\":119,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_average\":140,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_count\":119,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_maximum\":142,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_minimum\":142,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_p50\":142,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_p90\":142,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_p95\":142,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_p99\":142,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_p999\":142,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_p9999\":142,\"client\\/jonatstr-dt-otc_80\\/connection_sent_bytes_sum\":16699,\"client\\/jonatstr-dt-otc_80\\/connections\":0,\"client\\/jonatstr-dt-otc_80\\/connects\":119,\"client\\/jonatstr-dt-otc_80\\/failed_connect_latency_ms_count\":0,\"client\\/jonatstr-dt-otc_80\\/failfast\":0,\"client\\/jonatstr-dt-otc_80\\/failfast\\/unhealthy_for_ms\":0,\"client\\/jonatstr-dt-otc_80\\/failfast\\/unhealthy_num_tries\":0,\"client\\/jonatstr-dt-otc_80\\/failures\":0,\"client\\/jonatstr-dt-otc_80\\/failures\\/com.twitter.finagle.ChannelClosedException\":0,\"client\\/jonatstr-dt-otc_80\\/idle\":0,\"client\\/jonatstr-dt-otc_80\\/lifetime\":0,\"client\\/jonatstr-dt-otc_80\\/load\":0,\"client\\/jonatstr-dt-otc_80\\/pending\":0,\"client\\/jonatstr-dt-otc_80\\/pool_cached\":0,\"client\\/jonatstr-dt-otc_80\\/pool_num_waited\":0,\"client\\/jonatstr-dt-otc_80\\/pool_size\":0,\"client\\/jonatstr-dt-otc_80\\/pool_waiters\":0,\"client\\/jonatstr-dt-otc_80\\/received_bytes\":71876,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_average\":1,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_count\":119,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_maximum\":5,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_minimum\":1,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_p50\":1,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_p90\":2,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_p95\":2,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_p99\":5,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_p999\":5,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_p9999\":5,\"client\\/jonatstr-dt-otc_80\\/request_latency_ms_sum\":145,\"client\\/jonatstr-dt-otc_80\\/requests\":119,\"client\\/jonatstr-dt-otc_80\\/sent_bytes\":16699,\"client\\/jonatstr-dt-otc_80\\/socket_unwritable_ms\":0,\"client\\/jonatstr-dt-otc_80\\/socket_writable_ms\":0,\"client\\/jonatstr-dt-otc_80\\/success\":119,\"client\\/lifetime\":0,\"client\\/load\":0,\"client\\/loadbalancer\\/adds\":0,\"client\\/loadbalancer\\/available\":1,\"client\\/loadbalancer\\/load\":0,\"client\\/loadbalancer\\/removes\":0,\"client\\/loadbalancer\\/size\":1,\"client\\/pending\":0,\"client\\/pool_cached\":0,\"client\\/pool_num_waited\":0,\"client\\/pool_size\":0,\"client\\/pool_waiters\":0,\"client\\/received_bytes\":71876,\"client\\/request_latency_ms_average\":1,\"client\\/request_latency_ms_count\":119,\"client\\/request_latency_ms_maximum\":5,\"client\\/request_latency_ms_minimum\":1,\"client\\/request_latency_ms_p50\":1,\"client\\/request_latency_ms_p90\":2,\"client\\/request_latency_ms_p95\":2,\"client\\/request_latency_ms_p99\":5,\"client\\/request_latency_ms_p999\":5,\"client\\/request_latency_ms_p9999\":5,\"client\\/request_latency_ms_sum\":145,\"client\\/requests\":119,\"client\\/sent_bytes\":16699,\"client\\/socket_unwritable_ms\":0,\"client\\/socket_writable_ms\":0,\"client\\/success\":119,\"clock_error\":0,\"jvm_buffer_direct_count\":4,\"jvm_buffer_direct_max\":133120,\"jvm_buffer_direct_used\":133120,\"jvm_buffer_mapped_count\":0,\"jvm_buffer_mapped_max\":0,\"jvm_buffer_mapped_used\":0,\"jvm_current_mem_CMS_Old_Gen_max\":3657433088,\"jvm_current_mem_CMS_Old_Gen_used\":12173984,\"jvm_current_mem_CMS_Perm_Gen_max\":85983232,\"jvm_current_mem_CMS_Perm_Gen_used\":44577704,\"jvm_current_mem_Code_Cache_max\":50331648,\"jvm_current_mem_Code_Cache_used\":2589504,\"jvm_current_mem_Eden_Space_max\":429522944,\"jvm_current_mem_Eden_Space_used\":189752784,\"jvm_current_mem_Survivor_Space_max\":53673984,\"jvm_current_mem_Survivor_Space_used\":53673984,\"jvm_current_mem_used\":302767960,\"jvm_fd_count\":142,\"jvm_fd_limit\":4096,\"jvm_gc_ConcurrentMarkSweep_cycles\":0,\"jvm_gc_ConcurrentMarkSweep_msec\":0,\"jvm_gc_Copy_cycles\":0,\"jvm_gc_Copy_msec\":0,\"jvm_gc_cycles\":0,\"jvm_gc_msec\":0,\"jvm_heap_committed\":4140630016,\"jvm_heap_max\":4140630016,\"jvm_heap_used\":255600752,\"jvm_nonheap_committed\":47448064,\"jvm_nonheap_max\":136314880,\"jvm_nonheap_used\":47166344,\"jvm_num_cpus\":1,\"jvm_post_gc_CMS_Old_Gen_max\":3657433088,\"jvm_post_gc_CMS_Old_Gen_used\":0,\"jvm_post_gc_CMS_Perm_Gen_max\":85983232,\"jvm_post_gc_CMS_Perm_Gen_used\":0,\"jvm_post_gc_Eden_Space_max\":429522944,\"jvm_post_gc_Eden_Space_used\":0,\"jvm_post_gc_Survivor_Space_max\":53673984,\"jvm_post_gc_Survivor_Space_used\":53673984,\"jvm_post_gc_used\":53673984,\"jvm_start_time\":1402536778818,\"jvm_thread_count\":18,\"jvm_thread_daemon_count\":12,\"jvm_thread_peak_count\":18,\"jvm_uptime\":122186,\"queue_depth\":41,\"records-read\":119,\"requests_sent\":119,\"service\":\"parrot_web\",\"source\":\"jonatstr-dt-oneconnector\",\"timestamp\":1402536901,\"unexpected_error\":0,\"unexpected_error\\/com.twitter.finagle.ChannelClosedException\":0}"
  },
  {
    "path": "src/test/resources/JENKINS-16627_CSV_instead_of_XML.jtl",
    "content": "1393227741256,1425,GET /ordermgmt/login - Login Page,200,OK,Thread Group 1-1,text,true,3478,1016\n1393227742815,59,GET /ordermgmt/inventory,200,OK,Thread Group 1-1,text,true,3100,38\n1393227743132,2204,GET /ordermgmt/pre-logout,200,OK,Thread Group 1-1,text,true,19714,25"
  },
  {
    "path": "src/test/resources/JMeterCsvResults.csv",
    "content": "timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,bytes\n1393227741256,1425,GET /ordermgmt/login - Login Page,200,OK,Thread Group 1-1,text,true,3478\n1393227741257,2204,GET /ordermgmt/pre-logout,200,OK,Thread Group 1-1,text,true,19714\n1393227741258,2204,GET /ordermgmt/pre-logout,200,OK,Thread Group 1-1,text,true,19714"
  },
  {
    "path": "src/test/resources/JMeterCsvResults2.csv",
    "content": "timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,bytes,sentBytes\n2001/20/20 12:05:05.123,1425,GET /ordermgmt/login - Login Page,200,OK,Thread Group 1-1,text,true,3400,78\n2001/20/20 12:05:25.123,2204,GET /ordermgmt/pre-logout,200,OK,Thread Group 1-1,text,true,19000,714\n2001/20/20 12:05:55.123,2204,GET /ordermgmt/pre-logout,200,OK,Thread Group 1-1,text,true,19000,714"
  },
  {
    "path": "src/test/resources/JMeterCsvResults3.csv",
    "content": "timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,bytes,sentBytes\n2011-21-21 14:15:25.321,1425,GET /ordermgmt/login - Login Page,200,OK,Thread Group 1-1,text,true,3400,78\n2011-21-21 14:15:35.321,2204,GET /ordermgmt/pre-logout,200,OK,Thread Group 1-1,text,true,19000,714\n2011-21-21 14:15:45.321,2204,GET /ordermgmt/pre-logout,200,OK,Thread Group 1-1,text,true,19000,714"
  },
  {
    "path": "src/test/resources/JMeterPublisher.csv",
    "content": "timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,bytes\n1393227741256,1300,GET /ordermgmt/login - Login Page,501,FAIL,Thread Group 1-1,text,false,3478\n1393227741257,2000,GET /ordermgmt/pre-logout,200,OK,Thread Group 1-1,text,true,19714\n1393227741258,1000,GET /ordermgmt/pre-logout,200,OK,Thread Group 1-1,text,true,19714"
  },
  {
    "path": "src/test/resources/JMeterPublisher_formatted_timeStamp.csv",
    "content": "timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,bytes\n2014-02-24 07:42:21.256,1300,GET /ordermgmt/login - Login Page,501,FAIL,Thread Group 1-1,text,false,3478\n2014-02-24 07:42:21.257,2000,GET /ordermgmt/pre-logout,200,OK,Thread Group 1-1,text,true,19714\n2014-02-24 07:42:21.258,1000,GET /ordermgmt/pre-logout,200,OK,Thread Group 1-1,text,true,19714"
  },
  {
    "path": "src/test/resources/JMeterResults.jtl",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<testResults version=\"1.2\">\n<httpSample t=\"14720\" lt=\"9770\" ts=\"1296846793179\" s=\"true\" lb=\"Home\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-2\" dt=\"text\" by=\"771065\"/>\n<httpSample t=\"15902\" lt=\"10954\" ts=\"1296846792004\" s=\"true\" lb=\"Home\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-1\" dt=\"text\" by=\"771065\"/>\n<httpSample t=\"278\" lt=\"148\" ts=\"1296846847952\" s=\"true\" lb=\"Workgroup\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-2\" dt=\"text\" by=\"744705\"/>\n<httpSample t=\"1017\" lt=\"694\" ts=\"1296846847222\" s=\"true\" lb=\"Workgroup\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-1\" dt=\"text\" by=\"744705\"/>\n<httpSample t=\"598\" lt=\"321\" ts=\"1296846947037\" s=\"true\" lb=\"Home\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-1\" dt=\"text\" by=\"771149\"/>\n<httpSample t=\"501\" lt=\"298\" ts=\"1296846947144\" s=\"true\" lb=\"Home\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-2\" dt=\"text\" by=\"771149\"/>\n<httpSample t=\"63\" lt=\"3\" ts=\"1296846968923\" s=\"true\" lb=\"Workgroup\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-1\" dt=\"text\" by=\"744705\"/>\n<httpSample t=\"58\" lt=\"2\" ts=\"1296846969096\" s=\"true\" lb=\"Workgroup\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-2\" dt=\"text\" by=\"744705\"/>\n</testResults>\n"
  },
  {
    "path": "src/test/resources/JMeterResultsMultiLevel.jtl",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<testResults version=\"1.2\">\r\n<httpSample t=\"645\" lt=\"644\" ts=\"1298457003722\" s=\"true\" lb=\"Home\" rc=\"200\" rm=\"OK\" tn=\"OSS 1-1\" dt=\"text\" by=\"611\">\r\n  <assertionResult>\r\n    <name>Ok</name>\r\n    <failure>false</failure>\r\n    <error>false</error>\r\n    <failureMessage></failureMessage>\r\n  </assertionResult>\r\n  <assertionResult>\r\n    <name>Otp sms</name>\r\n    <failure>false</failure>\r\n    <error>false</error>\r\n    <failureMessage></failureMessage>\r\n  </assertionResult>\r\n  <assertionResult>\r\n    <name>Nominal mode</name>\r\n    <failure>false</failure>\r\n    <error>false</error>\r\n    <failureMessage></failureMessage>\r\n  </assertionResult>\r\n</httpSample>\r\n<httpSample t=\"449\" lt=\"449\" ts=\"1298457004512\" s=\"true\" lb=\"Home\" rc=\"200\" rm=\"OK\" tn=\"OSS 1-1\" dt=\"text\" by=\"557\">\r\n  <assertionResult>\r\n    <name>Ok</name>\r\n    <failure>false</failure>\r\n    <error>false</error>\r\n    <failureMessage></failureMessage>\r\n  </assertionResult>\r\n</httpSample>\r\n<httpSample t=\"372\" lt=\"372\" ts=\"1298457004965\" s=\"true\" lb=\"Home\" rc=\"200\" rm=\"OK\" tn=\"OSS 1-1\" dt=\"text\" by=\"506\">\r\n  <assertionResult>\r\n    <name>authentication ok</name>\r\n    <failure>false</failure>\r\n    <error>false</error>\r\n    <failureMessage></failureMessage>\r\n  </assertionResult>\r\n</httpSample>\r\n<httpSample t=\"342\" lt=\"342\" ts=\"1298457005341\" s=\"true\" lb=\"Workgroup\" rc=\"200\" rm=\"OK\" tn=\"OSS 1-1\" dt=\"text\" by=\"610\">\r\n  <assertionResult>\r\n    <name>Ok</name>\r\n    <failure>false</failure>\r\n    <error>false</error>\r\n    <failureMessage></failureMessage>\r\n  </assertionResult>\r\n  <assertionResult>\r\n    <name>Otp sms</name>\r\n    <failure>false</failure>\r\n    <error>false</error>\r\n    <failureMessage></failureMessage>\r\n  </assertionResult>\r\n  <assertionResult>\r\n    <name>Backup mode</name>\r\n    <failure>false</failure>\r\n    <error>false</error>\r\n    <failureMessage></failureMessage>\r\n  </assertionResult>\r\n</httpSample>\r\n<httpSample t=\"420\" lt=\"419\" ts=\"1298457005690\" s=\"true\" lb=\"Workgroup\" rc=\"200\" rm=\"OK\" tn=\"OSS 1-1\" dt=\"text\" by=\"557\">\r\n  <assertionResult>\r\n    <name>Ok</name>\r\n    <failure>false</failure>\r\n    <error>false</error>\r\n    <failureMessage></failureMessage>\r\n  </assertionResult>\r\n</httpSample>\r\n<httpSample t=\"374\" lt=\"373\" ts=\"1298457006113\" s=\"true\" lb=\"Workgroup\" rc=\"200\" rm=\"OK\" tn=\"OSS 1-1\" dt=\"text\" by=\"506\">\r\n  <assertionResult>\r\n    <name>Authentication ok</name>\r\n    <failure>false</failure>\r\n    <error>false</error>\r\n    <failureMessage></failureMessage>\r\n  </assertionResult>\r\n</httpSample>\r\n<httpSample t=\"280\" lt=\"279\" ts=\"1298457006490\" s=\"true\" lb=\"Home\" rc=\"200\" rm=\"OK\" tn=\"OSS 1-1\" dt=\"text\" by=\"622\">\r\n  <assertionResult>\r\n    <name>Ok</name>\r\n    <failure>false</failure>\r\n    <error>false</error>\r\n    <failureMessage></failureMessage>\r\n  </assertionResult>\r\n  <assertionResult>\r\n    <name>Otp sms</name>\r\n    <failure>false</failure>\r\n    <error>false</error>\r\n    <failureMessage></failureMessage>\r\n  </assertionResult>\r\n  <assertionResult>\r\n    <name>Nominal mode</name>\r\n    <failure>false</failure>\r\n    <error>false</error>\r\n    <failureMessage></failureMessage>\r\n  </assertionResult>\r\n</httpSample>\r\n<httpSample t=\"379\" lt=\"379\" ts=\"1298457006783\" s=\"true\" lb=\"Home\" rc=\"200\" rm=\"OK\" tn=\"OSS 1-1\" dt=\"text\" by=\"568\">\r\n  <assertionResult>\r\n    <name>Ok</name>\r\n    <failure>false</failure>\r\n    <error>false</error>\r\n    <failureMessage></failureMessage>\r\n  </assertionResult>\r\n</httpSample>\r\n<httpSample t=\"332\" lt=\"332\" ts=\"1298457007165\" s=\"true\" lb=\"Home\" rc=\"200\" rm=\"OK\" tn=\"OSS 1-1\" dt=\"text\" by=\"506\">\r\n  <assertionResult>\r\n    <name>Authentication ok</name>\r\n    <failure>false</failure>\r\n    <error>false</error>\r\n    <failureMessage></failureMessage>\r\n  </assertionResult>\r\n</httpSample>\r\n<httpSample t=\"226\" lt=\"226\" ts=\"1298457007500\" s=\"true\" lb=\"Workgroup\" rc=\"200\" rm=\"OK\" tn=\"OSS 1-1\" dt=\"text\" by=\"621\">\r\n  <assertionResult>\r\n    <name>Ok</name>\r\n    <failure>false</failure>\r\n    <error>false</error>\r\n    <failureMessage></failureMessage>\r\n  </assertionResult>\r\n  <assertionResult>\r\n    <name>Otp sms</name>\r\n    <failure>false</failure>\r\n    <error>false</error>\r\n    <failureMessage></failureMessage>\r\n  </assertionResult>\r\n  <assertionResult>\r\n    <name>Backup mode</name>\r\n    <failure>false</failure>\r\n    <error>false</error>\r\n    <failureMessage></failureMessage>\r\n  </assertionResult>\r\n</httpSample>\r\n\r\n\r\n</testResults>\r\n"
  },
  {
    "path": "src/test/resources/JMeterResultsMultiThread.jtl",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<testResults version=\"1.2\">\n<sample t=\"894\" lt=\"0\" ts=\"1236948710884\" s=\"true\" lb=\"WebService(SOAP) Request\" rc=\"200\" rm=\"\" tn=\"Thread Group 1-1\" dt=\"text\" by=\"13647\"/>\n<sample t=\"1508\" lt=\"0\" ts=\"1236948716606\" s=\"true\" lb=\"WebService(SOAP) Request\" rc=\"200\" rm=\"\" tn=\"Thread Group 1-2\" dt=\"text\" by=\"13647\"/>\n<sample t=\"1384\" lt=\"0\" ts=\"1236948722606\" s=\"true\" lb=\"WebService(SOAP) Request\" rc=\"200\" rm=\"\" tn=\"Thread Group 1-3\" dt=\"text\" by=\"13647\"/>\n<sample t=\"1581\" lt=\"0\" ts=\"1236948728607\" s=\"true\" lb=\"WebService(SOAP) Request\" rc=\"200\" rm=\"\" tn=\"Thread Group 1-4\" dt=\"text\" by=\"13647\"/>\n<sample t=\"996\" lt=\"0\" ts=\"1236948734606\" s=\"true\" lb=\"WebService(SOAP) Request\" rc=\"200\" rm=\"\" tn=\"Thread Group 1-5\" dt=\"text\" by=\"13647\"/>\n\n</testResults>\n"
  },
  {
    "path": "src/test/resources/JMeterResultsOneSample.jtl",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<testResults version=\"1.2\">\n<httpSample t=\"2\" lt=\"9770\" ts=\"1296846793179\" s=\"true\" lb=\"Bat\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-2\" dt=\"text\" by=\"771065\"/>\n</testResults>\n"
  },
  {
    "path": "src/test/resources/JMeterResultsRandomUri.jtl",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<testResults version=\"1.2\">\n<httpSample t=\"14720\" lt=\"9770\" ts=\"1296846793179\" s=\"true\" lb=\"Bat\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-2\" dt=\"text\" by=\"771065\"/>\n<httpSample t=\"278\" lt=\"148\" ts=\"1296846847952\" s=\"true\" lb=\"Dog\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-2\" dt=\"text\" by=\"744705\"/>\n<httpSample t=\"598\" lt=\"321\" ts=\"1296846947037\" s=\"true\" lb=\"Ant\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-1\" dt=\"text\" by=\"771149\"/>\n<httpSample t=\"63\" lt=\"3\" ts=\"1296846968923\" s=\"true\" lb=\"Cat\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-1\" dt=\"text\" by=\"744705\"/>\n</testResults>\n"
  },
  {
    "path": "src/test/resources/JMeterResultsTenSamples.jtl",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<testResults version=\"1.2\">\n<httpSample t=\"1\" lt=\"9770\" ts=\"1296846793179\" s=\"true\" lb=\"Bat\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-2\" dt=\"text\" by=\"771065\"/>\n<httpSample t=\"2\" lt=\"148\" ts=\"1296846847952\" s=\"true\" lb=\"Dog\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-2\" dt=\"text\" by=\"744705\"/>\n<httpSample t=\"3\" lt=\"321\" ts=\"1296846947037\" s=\"true\" lb=\"Ant\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-1\" dt=\"text\" by=\"771149\"/>\n<httpSample t=\"4\" lt=\"3\" ts=\"1296846968923\" s=\"true\" lb=\"Cat\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-1\" dt=\"text\" by=\"744705\"/>\n<httpSample t=\"5\" lt=\"9770\" ts=\"1296846793179\" s=\"true\" lb=\"Bat\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-2\" dt=\"text\" by=\"771065\"/>\n<httpSample t=\"6\" lt=\"148\" ts=\"1296846847952\" s=\"true\" lb=\"Dog\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-2\" dt=\"text\" by=\"744705\"/>\n<httpSample t=\"7\" lt=\"321\" ts=\"1296846947037\" s=\"true\" lb=\"Ant\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-1\" dt=\"text\" by=\"771149\"/>\n<httpSample t=\"8\" lt=\"3\" ts=\"1296846968923\" s=\"true\" lb=\"Cat\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-1\" dt=\"text\" by=\"744705\"/>\n<httpSample t=\"9\" lt=\"321\" ts=\"1296846947037\" s=\"true\" lb=\"Ant\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-1\" dt=\"text\" by=\"771149\"/>\n<httpSample t=\"10\" lt=\"3\" ts=\"1296846968923\" s=\"true\" lb=\"Cat\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-1\" dt=\"text\" by=\"744705\"/>\n</testResults>\n"
  },
  {
    "path": "src/test/resources/JMeterResultsThreeSamples.jtl",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<testResults version=\"1.2\">\n<httpSample t=\"1\" lt=\"9770\" ts=\"1296846793179\" s=\"true\" lb=\"Bat\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-2\" dt=\"text\" by=\"771065\"/>\n<httpSample t=\"2\" lt=\"9770\" ts=\"1296846793179\" s=\"true\" lb=\"Bat\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-2\" dt=\"text\" by=\"771065\"/>\n<httpSample t=\"3\" lt=\"9770\" ts=\"1296846793179\" s=\"true\" lb=\"Bat\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-2\" dt=\"text\" by=\"771065\"/>\n</testResults>\n"
  },
  {
    "path": "src/test/resources/TEST-JUnitResults-noTimeAttribute.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<testsuite failures=\"0\" time=\"0.100\" errors=\"0\" skipped=\"0\" tests=\"1\" name=\"hudson.plugins.performance.reports.UriReportTest\">\n  <testcase classname=\"hudson.plugins.performance.parsers.JUnitParserTest\" name=\"parseWithoutTimeAttribute\"/>\n  <testcase time=\"0.100\" classname=\"hudson.plugins.performance.parsers.JUnitParserTest\" name=\"parseWithoutTimeAttribute\"/>\n  <testcase classname=\"hudson.plugins.performance.parsers.JUnitParserTest\" name=\"parseWithoutTimeAttribute\"/>\n  <testcase time=\"0.100\" classname=\"hudson.plugins.performance.parsers.JUnitParserTest\" name=\"parseWithoutTimeAttribute\"/>\n</testsuite>\n"
  },
  {
    "path": "src/test/resources/TEST-JUnitResults-relative-thrashould-2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<testsuite failures=\"0\" time=\"0.160\" errors=\"0\" skipped=\"0\" tests=\"1\" name=\"hudson.plugins.performance.reports.UriReportTest\">\n    <testcase time=\"0.160\" classname=\"hudson.plugins.performance.reports.UriReportTest\" name=\"testCountErrors\"/>\n</testsuite>\n"
  },
  {
    "path": "src/test/resources/TEST-JUnitResults-relative-thrashould.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<testsuite failures=\"0\" time=\"0.100\" errors=\"0\" skipped=\"0\" tests=\"1\" name=\"hudson.plugins.performance.reports.UriReportTest\">\n  <testcase time=\"0.100\" classname=\"hudson.plugins.performance.reports.UriReportTest\" name=\"testCountErrors\"/>\n</testsuite>\n"
  },
  {
    "path": "src/test/resources/TEST-JUnitResults-success-failure-error.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?><testsuite errors=\"1\" failures=\"1\" hostname=\"someHostname\" name=\"tests.ATest\" tests=\"3\" time=\"0.069\" timestamp=\"2009-12-19T17:58:59\">\n\n    <testcase classname=\"tests.ATest\" name=\"error\" time=\"0.0060\">\n        <error type=\"java.lang.RuntimeException\">java.lang.RuntimeException at tests.ATest.error(ATest.java:11)</error>\n    </testcase>\n\n    <testcase classname=\"tests.ATest\" name=\"fail\" time=\"0.0020\">\n        <failure type=\"junit.framework.AssertionFailedError\">junit.framework.AssertionFailedError: at tests.ATest.fail(ATest.java:9)</failure>\n    </testcase>\n\n    <testcase classname=\"tests.ATest\" name=\"sucess\" time=\"0.0\"/>\n\n</testsuite>"
  },
  {
    "path": "src/test/resources/TEST-JUnitResults.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<testsuite failures=\"0\" time=\"0.008\" errors=\"0\" skipped=\"0\" tests=\"5\" name=\"hudson.plugins.performance.reports.UriReportTest\">\n  <properties>\n    <property name=\"jna.platform.library.path\" value=\"/usr/lib64:/lib64\"/>\n    <property name=\"java.runtime.name\" value=\"Java(TM) SE Runtime Environment\"/>\n    <property name=\"sun.boot.library.path\" value=\"/usr/lib/jvm/java-6-sun-1.6.0.20/jre/lib/amd64\"/>\n    <property name=\"java.vm.version\" value=\"16.3-b01\"/>\n    <property name=\"java.vm.vendor\" value=\"Sun Microsystems Inc.\"/>\n    <property name=\"java.vendor.url\" value=\"http://java.sun.com/\"/>\n    <property name=\"path.separator\" value=\":\"/>\n    <property name=\"java.vm.name\" value=\"Java HotSpot(TM) 64-Bit Server VM\"/>\n    <property name=\"file.encoding.pkg\" value=\"sun.io\"/>\n    <property name=\"user.country\" value=\"US\"/>\n    <property name=\"sun.java.launcher\" value=\"SUN_STANDARD\"/>\n    <property name=\"sun.os.patch.level\" value=\"unknown\"/>\n    <property name=\"java.vm.specification.name\" value=\"Java Virtual Machine Specification\"/>\n    <property name=\"user.dir\" value=\"/home/workspace/hudson/plugins/performance\"/>\n    <property name=\"java.runtime.version\" value=\"1.6.0_20-b02\"/>\n    <property name=\"java.awt.graphicsenv\" value=\"sun.awt.X11GraphicsEnvironment\"/>\n    <property name=\"basedir\" value=\"/home/workspace/hudson/plugins/performance\"/>\n    <property name=\"java.endorsed.dirs\" value=\"/usr/lib/jvm/java-6-sun-1.6.0.20/jre/lib/endorsed\"/>\n    <property name=\"os.arch\" value=\"amd64\"/>\n    <property name=\"surefire.real.class.path\" value=\"/tmp/surefirebooter381169233289569746.jar\"/>\n    <property name=\"java.io.tmpdir\" value=\"/tmp\"/>\n    <property name=\"line.separator\" value=\"\n\"/>\n    <property name=\"java.vm.specification.vendor\" value=\"Sun Microsystems Inc.\"/>\n    <property name=\"os.name\" value=\"Linux\"/>\n    <property name=\"sun.jnu.encoding\" value=\"UTF-8\"/>\n    <property name=\"java.library.path\" value=\"/usr/lib/jvm/java-6-sun-1.6.0.20/jre/lib/amd64/server:/usr/lib/jvm/java-6-sun-1.6.0.20/jre/lib/amd64:/usr/lib/jvm/java-6-sun-1.6.0.20/jre/../lib/amd64:/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib\"/>\n    <property name=\"surefire.test.class.path\" value=\"/home/workspace/hudson/plugins/performance/target/test-classes:/home/workspace/hudson/plugins/performance/target/classes:/home/manolo/.m2/repository/org/easymock/easymockclassextension/2.4/easymockclassextension-2.4.jar:/home/manolo/.m2/repository/org/easymock/easymock/2.4/easymock-2.4.jar:/home/manolo/.m2/repository/cglib/cglib-nodep/2.1_3/cglib-nodep-2.1_3.jar:/home/manolo/.m2/repository/org/jvnet/hudson/main/hudson-core/1.332/hudson-core-1.332.jar:/home/manolo/.m2/repository/org/jvnet/hudson/main/remoting/1.332/remoting-1.332.jar:/home/manolo/.m2/repository/org/jvnet/hudson/main/cli/1.332/cli-1.332.jar:/home/manolo/.m2/repository/org/jvnet/localizer/localizer/1.10/localizer-1.10.jar:/home/manolo/.m2/repository/org/jvnet/hudson/crypto-util/1.0/crypto-util-1.0.jar:/home/manolo/.m2/repository/commons-io/commons-io/1.3.1/commons-io-1.3.1.jar:/home/manolo/.m2/repository/org/jvnet/hudson/jtidy/4aug2000r7-dev-hudson-1/jtidy-4aug2000r7-dev-hudson-1.jar:/home/manolo/.m2/repository/org/jruby/ext/posix/jna-posix/1.0.1/jna-posix-1.0.1.jar:/home/manolo/.m2/repository/org/kohsuke/trilead-putty-extension/1.0/trilead-putty-extension-1.0.jar:/home/manolo/.m2/repository/org/jvnet/hudson/trilead-ssh2/build212-hudson-5/trilead-ssh2-build212-hudson-5.jar:/home/manolo/.m2/repository/org/kohsuke/stapler/stapler-jelly/1.122/stapler-jelly-1.122.jar:/home/manolo/.m2/repository/org/kohsuke/stapler/stapler/1.122/stapler-1.122.jar:/home/manolo/.m2/repository/commons-discovery/commons-discovery/0.4/commons-discovery-0.4.jar:/home/manolo/.m2/repository/commons-logging/commons-logging/1.1/commons-logging-1.1.jar:/home/manolo/.m2/repository/commons-beanutils/commons-beanutils/1.8.0/commons-beanutils-1.8.0.jar:/home/manolo/.m2/repository/org/kohsuke/stapler/json-lib/2.1-rev4/json-lib-2.1-rev4.jar:/home/manolo/.m2/repository/commons-collections/commons-collections/3.2/commons-collections-3.2.jar:/home/manolo/.m2/repository/commons-lang/commons-lang/2.4/commons-lang-2.4.jar:/home/manolo/.m2/repository/net/sf/ezmorph/ezmorph/1.0.3/ezmorph-1.0.3.jar:/home/manolo/.m2/repository/org/jvnet/tiger-types/1.1/tiger-types-1.1.jar:/home/manolo/.m2/repository/commons-fileupload/commons-fileupload/1.2.1/commons-fileupload-1.2.1.jar:/home/manolo/.m2/repository/junit/junit/4.3.1/junit-4.3.1.jar:/home/manolo/.m2/repository/com/google/collections/google-collections/1.0-rc3/google-collections-1.0-rc3.jar:/home/manolo/.m2/repository/args4j/args4j/2.0.16/args4j-2.0.16.jar:/home/manolo/.m2/repository/org/jvnet/hudson/annotation-indexer/1.1/annotation-indexer-1.1.jar:/home/manolo/.m2/repository/org/kohsuke/graph-layouter/1.0/graph-layouter-1.0.jar:/home/manolo/.m2/repository/antlr/antlr/2.7.6/antlr-2.7.6.jar:/home/manolo/.m2/repository/org/jvnet/hudson/xstream/1.3.1-hudson-5/xstream-1.3.1-hudson-5.jar:/home/manolo/.m2/repository/xpp3/xpp3_min/1.1.4c/xpp3_min-1.1.4c.jar:/home/manolo/.m2/repository/jfree/jfreechart/1.0.9/jfreechart-1.0.9.jar:/home/manolo/.m2/repository/jfree/jcommon/1.0.12/jcommon-1.0.12.jar:/home/manolo/.m2/repository/org/apache/ant/ant-junit/1.7.0/ant-junit-1.7.0.jar:/home/manolo/.m2/repository/org/apache/ant/ant/1.7.0/ant-1.7.0.jar:/home/manolo/.m2/repository/org/apache/ant/ant-launcher/1.7.0/ant-launcher-1.7.0.jar:/home/manolo/.m2/repository/commons-digester/commons-digester/1.7/commons-digester-1.7.jar:/home/manolo/.m2/repository/javax/mail/mail/1.4/mail-1.4.jar:/home/manolo/.m2/repository/org/jvnet/hudson/activation/1.1.1-hudson-1/activation-1.1.1-hudson-1.jar:/home/manolo/.m2/repository/org/jvnet/hudson/dom4j/dom4j/1.6.1-hudson-1/dom4j-1.6.1-hudson-1.jar:/home/manolo/.m2/repository/jaxen/jaxen/1.1-beta-11/jaxen-1.1-beta-11.jar:/home/manolo/.m2/repository/commons-jelly/commons-jelly-tags-fmt/1.0/commons-jelly-tags-fmt-1.0.jar:/home/manolo/.m2/repository/commons-jelly/commons-jelly-tags-xml/1.1/commons-jelly-tags-xml-1.1.jar:/home/manolo/.m2/repository/org/jvnet/hudson/commons-jelly-tags-define/1.0.1-hudson-20071021/commons-jelly-tags-define-1.0.1-hudson-20071021.jar:/home/manolo/.m2/repository/org/jvnet/hudson/commons-jelly/1.1-hudson-20090709/commons-jelly-1.1-hudson-20090709.jar:/home/manolo/.m2/repository/org/jvnet/hudson/commons-jexl/1.1-hudson-20090508/commons-jexl-1.1-hudson-20090508.jar:/home/manolo/.m2/repository/org/acegisecurity/acegi-security/1.0.5/acegi-security-1.0.5.jar:/home/manolo/.m2/repository/org/springframework/spring-core/2.5/spring-core-2.5.jar:/home/manolo/.m2/repository/org/springframework/spring-jdbc/1.2.9/spring-jdbc-1.2.9.jar:/home/manolo/.m2/repository/org/springframework/spring-beans/2.5/spring-beans-2.5.jar:/home/manolo/.m2/repository/org/springframework/spring-dao/1.2.9/spring-dao-1.2.9.jar:/home/manolo/.m2/repository/org/springframework/spring-context/2.5/spring-context-2.5.jar:/home/manolo/.m2/repository/commons-codec/commons-codec/1.3/commons-codec-1.3.jar:/home/manolo/.m2/repository/oro/oro/2.0.8/oro-2.0.8.jar:/home/manolo/.m2/repository/log4j/log4j/1.2.9/log4j-1.2.9.jar:/home/manolo/.m2/repository/org/codehaus/groovy/groovy-all/1.6.0/groovy-all-1.6.0.jar:/home/manolo/.m2/repository/jline/jline/0.9.94/jline-0.9.94.jar:/home/manolo/.m2/repository/org/springframework/spring-web/2.5/spring-web-2.5.jar:/home/manolo/.m2/repository/aopalliance/aopalliance/1.0/aopalliance-1.0.jar:/home/manolo/.m2/repository/org/springframework/spring-aop/2.5/spring-aop-2.5.jar:/home/manolo/.m2/repository/xpp3/xpp3/1.1.3.3/xpp3-1.1.3.3.jar:/home/manolo/.m2/repository/javax/servlet/jstl/1.1.0/jstl-1.1.0.jar:/home/manolo/.m2/repository/logkit/logkit/1.0.1/logkit-1.0.1.jar:/home/manolo/.m2/repository/avalon-framework/avalon-framework/4.1.3/avalon-framework-4.1.3.jar:/home/manolo/.m2/repository/javax/servlet/servlet-api/2.4/servlet-api-2.4.jar:/home/manolo/.m2/repository/com/sun/xml/txw2/txw2/20070624/txw2-20070624.jar:/home/manolo/.m2/repository/org/jvnet/winp/winp/1.13/winp-1.13.jar:/home/manolo/.m2/repository/org/jvnet/hudson/memory-monitor/1.1/memory-monitor-1.1.jar:/home/manolo/.m2/repository/net/java/dev/jna/jna/3.2.2/jna-3.2.2.jar:/home/manolo/.m2/repository/com/octo/captcha/jcaptcha-all/1.0-RC6/jcaptcha-all-1.0-RC6.jar:/home/manolo/.m2/repository/commons-pool/commons-pool/1.3/commons-pool-1.3.jar:/home/manolo/.m2/repository/org/codehaus/woodstox/wstx-asl/3.2.7/wstx-asl-3.2.7.jar:/home/manolo/.m2/repository/stax/stax-api/1.0.1/stax-api-1.0.1.jar:/home/manolo/.m2/repository/com/sun/akuma/akuma/1.2/akuma-1.2.jar:/home/manolo/.m2/repository/org/jvnet/libpam4j/libpam4j/1.2/libpam4j-1.2.jar:/home/manolo/.m2/repository/org/jvnet/libzfs/libzfs/0.5/libzfs-0.5.jar:/home/manolo/.m2/repository/com/sun/solaris/embedded_su4j/1.1/embedded_su4j-1.1.jar:/home/manolo/.m2/repository/net/java/sezpoz/sezpoz/1.4/sezpoz-1.4.jar:/home/manolo/.m2/repository/org/jvnet/hudson/jinterop-wmi/1.0/jinterop-wmi-1.0.jar:/home/manolo/.m2/repository/org/kohsuke/jinterop/jinterop-proxy/1.1/jinterop-proxy-1.1.jar:/home/manolo/.m2/repository/org/kohsuke/jinterop/j-interop/2.0.5/j-interop-2.0.5.jar:/home/manolo/.m2/repository/org/kohsuke/jinterop/j-interopdeps/2.0.5/j-interopdeps-2.0.5.jar:/home/manolo/.m2/repository/org/samba/jcifs/jcifs/1.3.3/jcifs-1.3.3.jar:/home/manolo/.m2/repository/org/jvnet/robust-http-client/robust-http-client/1.0/robust-http-client-1.0.jar:/home/manolo/.m2/repository/org/jvnet/hudson/main/hudson-test-harness/1.332/hudson-test-harness-1.332.jar:/home/manolo/.m2/repository/org/jvnet/hudson/main/hudson-war/1.332/hudson-war-1.332-war-for-test.jar:/home/manolo/.m2/repository/org/jvnet/hudson/main/maven-plugin/1.332/maven-plugin-1.332.jar:/home/manolo/.m2/repository/org/jvnet/hudson/main/maven-agent/1.332/maven-agent-1.332.jar:/home/manolo/.m2/repository/org/jvnet/hudson/main/maven-interceptor/1.332/maven-interceptor-1.332.jar:/home/manolo/.m2/repository/org/apache/maven/maven-core/2.0.9/maven-core-2.0.9.jar:/home/manolo/.m2/repository/org/apache/maven/maven-settings/2.0.9/maven-settings-2.0.9.jar:/home/manolo/.m2/repository/org/apache/maven/maven-model/2.0.9/maven-model-2.0.9.jar:/home/manolo/.m2/repository/org/codehaus/plexus/plexus-utils/1.5.1/plexus-utils-1.5.1.jar:/home/manolo/.m2/repository/org/codehaus/plexus/plexus-container-default/1.0-alpha-9-stable-1/plexus-container-default-1.0-alpha-9-stable-1.jar:/home/manolo/.m2/repository/classworlds/classworlds/1.1/classworlds-1.1.jar:/home/manolo/.m2/repository/org/apache/maven/wagon/wagon-file/1.0-beta-2/wagon-file-1.0-beta-2.jar:/home/manolo/.m2/repository/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.jar:/home/manolo/.m2/repository/org/apache/maven/maven-plugin-parameter-documenter/2.0.9/maven-plugin-parameter-documenter-2.0.9.jar:/home/manolo/.m2/repository/slide/slide-webdavlib/2.1/slide-webdavlib-2.1.jar:/home/manolo/.m2/repository/commons-httpclient/commons-httpclient/3.1/commons-httpclient-3.1.jar:/home/manolo/.m2/repository/de/zeigermann/xml/xml-im-exporter/1.1/xml-im-exporter-1.1.jar:/home/manolo/.m2/repository/org/apache/maven/wagon/wagon-http-lightweight/1.0-beta-2/wagon-http-lightweight-1.0-beta-2.jar:/home/manolo/.m2/repository/org/apache/maven/wagon/wagon-http-shared/1.0-beta-2/wagon-http-shared-1.0-beta-2.jar:/home/manolo/.m2/repository/org/apache/maven/reporting/maven-reporting-api/2.0.9/maven-reporting-api-2.0.9.jar:/home/manolo/.m2/repository/org/apache/maven/doxia/doxia-sink-api/1.0-alpha-10/doxia-sink-api-1.0-alpha-10.jar:/home/manolo/.m2/repository/org/apache/maven/maven-profile/2.0.9/maven-profile-2.0.9.jar:/home/manolo/.m2/repository/org/apache/maven/maven-artifact/2.0.9/maven-artifact-2.0.9.jar:/home/manolo/.m2/repository/org/apache/maven/maven-repository-metadata/2.0.9/maven-repository-metadata-2.0.9.jar:/home/manolo/.m2/repository/org/apache/maven/maven-error-diagnostics/2.0.9/maven-error-diagnostics-2.0.9.jar:/home/manolo/.m2/repository/org/apache/maven/maven-project/2.0.9/maven-project-2.0.9.jar:/home/manolo/.m2/repository/org/apache/maven/maven-artifact-manager/2.0.9/maven-artifact-manager-2.0.9.jar:/home/manolo/.m2/repository/org/apache/maven/maven-plugin-registry/2.0.9/maven-plugin-registry-2.0.9.jar:/home/manolo/.m2/repository/org/apache/maven/maven-plugin-api/2.0.9/maven-plugin-api-2.0.9.jar:/home/manolo/.m2/repository/org/apache/maven/wagon/wagon-ssh-external/1.0-beta-2/wagon-ssh-external-1.0-beta-2.jar:/home/manolo/.m2/repository/org/apache/maven/wagon/wagon-ssh-common/1.0-beta-2/wagon-ssh-common-1.0-beta-2.jar:/home/manolo/.m2/repository/org/codehaus/plexus/plexus-interactivity-api/1.0-alpha-4/plexus-interactivity-api-1.0-alpha-4.jar:/home/manolo/.m2/repository/org/apache/maven/maven-plugin-descriptor/2.0.9/maven-plugin-descriptor-2.0.9.jar:/home/manolo/.m2/repository/org/apache/maven/maven-monitor/2.0.9/maven-monitor-2.0.9.jar:/home/manolo/.m2/repository/org/apache/maven/wagon/wagon-ssh/1.0-beta-2/wagon-ssh-1.0-beta-2.jar:/home/manolo/.m2/repository/com/jcraft/jsch/0.1.27/jsch-0.1.27.jar:/home/manolo/.m2/repository/org/jvnet/hudson/maven2.1-interceptor/1.2/maven2.1-interceptor-1.2.jar:/home/manolo/.m2/repository/org/apache/maven/maven-embedder/2.0.4/maven-embedder-2.0.4.jar:/home/manolo/.m2/repository/org/jvnet/hudson/wagon-webdav/1.0-beta-2-hudson-1/wagon-webdav-1.0-beta-2-hudson-1.jar:/home/manolo/.m2/repository/org/jvnet/hudson/plugins/subversion/1.7/subversion-1.7.jar:/home/manolo/.m2/repository/org/jvnet/hudson/svnkit/svnkit/1.3.0-hudson-2/svnkit-1.3.0-hudson-2.jar:/home/manolo/.m2/repository/org/mortbay/jetty/jetty/6.1.11/jetty-6.1.11.jar:/home/manolo/.m2/repository/org/mortbay/jetty/jetty-util/6.1.11/jetty-util-6.1.11.jar:/home/manolo/.m2/repository/org/mortbay/jetty/servlet-api-2.5/6.1.11/servlet-api-2.5-6.1.11.jar:/home/manolo/.m2/repository/org/jvnet/mock-javamail/mock-javamail/1.7/mock-javamail-1.7.jar:/home/manolo/.m2/repository/org/jvnet/hudson/htmlunit/2.2-hudson-10/htmlunit-2.2-hudson-10.jar:/home/manolo/.m2/repository/xalan/xalan/2.7.0/xalan-2.7.0.jar:/home/manolo/.m2/repository/org/jvnet/hudson/htmlunit-core-js/2.2-hudson-2/htmlunit-core-js-2.2-hudson-2.jar:/home/manolo/.m2/repository/net/sourceforge/nekohtml/nekohtml/1.9.8/nekohtml-1.9.8.jar:/home/manolo/.m2/repository/xerces/xercesImpl/2.8.1/xercesImpl-2.8.1.jar:/home/manolo/.m2/repository/net/sourceforge/cssparser/cssparser/0.9.5/cssparser-0.9.5.jar:/home/manolo/.m2/repository/org/w3c/css/sac/1.3/sac-1.3.jar:/home/manolo/.m2/repository/org/jvnet/hudson/embedded-rhino-debugger/1.1/embedded-rhino-debugger-1.1.jar:/home/manolo/.m2/repository/org/jvnet/hudson/netx/0.5-hudson-2/netx-0.5-hudson-2.jar:\"/>\n    <property name=\"java.specification.name\" value=\"Java Platform API Specification\"/>\n    <property name=\"java.class.version\" value=\"50.0\"/>\n    <property name=\"sun.management.compiler\" value=\"HotSpot 64-Bit Server Compiler\"/>\n    <property name=\"os.version\" value=\"2.6.32-22-generic\"/>\n    <property name=\"user.home\" value=\"/home/manolo\"/>\n    <property name=\"user.timezone\" value=\"Europe/Madrid\"/>\n    <property name=\"java.awt.printerjob\" value=\"sun.print.PSPrinterJob\"/>\n    <property name=\"java.specification.version\" value=\"1.6\"/>\n    <property name=\"file.encoding\" value=\"UTF-8\"/>\n    <property name=\"user.name\" value=\"manolo\"/>\n    <property name=\"java.class.path\" value=\"/home/workspace/hudson/plugins/performance/target/test-classes:/home/workspace/hudson/plugins/performance/target/classes:/home/manolo/.m2/repository/org/easymock/easymockclassextension/2.4/easymockclassextension-2.4.jar:/home/manolo/.m2/repository/org/easymock/easymock/2.4/easymock-2.4.jar:/home/manolo/.m2/repository/cglib/cglib-nodep/2.1_3/cglib-nodep-2.1_3.jar:/home/manolo/.m2/repository/org/jvnet/hudson/main/hudson-core/1.332/hudson-core-1.332.jar:/home/manolo/.m2/repository/org/jvnet/hudson/main/remoting/1.332/remoting-1.332.jar:/home/manolo/.m2/repository/org/jvnet/hudson/main/cli/1.332/cli-1.332.jar:/home/manolo/.m2/repository/org/jvnet/localizer/localizer/1.10/localizer-1.10.jar:/home/manolo/.m2/repository/org/jvnet/hudson/crypto-util/1.0/crypto-util-1.0.jar:/home/manolo/.m2/repository/commons-io/commons-io/1.3.1/commons-io-1.3.1.jar:/home/manolo/.m2/repository/org/jvnet/hudson/jtidy/4aug2000r7-dev-hudson-1/jtidy-4aug2000r7-dev-hudson-1.jar:/home/manolo/.m2/repository/org/jruby/ext/posix/jna-posix/1.0.1/jna-posix-1.0.1.jar:/home/manolo/.m2/repository/org/kohsuke/trilead-putty-extension/1.0/trilead-putty-extension-1.0.jar:/home/manolo/.m2/repository/org/jvnet/hudson/trilead-ssh2/build212-hudson-5/trilead-ssh2-build212-hudson-5.jar:/home/manolo/.m2/repository/org/kohsuke/stapler/stapler-jelly/1.122/stapler-jelly-1.122.jar:/home/manolo/.m2/repository/org/kohsuke/stapler/stapler/1.122/stapler-1.122.jar:/home/manolo/.m2/repository/commons-discovery/commons-discovery/0.4/commons-discovery-0.4.jar:/home/manolo/.m2/repository/commons-logging/commons-logging/1.1/commons-logging-1.1.jar:/home/manolo/.m2/repository/commons-beanutils/commons-beanutils/1.8.0/commons-beanutils-1.8.0.jar:/home/manolo/.m2/repository/org/kohsuke/stapler/json-lib/2.1-rev4/json-lib-2.1-rev4.jar:/home/manolo/.m2/repository/commons-collections/commons-collections/3.2/commons-collections-3.2.jar:/home/manolo/.m2/repository/commons-lang/commons-lang/2.4/commons-lang-2.4.jar:/home/manolo/.m2/repository/net/sf/ezmorph/ezmorph/1.0.3/ezmorph-1.0.3.jar:/home/manolo/.m2/repository/org/jvnet/tiger-types/1.1/tiger-types-1.1.jar:/home/manolo/.m2/repository/commons-fileupload/commons-fileupload/1.2.1/commons-fileupload-1.2.1.jar:/home/manolo/.m2/repository/junit/junit/4.3.1/junit-4.3.1.jar:/home/manolo/.m2/repository/com/google/collections/google-collections/1.0-rc3/google-collections-1.0-rc3.jar:/home/manolo/.m2/repository/args4j/args4j/2.0.16/args4j-2.0.16.jar:/home/manolo/.m2/repository/org/jvnet/hudson/annotation-indexer/1.1/annotation-indexer-1.1.jar:/home/manolo/.m2/repository/org/kohsuke/graph-layouter/1.0/graph-layouter-1.0.jar:/home/manolo/.m2/repository/antlr/antlr/2.7.6/antlr-2.7.6.jar:/home/manolo/.m2/repository/org/jvnet/hudson/xstream/1.3.1-hudson-5/xstream-1.3.1-hudson-5.jar:/home/manolo/.m2/repository/xpp3/xpp3_min/1.1.4c/xpp3_min-1.1.4c.jar:/home/manolo/.m2/repository/jfree/jfreechart/1.0.9/jfreechart-1.0.9.jar:/home/manolo/.m2/repository/jfree/jcommon/1.0.12/jcommon-1.0.12.jar:/home/manolo/.m2/repository/org/apache/ant/ant-junit/1.7.0/ant-junit-1.7.0.jar:/home/manolo/.m2/repository/org/apache/ant/ant/1.7.0/ant-1.7.0.jar:/home/manolo/.m2/repository/org/apache/ant/ant-launcher/1.7.0/ant-launcher-1.7.0.jar:/home/manolo/.m2/repository/commons-digester/commons-digester/1.7/commons-digester-1.7.jar:/home/manolo/.m2/repository/javax/mail/mail/1.4/mail-1.4.jar:/home/manolo/.m2/repository/org/jvnet/hudson/activation/1.1.1-hudson-1/activation-1.1.1-hudson-1.jar:/home/manolo/.m2/repository/org/jvnet/hudson/dom4j/dom4j/1.6.1-hudson-1/dom4j-1.6.1-hudson-1.jar:/home/manolo/.m2/repository/jaxen/jaxen/1.1-beta-11/jaxen-1.1-beta-11.jar:/home/manolo/.m2/repository/commons-jelly/commons-jelly-tags-fmt/1.0/commons-jelly-tags-fmt-1.0.jar:/home/manolo/.m2/repository/commons-jelly/commons-jelly-tags-xml/1.1/commons-jelly-tags-xml-1.1.jar:/home/manolo/.m2/repository/org/jvnet/hudson/commons-jelly-tags-define/1.0.1-hudson-20071021/commons-jelly-tags-define-1.0.1-hudson-20071021.jar:/home/manolo/.m2/repository/org/jvnet/hudson/commons-jelly/1.1-hudson-20090709/commons-jelly-1.1-hudson-20090709.jar:/home/manolo/.m2/repository/org/jvnet/hudson/commons-jexl/1.1-hudson-20090508/commons-jexl-1.1-hudson-20090508.jar:/home/manolo/.m2/repository/org/acegisecurity/acegi-security/1.0.5/acegi-security-1.0.5.jar:/home/manolo/.m2/repository/org/springframework/spring-core/2.5/spring-core-2.5.jar:/home/manolo/.m2/repository/org/springframework/spring-jdbc/1.2.9/spring-jdbc-1.2.9.jar:/home/manolo/.m2/repository/org/springframework/spring-beans/2.5/spring-beans-2.5.jar:/home/manolo/.m2/repository/org/springframework/spring-dao/1.2.9/spring-dao-1.2.9.jar:/home/manolo/.m2/repository/org/springframework/spring-context/2.5/spring-context-2.5.jar:/home/manolo/.m2/repository/commons-codec/commons-codec/1.3/commons-codec-1.3.jar:/home/manolo/.m2/repository/oro/oro/2.0.8/oro-2.0.8.jar:/home/manolo/.m2/repository/log4j/log4j/1.2.9/log4j-1.2.9.jar:/home/manolo/.m2/repository/org/codehaus/groovy/groovy-all/1.6.0/groovy-all-1.6.0.jar:/home/manolo/.m2/repository/jline/jline/0.9.94/jline-0.9.94.jar:/home/manolo/.m2/repository/org/springframework/spring-web/2.5/spring-web-2.5.jar:/home/manolo/.m2/repository/aopalliance/aopalliance/1.0/aopalliance-1.0.jar:/home/manolo/.m2/repository/org/springframework/spring-aop/2.5/spring-aop-2.5.jar:/home/manolo/.m2/repository/xpp3/xpp3/1.1.3.3/xpp3-1.1.3.3.jar:/home/manolo/.m2/repository/javax/servlet/jstl/1.1.0/jstl-1.1.0.jar:/home/manolo/.m2/repository/logkit/logkit/1.0.1/logkit-1.0.1.jar:/home/manolo/.m2/repository/avalon-framework/avalon-framework/4.1.3/avalon-framework-4.1.3.jar:/home/manolo/.m2/repository/javax/servlet/servlet-api/2.4/servlet-api-2.4.jar:/home/manolo/.m2/repository/com/sun/xml/txw2/txw2/20070624/txw2-20070624.jar:/home/manolo/.m2/repository/org/jvnet/winp/winp/1.13/winp-1.13.jar:/home/manolo/.m2/repository/org/jvnet/hudson/memory-monitor/1.1/memory-monitor-1.1.jar:/home/manolo/.m2/repository/net/java/dev/jna/jna/3.2.2/jna-3.2.2.jar:/home/manolo/.m2/repository/com/octo/captcha/jcaptcha-all/1.0-RC6/jcaptcha-all-1.0-RC6.jar:/home/manolo/.m2/repository/commons-pool/commons-pool/1.3/commons-pool-1.3.jar:/home/manolo/.m2/repository/org/codehaus/woodstox/wstx-asl/3.2.7/wstx-asl-3.2.7.jar:/home/manolo/.m2/repository/stax/stax-api/1.0.1/stax-api-1.0.1.jar:/home/manolo/.m2/repository/com/sun/akuma/akuma/1.2/akuma-1.2.jar:/home/manolo/.m2/repository/org/jvnet/libpam4j/libpam4j/1.2/libpam4j-1.2.jar:/home/manolo/.m2/repository/org/jvnet/libzfs/libzfs/0.5/libzfs-0.5.jar:/home/manolo/.m2/repository/com/sun/solaris/embedded_su4j/1.1/embedded_su4j-1.1.jar:/home/manolo/.m2/repository/net/java/sezpoz/sezpoz/1.4/sezpoz-1.4.jar:/home/manolo/.m2/repository/org/jvnet/hudson/jinterop-wmi/1.0/jinterop-wmi-1.0.jar:/home/manolo/.m2/repository/org/kohsuke/jinterop/jinterop-proxy/1.1/jinterop-proxy-1.1.jar:/home/manolo/.m2/repository/org/kohsuke/jinterop/j-interop/2.0.5/j-interop-2.0.5.jar:/home/manolo/.m2/repository/org/kohsuke/jinterop/j-interopdeps/2.0.5/j-interopdeps-2.0.5.jar:/home/manolo/.m2/repository/org/samba/jcifs/jcifs/1.3.3/jcifs-1.3.3.jar:/home/manolo/.m2/repository/org/jvnet/robust-http-client/robust-http-client/1.0/robust-http-client-1.0.jar:/home/manolo/.m2/repository/org/jvnet/hudson/main/hudson-test-harness/1.332/hudson-test-harness-1.332.jar:/home/manolo/.m2/repository/org/jvnet/hudson/main/hudson-war/1.332/hudson-war-1.332-war-for-test.jar:/home/manolo/.m2/repository/org/jvnet/hudson/main/maven-plugin/1.332/maven-plugin-1.332.jar:/home/manolo/.m2/repository/org/jvnet/hudson/main/maven-agent/1.332/maven-agent-1.332.jar:/home/manolo/.m2/repository/org/jvnet/hudson/main/maven-interceptor/1.332/maven-interceptor-1.332.jar:/home/manolo/.m2/repository/org/apache/maven/maven-core/2.0.9/maven-core-2.0.9.jar:/home/manolo/.m2/repository/org/apache/maven/maven-settings/2.0.9/maven-settings-2.0.9.jar:/home/manolo/.m2/repository/org/apache/maven/maven-model/2.0.9/maven-model-2.0.9.jar:/home/manolo/.m2/repository/org/codehaus/plexus/plexus-utils/1.5.1/plexus-utils-1.5.1.jar:/home/manolo/.m2/repository/org/codehaus/plexus/plexus-container-default/1.0-alpha-9-stable-1/plexus-container-default-1.0-alpha-9-stable-1.jar:/home/manolo/.m2/repository/classworlds/classworlds/1.1/classworlds-1.1.jar:/home/manolo/.m2/repository/org/apache/maven/wagon/wagon-file/1.0-beta-2/wagon-file-1.0-beta-2.jar:/home/manolo/.m2/repository/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.jar:/home/manolo/.m2/repository/org/apache/maven/maven-plugin-parameter-documenter/2.0.9/maven-plugin-parameter-documenter-2.0.9.jar:/home/manolo/.m2/repository/slide/slide-webdavlib/2.1/slide-webdavlib-2.1.jar:/home/manolo/.m2/repository/commons-httpclient/commons-httpclient/3.1/commons-httpclient-3.1.jar:/home/manolo/.m2/repository/de/zeigermann/xml/xml-im-exporter/1.1/xml-im-exporter-1.1.jar:/home/manolo/.m2/repository/org/apache/maven/wagon/wagon-http-lightweight/1.0-beta-2/wagon-http-lightweight-1.0-beta-2.jar:/home/manolo/.m2/repository/org/apache/maven/wagon/wagon-http-shared/1.0-beta-2/wagon-http-shared-1.0-beta-2.jar:/home/manolo/.m2/repository/org/apache/maven/reporting/maven-reporting-api/2.0.9/maven-reporting-api-2.0.9.jar:/home/manolo/.m2/repository/org/apache/maven/doxia/doxia-sink-api/1.0-alpha-10/doxia-sink-api-1.0-alpha-10.jar:/home/manolo/.m2/repository/org/apache/maven/maven-profile/2.0.9/maven-profile-2.0.9.jar:/home/manolo/.m2/repository/org/apache/maven/maven-artifact/2.0.9/maven-artifact-2.0.9.jar:/home/manolo/.m2/repository/org/apache/maven/maven-repository-metadata/2.0.9/maven-repository-metadata-2.0.9.jar:/home/manolo/.m2/repository/org/apache/maven/maven-error-diagnostics/2.0.9/maven-error-diagnostics-2.0.9.jar:/home/manolo/.m2/repository/org/apache/maven/maven-project/2.0.9/maven-project-2.0.9.jar:/home/manolo/.m2/repository/org/apache/maven/maven-artifact-manager/2.0.9/maven-artifact-manager-2.0.9.jar:/home/manolo/.m2/repository/org/apache/maven/maven-plugin-registry/2.0.9/maven-plugin-registry-2.0.9.jar:/home/manolo/.m2/repository/org/apache/maven/maven-plugin-api/2.0.9/maven-plugin-api-2.0.9.jar:/home/manolo/.m2/repository/org/apache/maven/wagon/wagon-ssh-external/1.0-beta-2/wagon-ssh-external-1.0-beta-2.jar:/home/manolo/.m2/repository/org/apache/maven/wagon/wagon-ssh-common/1.0-beta-2/wagon-ssh-common-1.0-beta-2.jar:/home/manolo/.m2/repository/org/codehaus/plexus/plexus-interactivity-api/1.0-alpha-4/plexus-interactivity-api-1.0-alpha-4.jar:/home/manolo/.m2/repository/org/apache/maven/maven-plugin-descriptor/2.0.9/maven-plugin-descriptor-2.0.9.jar:/home/manolo/.m2/repository/org/apache/maven/maven-monitor/2.0.9/maven-monitor-2.0.9.jar:/home/manolo/.m2/repository/org/apache/maven/wagon/wagon-ssh/1.0-beta-2/wagon-ssh-1.0-beta-2.jar:/home/manolo/.m2/repository/com/jcraft/jsch/0.1.27/jsch-0.1.27.jar:/home/manolo/.m2/repository/org/jvnet/hudson/maven2.1-interceptor/1.2/maven2.1-interceptor-1.2.jar:/home/manolo/.m2/repository/org/apache/maven/maven-embedder/2.0.4/maven-embedder-2.0.4.jar:/home/manolo/.m2/repository/org/jvnet/hudson/wagon-webdav/1.0-beta-2-hudson-1/wagon-webdav-1.0-beta-2-hudson-1.jar:/home/manolo/.m2/repository/org/jvnet/hudson/plugins/subversion/1.7/subversion-1.7.jar:/home/manolo/.m2/repository/org/jvnet/hudson/svnkit/svnkit/1.3.0-hudson-2/svnkit-1.3.0-hudson-2.jar:/home/manolo/.m2/repository/org/mortbay/jetty/jetty/6.1.11/jetty-6.1.11.jar:/home/manolo/.m2/repository/org/mortbay/jetty/jetty-util/6.1.11/jetty-util-6.1.11.jar:/home/manolo/.m2/repository/org/mortbay/jetty/servlet-api-2.5/6.1.11/servlet-api-2.5-6.1.11.jar:/home/manolo/.m2/repository/org/jvnet/mock-javamail/mock-javamail/1.7/mock-javamail-1.7.jar:/home/manolo/.m2/repository/org/jvnet/hudson/htmlunit/2.2-hudson-10/htmlunit-2.2-hudson-10.jar:/home/manolo/.m2/repository/xalan/xalan/2.7.0/xalan-2.7.0.jar:/home/manolo/.m2/repository/org/jvnet/hudson/htmlunit-core-js/2.2-hudson-2/htmlunit-core-js-2.2-hudson-2.jar:/home/manolo/.m2/repository/net/sourceforge/nekohtml/nekohtml/1.9.8/nekohtml-1.9.8.jar:/home/manolo/.m2/repository/xerces/xercesImpl/2.8.1/xercesImpl-2.8.1.jar:/home/manolo/.m2/repository/net/sourceforge/cssparser/cssparser/0.9.5/cssparser-0.9.5.jar:/home/manolo/.m2/repository/org/w3c/css/sac/1.3/sac-1.3.jar:/home/manolo/.m2/repository/org/jvnet/hudson/embedded-rhino-debugger/1.1/embedded-rhino-debugger-1.1.jar:/home/manolo/.m2/repository/org/jvnet/hudson/netx/0.5-hudson-2/netx-0.5-hudson-2.jar:\"/>\n    <property name=\"java.vm.specification.version\" value=\"1.0\"/>\n    <property name=\"sun.arch.data.model\" value=\"64\"/>\n    <property name=\"java.home\" value=\"/usr/lib/jvm/java-6-sun-1.6.0.20/jre\"/>\n    <property name=\"svnkit.ssh2.persistent\" value=\"false\"/>\n    <property name=\"java.specification.vendor\" value=\"Sun Microsystems Inc.\"/>\n    <property name=\"user.language\" value=\"en\"/>\n    <property name=\"java.vm.info\" value=\"mixed mode\"/>\n    <property name=\"java.version\" value=\"1.6.0_20\"/>\n    <property name=\"java.ext.dirs\" value=\"/usr/lib/jvm/java-6-sun-1.6.0.20/jre/lib/ext:/usr/java/packages/lib/ext\"/>\n    <property name=\"sun.boot.class.path\" value=\"/usr/lib/jvm/java-6-sun-1.6.0.20/jre/lib/resources.jar:/usr/lib/jvm/java-6-sun-1.6.0.20/jre/lib/rt.jar:/usr/lib/jvm/java-6-sun-1.6.0.20/jre/lib/sunrsasign.jar:/usr/lib/jvm/java-6-sun-1.6.0.20/jre/lib/jsse.jar:/usr/lib/jvm/java-6-sun-1.6.0.20/jre/lib/jce.jar:/usr/lib/jvm/java-6-sun-1.6.0.20/jre/lib/charsets.jar:/usr/lib/jvm/java-6-sun-1.6.0.20/jre/classes\"/>\n    <property name=\"java.vendor\" value=\"Sun Microsystems Inc.\"/>\n    <property name=\"localRepository\" value=\"/home/manolo/.m2/repository\"/>\n    <property name=\"file.separator\" value=\"/\"/>\n    <property name=\"java.vendor.url.bug\" value=\"http://java.sun.com/cgi-bin/bugreport.cgi\"/>\n    <property name=\"sun.cpu.endian\" value=\"little\"/>\n    <property name=\"sun.io.unicode.encoding\" value=\"UnicodeLittle\"/>\n    <property name=\"sun.desktop\" value=\"gnome\"/>\n    <property name=\"sun.cpu.isalist\" value=\"\"/>\n  </properties>\n  <testcase time=\"0.001\" classname=\"hudson.plugins.performance.reports.UriReportTest\" name=\"testCountErrors\"/>\n  <testcase time=\"0.001\" classname=\"hudson.plugins.performance.reports.UriReportTest\" name=\"testGetAverage\"/>\n  <testcase time=\"0.026\" classname=\"hudson.plugins.performance.reports.UriReportTest\" name=\"testGetMax\">\n   <failure message=\"\" type=\"java.lang.AssertionError\">java.lang.AssertionError:\n        at org.junit.Assert.fail(Assert.java:71)\n   </failure>\n  </testcase>\n  <testcase time=\"0.031\" classname=\"hudson.plugins.performance.reports.UriReportTest\" name=\"testGetMin\"/>\n  <testcase time=\"0.001\" classname=\"hudson.plugins.performance.reports.UriReportTest\" name=\"testIsFailed\"/>\n</testsuite>\n"
  },
  {
    "path": "src/test/resources/TEST-results.xml",
    "content": "<testsuites>\n  <testsuite errors=\"0\"\n             failures=\"0\"\n             tests=\"4\"\n             time=\"0.5798499584198\"\n             name=\"00-compile_t\">\n    <testcase time=\"0.262654066085815\"\n              name=\"1 - use ACLBot::Storage;\"></testcase>\n    <testcase name=\"2 - use ACLBot::Netmap;\" time=\"0.00218796730041504\"></testcase>\n    <testcase time=\"0.00153183937072754\"\n              name=\"3 - use Cisco::Portmap;\"></testcase>\n    <testcase time=\"0.00264906883239746\"\n              name=\"4 - use Cisco::ACL::Generator;\"></testcase>\n    <testcase time=\"0.23412299156189\" name=\"(teardown)\" />\n    <system-out><![CDATA[ok 1 - use ACLBot::Storage;\nok 2 - use ACLBot::Netmap;\nok 3 - use Cisco::Portmap;\nok 4 - use Cisco::ACL::Generator;\n1..4\n]]></system-out>\n    <system-err></system-err>\n  </testsuite>\n  <testsuite time=\"0.6350998878479\"\n             name=\"01-storage_t\"\n             tests=\"16\"\n             failures=\"0\"\n             errors=\"0\">\n    <testcase name=\"1 - fail if cant connect to db\" time=\"0.344143867492676\"></testcase>\n    <testcase time=\"0.00188207626342773\"\n              name=\"2 - fail if cant create table\"></testcase>\n    <testcase name=\"3 - An object of class 'ACLBot::Storage' isa 'ACLBot::Storage'\" time=\"0.0179200172424316\"></testcase>\n    <testcase time=\"0.000267982482910156\" name=\"4 - empty input\"></testcase>\n    <testcase time=\"0.000181913375854492\" name=\"5 - no expire\"></testcase>\n    <testcase name=\"6 - Add ACL\" time=\"0.0174431800842285\"></testcase>\n    <testcase time=\"0.00342202186584473\"\n              name=\"7 - get single acl and validate fields\"></testcase>\n    <testcase time=\"0.00336384773254395\"\n              name=\"8 - get all acl and validate added one\"></testcase>\n    <testcase name=\"9 - remove acl\" time=\"0.0134179592132568\"></testcase>\n    <testcase time=\"0.000571966171264648\"\n              name=\"10 - remove successful\"></testcase>\n    <testcase name=\"11 - Add expired ACL\" time=\"0.0156941413879395\"></testcase>\n    <testcase time=\"0.00052189826965332\"\n              name=\"12 - expired acl not returned\"></testcase>\n    <testcase time=\"0.026278018951416\"\n              name=\"13 - do not add duplicates\"></testcase>\n    <testcase name=\"14 - expire time should be updated if acl is duplicate but have later expiry\" time=\"0.000694990158081055\"></testcase>\n    <testcase name=\"15 - comment should be updated together with time\" time=\"0.000492095947265625\"></testcase>\n    <testcase time=\"0.00173187255859375\"\n              name=\"16 - do not add ACL that resolve to same network range\"></testcase>\n    <testcase name=\"(teardown)\" time=\"0.186705827713013\" />\n    <system-out><![CDATA[ok 1 - fail if cant connect to db\nok 2 - fail if cant create table\nok 3 - An object of class 'ACLBot::Storage' isa 'ACLBot::Storage'\nok 4 - empty input\nok 5 - no expire\nok 6 - Add ACL\n    # Subtest: get single acl and validate fields\n    ok 1 - proto\n    ok 2 - src_addr\n    ok 3 - dst_addr\n    ok 4 - dst_port\n    1..4\nok 7 - get single acl and validate fields\n    # Subtest: get all acl and validate added one\n    ok 1 - proto\n    ok 2 - src_addr\n    ok 3 - dst_addr\n    ok 4 - dst_port\n    1..4\nok 8 - get all acl and validate added one\nok 9 - remove acl\nok 10 - remove successful\nok 11 - Add expired ACL\nok 12 - expired acl not returned\nok 13 - do not add duplicates\nok 14 - expire time should be updated if acl is duplicate but have later expiry\nok 15 - comment should be updated together with time\nok 16 - do not add ACL that resolve to same network range\n1..16\n]]></system-out>\n    <system-err></system-err>\n  </testsuite>\n  <testsuite failures=\"0\"\n             errors=\"0\"\n             time=\"0.458131074905396\"\n             name=\"02-cisco-portmap_t\"\n             tests=\"16\">\n    <testcase time=\"0.279895067214966\"\n              name=\"1 - An object of class 'Cisco::Portmap' isa 'Cisco::Portmap'\"></testcase>\n    <testcase time=\"0.00489306449890137\"\n              name=\"2 - TCP cisco service name to port\"></testcase>\n    <testcase time=\"0.00535106658935547\"\n              name=\"3 - TCP port to cisco service name\"></testcase>\n    <testcase time=\"0.00356698036193848\"\n              name=\"4 - UDP cisco service name to port\"></testcase>\n    <testcase name=\"5 - UDP port to cisco service name\" time=\"0.00378084182739258\"></testcase>\n    <testcase time=\"0.00261497497558594\"\n              name=\"6 - ICMP cisco service name to port\"></testcase>\n    <testcase time=\"0.00289416313171387\"\n              name=\"7 - ICMP port to cisco service name\"></testcase>\n    <testcase name=\"8 - not udp service\" time=\"0.000303030014038086\"></testcase>\n    <testcase time=\"0.000204801559448242\"\n              name=\"9 - nonexisting service\"></testcase>\n    <testcase time=\"0.000207185745239258\"\n              name=\"10 - cisco uses www instead of http because fuck cisco\"></testcase>\n    <testcase name=\"11 - fail on unknown protocol\" time=\"0.000885009765625\"></testcase>\n    <testcase name=\"12 - fail on unknown protocol\" time=\"0.00055384635925293\"></testcase>\n    <testcase time=\"0.000611066818237305\"\n              name=\"13 - port out of range\"></testcase>\n    <testcase time=\"0.000683069229125977\"\n              name=\"14 - port out of range\"></testcase>\n    <testcase name=\"15 - code out of range\" time=\"0.000484943389892578\"></testcase>\n    <testcase name=\"16 - NaN\" time=\"0.000633001327514648\"></testcase>\n    <testcase time=\"0.150335073471069\" name=\"(teardown)\" />\n    <system-out><![CDATA[ok 1 - An object of class 'Cisco::Portmap' isa 'Cisco::Portmap'\n    # Subtest: TCP cisco service name to port\n    ok 1 - TCP: bgp to 179\n    ok 2 - TCP: chargen to 19\n    ok 3 - TCP: cmd to 514\n    ok 4 - TCP: daytime to 13\n    ok 5 - TCP: discard to 9\n    ok 6 - TCP: domain to 53\n    ok 7 - TCP: drip to 3949\n    ok 8 - TCP: ftp to 21\n    ok 9 - TCP: ftp-data to 20\n    ok 10 - TCP: pop3 to 110\n    ok 11 - TCP: smtp to 25\n    ok 12 - TCP: www to 80\n    1..12\nok 2 - TCP cisco service name to port\n    # Subtest: TCP port to cisco service name\n    ok 1 - TCP: 9 to discard\n    ok 2 - TCP: 13 to daytime\n    ok 3 - TCP: 19 to chargen\n    ok 4 - TCP: 20 to ftp-data\n    ok 5 - TCP: 21 to ftp\n    ok 6 - TCP: 25 to smtp\n    ok 7 - TCP: 53 to domain\n    ok 8 - TCP: 80 to www\n    ok 9 - TCP: 110 to pop3\n    ok 10 - TCP: 179 to bgp\n    ok 11 - TCP: 514 to cmd\n    ok 12 - TCP: 3949 to drip\n    1..12\nok 3 - TCP port to cisco service name\n    # Subtest: UDP cisco service name to port\n    ok 1 - UDP: bootpc to 68\n    ok 2 - UDP: bootps to 67\n    ok 3 - UDP: netbios-dgm to 138\n    ok 4 - UDP: netbios-ns to 137\n    ok 5 - UDP: netbios-ss to 139\n    ok 6 - UDP: snmp to 161\n    ok 7 - UDP: snmptrap to 162\n    ok 8 - UDP: sunrpc to 111\n    1..8\nok 4 - UDP cisco service name to port\n    # Subtest: UDP port to cisco service name\n    ok 1 - UDP: 67 to bootps\n    ok 2 - UDP: 68 to bootpc\n    ok 3 - UDP: 111 to sunrpc\n    ok 4 - UDP: 137 to netbios-ns\n    ok 5 - UDP: 138 to netbios-dgm\n    ok 6 - UDP: 139 to netbios-ss\n    ok 7 - UDP: 161 to snmp\n    ok 8 - UDP: 162 to snmptrap\n    1..8\nok 5 - UDP port to cisco service name\n    # Subtest: ICMP cisco service name to port\n    ok 1 - ICMP: echo to 8\n    ok 2 - ICMP: echo-reply to 0\n    ok 3 - ICMP: time-exceeded to 11\n    ok 4 - ICMP: timestamp-reply to 14\n    ok 5 - ICMP: timestamp-request to 13\n    1..5\nok 6 - ICMP cisco service name to port\n    # Subtest: ICMP port to cisco service name\n    ok 1 - ICMP: 0 to echo-reply\n    ok 2 - ICMP: 8 to echo\n    ok 3 - ICMP: 11 to time-exceeded\n    ok 4 - ICMP: 13 to timestamp-request\n    ok 5 - ICMP: 14 to timestamp-reply\n    1..5\nok 7 - ICMP port to cisco service name\nok 8 - not udp service\nok 9 - nonexisting service\nok 10 - cisco uses www instead of http because fuck cisco\nok 11 - fail on unknown protocol\nok 12 - fail on unknown protocol\nok 13 - port out of range\nok 14 - port out of range\nok 15 - code out of range\nok 16 - NaN\n1..16\n]]></system-out>\n    <system-err></system-err>\n  </testsuite>\n  <testsuite tests=\"10\"\n             name=\"03-aclgen_t\"\n             time=\"0.493135929107666\"\n             errors=\"0\"\n             failures=\"0\">\n    <testcase name=\"1 - An object of class 'Cisco::ACL::Generator' isa 'Cisco::ACL::Generator'\" time=\"0.301930904388428\"></testcase>\n    <testcase name=\"2 - destination\" time=\"0.00803804397583008\"></testcase>\n    <testcase name=\"3 - wildcard\" time=\"0.000364065170288086\"></testcase>\n    <testcase time=\"0.000561952590942383\" name=\"4 - range\"></testcase>\n    <testcase name=\"5 - any source\" time=\"0.000203847885131836\"></testcase>\n    <testcase name=\"6 - IP out of range\" time=\"0.000225067138671875\"></testcase>\n    <testcase time=\"0.000546932220458984\"\n              name=\"7 - Port out of range\"></testcase>\n    <testcase time=\"0.000221014022827148\"\n              name=\"8 - range without operator\"></testcase>\n    <testcase name=\"9 - range not a digit\" time=\"0.00021815299987793\"></testcase>\n    <testcase time=\"0.000205039978027344\"\n              name=\"10 - invalid operator\"></testcase>\n    <testcase name=\"(teardown)\" time=\"0.180413007736206\" />\n    <system-out><![CDATA[ok 1 - An object of class 'Cisco::ACL::Generator' isa 'Cisco::ACL::Generator'\nok 2 - destination\nok 3 - wildcard\n--- 80\n--- 90\nok 4 - range\nok 5 - any source\nok 6 - IP out of range\n--- 80\n--- 65536\nok 7 - Port out of range\nok 8 - range without operator\nok 9 - range not a digit\nok 10 - invalid operator\n1..10\n]]></system-out>\n    <system-err></system-err>\n  </testsuite>\n  <testsuite failures=\"0\"\n             errors=\"0\"\n             time=\"0.474467992782593\"\n             name=\"04-netmap_t\"\n             tests=\"12\">\n    <testcase time=\"0.34987998008728\" name=\"1 - empty map\"></testcase>\n    <testcase time=\"0.00766992568969727\" name=\"2 - bad map\"></testcase>\n    <testcase name=\"3 - Created\" time=\"0.000236034393310547\"></testcase>\n    <testcase name=\"4 - ip from testacl1\" time=\"0.000212907791137695\"></testcase>\n    <testcase time=\"0.000239133834838867\" name=\"5 - ip from testacl2\"></testcase>\n    <testcase time=\"0.000218868255615234\" name=\"6 - ip from testacl3\"></testcase>\n    <testcase name=\"7 - ip outside of acl\" time=\"0.000190019607543945\"></testcase>\n    <testcase time=\"0.00018620491027832\"\n              name=\"8 - net from testacl1\"></testcase>\n    <testcase time=\"0.000177860260009766\"\n              name=\"9 - net from testacl2\"></testcase>\n    <testcase time=\"0.000251054763793945\"\n              name=\"10 - net from testacl3\"></testcase>\n    <testcase time=\"0.00020909309387207\"\n              name=\"11 - ip outside of acl\"></testcase>\n    <testcase name=\"12 - not cidr\" time=\"0.00246882438659668\"></testcase>\n    <testcase time=\"0.112221002578735\" name=\"(teardown)\" />\n    <system-out><![CDATA[ok 1 - empty map\nok 2 - bad map\nok 3 - Created\nok 4 - ip from testacl1\nok 5 - ip from testacl2\nok 6 - ip from testacl3\nok 7 - ip outside of acl\nok 8 - net from testacl1\nok 9 - net from testacl2\nok 10 - net from testacl3\nok 11 - ip outside of acl\nok 12 - not cidr\n1..12\n]]></system-out>\n    <system-err></system-err>\n  </testsuite>\n</testsuites>\n"
  },
  {
    "path": "src/test/resources/TaurusPreviousBuildReport.xml",
    "content": "<?xml version='1.0' encoding='UTF-8'?>\n<FinalStatus>\n    <ReportURL>https://test_url.com/summary</ReportURL>\n    <Group label=\"\">\n        <avg_ct value=\"0\">\n            <name>avg_ct</name>\n            <value>0</value>\n        </avg_ct>\n        <stdev_rt value=\"3.16982\">\n            <name>stdev_rt</name>\n            <value>3.16982</value>\n        </stdev_rt>\n        <avg_lt value=\"0.79907\">\n            <name>avg_lt</name>\n            <value>0.79907</value>\n        </avg_lt>\n        <rc value=\"440\" param=\"200\">\n            <name>rc/200</name>\n            <value>440</value>\n        </rc>\n        <rc value=\"3\" param=\"503\">\n            <name>rc/503</name>\n            <value>3</value>\n        </rc>\n        <rc value=\"2\" param=\"ConnectException\">\n            <name>rc/ConnectException</name>\n            <value>2</value>\n        </rc>\n        <bytes value=\"4594038\">\n            <name>bytes</name>\n            <value>4594038</value>\n        </bytes>\n        <perc value=\"3.61700\" param=\"95.0\">\n            <name>perc/95.0</name>\n            <value>3.61700</value>\n        </perc>\n        <perc value=\"0.05800\" param=\"0.0\">\n            <name>perc/0.0</name>\n            <value>0.05800</value>\n        </perc>\n        <perc value=\"15.69500\" param=\"99.9\">\n            <name>perc/99.9</name>\n            <value>15.69500</value>\n        </perc>\n        <perc value=\"0.94500\" param=\"90.0\">\n            <name>perc/90.0</name>\n            <value>0.94500</value>\n        </perc>\n        <perc value=\"0.94500\" param=\"95.0\">\n            <name>perc/95.0</name>\n            <value>0.94500</value>\n        </perc>\n        <perc value=\"15.69500\" param=\"100.0\">\n            <name>perc/100.0</name>\n            <value>15.69500</value>\n        </perc>\n        <perc value=\"15.61000\" param=\"99.0\">\n            <name>perc/99.0</name>\n            <value>15.61000</value>\n        </perc>\n        <perc value=\"0.20100\" param=\"50.0\">\n            <name>perc/50.0</name>\n            <value>0.20100</value>\n        </perc>\n        <succ value=\"440\">\n            <name>succ</name>\n            <value>440</value>\n        </succ>\n        <throughput value=\"445\">\n            <name>throughput</name>\n            <value>445</value>\n        </throughput>\n        <concurrency value=\"9\">\n            <name>concurrency</name>\n            <value>9</value>\n        </concurrency>\n        <avg_rt value=\"0.85988\">\n            <name>avg_rt</name>\n            <value>0.85988</value>\n        </avg_rt>\n        <fail value=\"5\">\n            <name>fail</name>\n            <value>5</value>\n        </fail>\n    </Group>\n    <Group label=\"http://test_url1.org/\">\n        <avg_ct value=\"0\">\n            <name>avg_ct</name>\n            <value>0</value>\n        </avg_ct>\n        <stdev_rt value=\"0.10286\">\n            <name>stdev_rt</name>\n            <value>0.10286</value>\n        </stdev_rt>\n        <avg_lt value=\"0.10228\">\n            <name>avg_lt</name>\n            <value>0.10228</value>\n        </avg_lt>\n        <rc value=\"224\" param=\"200\">\n            <name>rc/200</name>\n            <value>224</value>\n        </rc>\n        <bytes value=\"1764229\">\n            <name>bytes</name>\n            <value>1764229</value>\n        </bytes>\n        <perc value=\"0.18400\" param=\"95.0\">\n            <name>perc/95.0</name>\n            <value>0.18400</value>\n        </perc>\n        <perc value=\"0.05800\" param=\"0.0\">\n            <name>perc/0.0</name>\n            <value>0.05800</value>\n        </perc>\n        <perc value=\"0.28500\" param=\"99.9\">\n            <name>perc/99.9</name>\n            <value>0.28500</value>\n        </perc>\n        <perc value=\"0.16700\" param=\"90.0\">\n            <name>perc/90.0</name>\n            <value>0.16700</value>\n        </perc>\n        <perc value=\"0.16700\" param=\"95.0\">\n            <name>perc/95.0</name>\n            <value>0.16700</value>\n        </perc>\n        <perc value=\"0.28500\" param=\"100.0\">\n            <name>perc/100.0</name>\n            <value>0.28500</value>\n        </perc>\n        <perc value=\"0.26900\" param=\"99.0\">\n            <name>perc/99.0</name>\n            <value>0.26900</value>\n        </perc>\n        <perc value=\"0.06600\" param=\"50.0\">\n            <name>perc/50.0</name>\n            <value>0.06600</value>\n        </perc>\n        <succ value=\"224\">\n            <name>succ</name>\n            <value>224</value>\n        </succ>\n        <throughput value=\"224\">\n            <name>throughput</name>\n            <value>224</value>\n        </throughput>\n        <concurrency value=\"16\">\n            <name>concurrency</name>\n            <value>16</value>\n        </concurrency>\n        <avg_rt value=\"0.10234\">\n            <name>avg_rt</name>\n            <value>0.10234</value>\n        </avg_rt>\n        <fail value=\"0\">\n            <name>fail</name>\n            <value>0</value>\n        </fail>\n    </Group>\n    <Group label=\"http://test_url2.com/\">\n        <avg_ct value=\"0\">\n            <name>avg_ct</name>\n            <value>0</value>\n        </avg_ct>\n        <stdev_rt value=\"3.38245\">\n            <name>stdev_rt</name>\n            <value>3.38245</value>\n        </stdev_rt>\n        <avg_lt value=\"1.50533\">\n            <name>avg_lt</name>\n            <value>1.50533</value>\n        </avg_lt>\n        <rc value=\"216\" param=\"200\">\n            <name>rc/200</name>\n            <value>216</value>\n        </rc>\n        <rc value=\"3\" param=\"503\">\n            <name>rc/503</name>\n            <value>3</value>\n        </rc>\n        <rc value=\"2\" param=\"ConnectException\">\n            <name>rc/ConnectException</name>\n            <value>2</value>\n        </rc>\n        <bytes value=\"2829809\">\n            <name>bytes</name>\n            <value>2829809</value>\n        </bytes>\n        <perc value=\"7.68900\" param=\"95.0\">\n            <name>perc/95.0</name>\n            <value>7.68900</value>\n        </perc>\n        <perc value=\"0.16200\" param=\"0.0\">\n            <name>perc/0.0</name>\n            <value>0.16200</value>\n        </perc>\n        <perc value=\"15.69500\" param=\"99.9\">\n            <name>perc/99.9</name>\n            <value>15.69500</value>\n        </perc>\n        <perc value=\"3.61700\" param=\"90.0\">\n            <name>perc/90.0</name>\n            <value>3.61700</value>\n        </perc>\n        <perc value=\"3.61700\" param=\"95.0\">\n            <name>perc/95.0</name>\n            <value>3.61700</value>\n        </perc>\n        <perc value=\"15.69500\" param=\"100.0\">\n            <name>perc/100.0</name>\n            <value>15.69500</value>\n        </perc>\n        <perc value=\"15.64300\" param=\"99.0\">\n            <name>perc/99.0</name>\n            <value>15.64300</value>\n        </perc>\n        <perc value=\"0.66900\" param=\"50.0\">\n            <name>perc/50.0</name>\n            <value>0.66900</value>\n        </perc>\n        <succ value=\"216\">\n            <name>succ</name>\n            <value>216</value>\n        </succ>\n        <throughput value=\"221\">\n            <name>throughput</name>\n            <value>221</value>\n        </throughput>\n        <concurrency value=\"9\">\n            <name>concurrency</name>\n            <value>9</value>\n        </concurrency>\n        <avg_rt value=\"1.62770\">\n            <name>avg_rt</name>\n            <value>1.62770</value>\n        </avg_rt>\n        <fail value=\"5\">\n            <name>fail</name>\n            <value>5</value>\n        </fail>\n    </Group>\n</FinalStatus>\n"
  },
  {
    "path": "src/test/resources/TaurusXMLReport.xml",
    "content": "<?xml version='1.0' encoding='UTF-8'?>\n<FinalStatus>\n  <ReportURL>https://link_for_report.com/aaaa/bbb/report</ReportURL>\n  <Group label=\"\">\n    <avg_ct value=\"0\">\n      <name>avg_ct</name>\n      <value>0</value>\n    </avg_ct>\n    <stdev_rt value=\"0.64395\">\n      <name>stdev_rt</name>\n      <value>0.64395</value>\n    </stdev_rt>\n    <avg_lt value=\"0.39795\">\n      <name>avg_lt</name>\n      <value>0.39795</value>\n    </avg_lt>\n    <rc value=\"666\" param=\"200\">\n      <name>rc/200</name>\n      <value>666</value>\n    </rc>\n    <rc value=\"11\" param=\"503\">\n      <name>rc/503</name>\n      <value>11</value>\n    </rc>\n    <bytes value=\"6946463\">\n      <name>bytes</name>\n      <value>6946463</value>\n    </bytes>\n    <perc value=\"1.29300\" param=\"95.0\">\n      <name>perc/95.0</name>\n      <value>1.29300</value>\n    </perc>\n    <perc value=\"0.06400\" param=\"0.0\">\n      <name>perc/0.0</name>\n      <value>0.06400</value>\n    </perc>\n    <perc value=\"1.71800\" param=\"99.9\">\n      <name>perc/99.9</name>\n      <value>1.71800</value>\n    </perc>\n    <perc value=\"1.15800\" param=\"90.0\">\n      <name>perc/90.0</name>\n      <value>1.15800</value>\n    </perc>\n    <perc value=\"1.71800\" param=\"100.0\">\n      <name>perc/100.0</name>\n      <value>1.71800</value>\n    </perc>\n    <perc value=\"1.49300\" param=\"99.0\">\n      <name>perc/99.0</name>\n      <value>1.49300</value>\n    </perc>\n    <perc value=\"0.18700\" param=\"50.0\">\n      <name>perc/50.0</name>\n      <value>0.18700</value>\n    </perc>\n    <succ value=\"666\">\n      <name>succ</name>\n      <value>666</value>\n    </succ>\n    <throughput value=\"677\">\n      <name>throughput</name>\n      <value>677</value>\n    </throughput>\n    <concurrency value=\"16\">\n      <name>concurrency</name>\n      <value>16</value>\n    </concurrency>\n    <avg_rt value=\"0.45950\">\n      <name>avg_rt</name>\n      <value>0.45950</value>\n    </avg_rt>\n    <fail value=\"11\">\n      <name>fail</name>\n      <value>11</value>\n    </fail>\n  </Group>\n  <Group label=\"http://test_url1.org/\">\n    <avg_ct value=\"0\">\n      <name>avg_ct</name>\n      <value>0</value>\n    </avg_ct>\n    <stdev_rt value=\"0.43299\">\n      <name>stdev_rt</name>\n      <value>0.43299</value>\n    </stdev_rt>\n    <avg_lt value=\"0.68278\">\n      <name>avg_lt</name>\n      <value>0.68278</value>\n    </avg_lt>\n    <rc value=\"326\" param=\"200\">\n      <name>rc/200</name>\n      <value>326</value>\n    </rc>\n    <rc value=\"11\" param=\"503\">\n      <name>rc/503</name>\n      <value>11</value>\n    </rc>\n    <bytes value=\"4268617\">\n      <name>bytes</name>\n      <value>4268617</value>\n    </bytes>\n    <perc value=\"1.42000\" param=\"95.0\">\n      <name>perc/95.0</name>\n      <value>1.42000</value>\n    </perc>\n    <perc value=\"0.15600\" param=\"0.0\">\n      <name>perc/0.0</name>\n      <value>0.15600</value>\n    </perc>\n    <perc value=\"1.71800\" param=\"99.9\">\n      <name>perc/99.9</name>\n      <value>1.71800</value>\n    </perc>\n    <perc value=\"1.29300\" param=\"90.0\">\n      <name>perc/90.0</name>\n      <value>1.29300</value>\n    </perc>\n    <perc value=\"1.71800\" param=\"100.0\">\n      <name>perc/100.0</name>\n      <value>1.71800</value>\n    </perc>\n    <perc value=\"1.56700\" param=\"99.0\">\n      <name>perc/99.0</name>\n      <value>1.56700</value>\n    </perc>\n    <perc value=\"0.84300\" param=\"50.0\">\n      <name>perc/50.0</name>\n      <value>0.84300</value>\n    </perc>\n    <succ value=\"326\">\n      <name>succ</name>\n      <value>326</value>\n    </succ>\n    <throughput value=\"337\">\n      <name>throughput</name>\n      <value>337</value>\n    </throughput>\n    <concurrency value=\"1\">\n      <name>concurrency</name>\n      <value>1</value>\n    </concurrency>\n    <avg_rt value=\"0.80638\">\n      <name>avg_rt</name>\n      <value>0.80638</value>\n    </avg_rt>\n    <fail value=\"11\">\n      <name>fail</name>\n      <value>11</value>\n    </fail>\n  </Group>\n  <Group label=\"http://test_url2.com/\">\n    <avg_ct value=\"0\">\n      <name>avg_ct</name>\n      <value>0</value>\n    </avg_ct>\n    <stdev_rt value=\"0.14804\">\n      <name>stdev_rt</name>\n      <value>0.14804</value>\n    </stdev_rt>\n    <avg_lt value=\"0.11562\">\n      <name>avg_lt</name>\n      <value>0.11562</value>\n    </avg_lt>\n    <rc value=\"340\" param=\"200\">\n      <name>rc/200</name>\n      <value>340</value>\n    </rc>\n    <bytes value=\"2677846\">\n      <name>bytes</name>\n      <value>2677846</value>\n    </bytes>\n    <perc value=\"0.20400\" param=\"95.0\">\n      <name>perc/95.0</name>\n      <value>0.20400</value>\n    </perc>\n    <perc value=\"0.06400\" param=\"0.0\">\n      <name>perc/0.0</name>\n      <value>0.06400</value>\n    </perc>\n    <perc value=\"0.52200\" param=\"99.9\">\n      <name>perc/99.9</name>\n      <value>0.52200</value>\n    </perc>\n    <perc value=\"0.18900\" param=\"90.0\">\n      <name>perc/90.0</name>\n      <value>0.18900</value>\n    </perc>\n    <perc value=\"0.52200\" param=\"100.0\">\n      <name>perc/100.0</name>\n      <value>0.52200</value>\n    </perc>\n    <perc value=\"0.31900\" param=\"99.0\">\n      <name>perc/99.0</name>\n      <value>0.31900</value>\n    </perc>\n    <perc value=\"0.07200\" param=\"50.0\">\n      <name>perc/50.0</name>\n      <value>0.07200</value>\n    </perc>\n    <succ value=\"340\">\n      <name>succ</name>\n      <value>340</value>\n    </succ>\n    <throughput value=\"340\">\n      <name>throughput</name>\n      <value>340</value>\n    </throughput>\n    <concurrency value=\"16\">\n      <name>concurrency</name>\n      <value>16</value>\n    </concurrency>\n    <avg_rt value=\"0.11568\">\n      <name>avg_rt</name>\n      <value>0.11568</value>\n    </avg_rt>\n    <fail value=\"0\">\n      <name>fail</name>\n      <value>0</value>\n    </fail>\n  </Group>\n</FinalStatus>\n"
  },
  {
    "path": "src/test/resources/TaurusXmlWithDuration.xml",
    "content": "<?xml version='1.0' encoding='UTF-8'?>\n<FinalStatus>\n    <TestDuration>3.141592</TestDuration>\n    <Group label=\"\">\n        <rc value=\"2\" param=\"200\">\n            <name>rc/200</name>\n            <value>2</value>\n        </rc>\n        <rc value=\"29656\" param=\"304\">\n            <name>rc/304</name>\n            <value>29656</value>\n        </rc>\n        <rc value=\"29656\" param=\"403\">\n            <name>rc/403</name>\n            <value>29656</value>\n        </rc>\n        <avg_lt value=\"0.00028\">\n            <name>avg_lt</name>\n            <value>0.00028</value>\n        </avg_lt>\n        <throughput value=\"59314\">\n            <name>throughput</name>\n            <value>59314</value>\n        </throughput>\n        <avg_rt value=\"0.00054\">\n            <name>avg_rt</name>\n            <value>0.00054</value>\n        </avg_rt>\n        <perc value=\"0.00000\" param=\"50.0\">\n            <name>perc/50.0</name>\n            <value>0.00000</value>\n        </perc>\n        <perc value=\"0.00100\" param=\"95.0\">\n            <name>perc/95.0</name>\n            <value>0.00100</value>\n        </perc>\n        <perc value=\"0.00300\" param=\"99.0\">\n            <name>perc/99.0</name>\n            <value>0.00300</value>\n        </perc>\n        <perc value=\"0.00000\" param=\"0.0\">\n            <name>perc/0.0</name>\n            <value>0.00000</value>\n        </perc>\n        <perc value=\"0.00800\" param=\"99.9\">\n            <name>perc/99.9</name>\n            <value>0.00800</value>\n        </perc>\n        <perc value=\"0.08100\" param=\"100.0\">\n            <name>perc/100.0</name>\n            <value>0.08100</value>\n        </perc>\n        <perc value=\"0.00100\" param=\"90.0\">\n            <name>perc/90.0</name>\n            <value>0.00100</value>\n        </perc>\n        <stdev_rt value=\"0.04948\">\n            <name>stdev_rt</name>\n            <value>0.04948</value>\n        </stdev_rt>\n        <concurrency value=\"0\">\n            <name>concurrency</name>\n            <value>0</value>\n        </concurrency>\n        <fail value=\"29656\">\n            <name>fail</name>\n            <value>29656</value>\n        </fail>\n        <avg_ct value=\"0.00001\">\n            <name>avg_ct</name>\n            <value>0.00001</value>\n        </avg_ct>\n        <bytes value=\"0\">\n            <name>bytes</name>\n            <value>0</value>\n        </bytes>\n        <succ value=\"29658\">\n            <name>succ</name>\n            <value>29658</value>\n        </succ>\n    </Group>\n    <Group label=\"http://192.168.1.1/anotherquery\">\n        <rc value=\"29656\" param=\"403\">\n            <name>rc/403</name>\n            <value>29656</value>\n        </rc>\n        <avg_lt value=\"0.00056\">\n            <name>avg_lt</name>\n            <value>0.00056</value>\n        </avg_lt>\n        <throughput value=\"29656\">\n            <name>throughput</name>\n            <value>29656</value>\n        </throughput>\n        <avg_rt value=\"0.00057\">\n            <name>avg_rt</name>\n            <value>0.00057</value>\n        </avg_rt>\n        <perc value=\"0.00000\" param=\"50.0\">\n            <name>perc/50.0</name>\n            <value>0.00000</value>\n        </perc>\n        <perc value=\"0.00100\" param=\"95.0\">\n            <name>perc/95.0</name>\n            <value>0.00100</value>\n        </perc>\n        <perc value=\"0.00300\" param=\"99.0\">\n            <name>perc/99.0</name>\n            <value>0.00300</value>\n        </perc>\n        <perc value=\"0.00000\" param=\"0.0\">\n            <name>perc/0.0</name>\n            <value>0.00000</value>\n        </perc>\n        <perc value=\"0.00800\" param=\"99.9\">\n            <name>perc/99.9</name>\n            <value>0.00800</value>\n        </perc>\n        <perc value=\"0.04000\" param=\"100.0\">\n            <name>perc/100.0</name>\n            <value>0.04000</value>\n        </perc>\n        <perc value=\"0.00100\" param=\"90.0\">\n            <name>perc/90.0</name>\n            <value>0.00100</value>\n        </perc>\n        <stdev_rt value=\"0.03247\">\n            <name>stdev_rt</name>\n            <value>0.03247</value>\n        </stdev_rt>\n        <concurrency value=\"0\">\n            <name>concurrency</name>\n            <value>0</value>\n        </concurrency>\n        <fail value=\"29656\">\n            <name>fail</name>\n            <value>29656</value>\n        </fail>\n        <avg_ct value=\"0.00001\">\n            <name>avg_ct</name>\n            <value>0.00001</value>\n        </avg_ct>\n        <bytes value=\"0\">\n            <name>bytes</name>\n            <value>0</value>\n        </bytes>\n        <succ value=\"0\">\n            <name>succ</name>\n            <value>0</value>\n        </succ>\n    </Group>\n    <Group label=\"http://192.168.100.100/somequery\">\n        <rc value=\"2\" param=\"200\">\n            <name>rc/200</name>\n            <value>2</value>\n        </rc>\n        <rc value=\"29656\" param=\"304\">\n            <name>rc/304</name>\n            <value>29656</value>\n        </rc>\n        <avg_lt value=\"0.00000\">\n            <name>avg_lt</name>\n            <value>0.00000</value>\n        </avg_lt>\n        <throughput value=\"29658\">\n            <name>throughput</name>\n            <value>29658</value>\n        </throughput>\n        <avg_rt value=\"0.00052\">\n            <name>avg_rt</name>\n            <value>0.00052</value>\n        </avg_rt>\n        <perc value=\"0.00000\" param=\"50.0\">\n            <name>perc/50.0</name>\n            <value>0.00000</value>\n        </perc>\n        <perc value=\"0.00100\" param=\"95.0\">\n            <name>perc/95.0</name>\n            <value>0.00100</value>\n        </perc>\n        <perc value=\"0.00400\" param=\"99.0\">\n            <name>perc/99.0</name>\n            <value>0.00400</value>\n        </perc>\n        <perc value=\"0.00000\" param=\"0.0\">\n            <name>perc/0.0</name>\n            <value>0.00000</value>\n        </perc>\n        <perc value=\"0.00900\" param=\"99.9\">\n            <name>perc/99.9</name>\n            <value>0.00900</value>\n        </perc>\n        <perc value=\"0.08100\" param=\"100.0\">\n            <name>perc/100.0</name>\n            <value>0.08100</value>\n        </perc>\n        <perc value=\"0.00100\" param=\"90.0\">\n            <name>perc/90.0</name>\n            <value>0.00100</value>\n        </perc>\n        <stdev_rt value=\"0.04073\">\n            <name>stdev_rt</name>\n            <value>0.04073</value>\n        </stdev_rt>\n        <concurrency value=\"0\">\n            <name>concurrency</name>\n            <value>0</value>\n        </concurrency>\n        <fail value=\"0\">\n            <name>fail</name>\n            <value>0</value>\n        </fail>\n        <avg_ct value=\"0.00001\">\n            <name>avg_ct</name>\n            <value>0.00001</value>\n        </avg_ct>\n        <bytes value=\"0\">\n            <name>bytes</name>\n            <value>0</value>\n        </bytes>\n        <succ value=\"29658\">\n            <name>succ</name>\n            <value>29658</value>\n        </succ>\n    </Group>\n    <Group label=\"http://192.168.1.1/somequery\">\n        <rc value=\"2\" param=\"200\">\n            <name>rc/200</name>\n            <value>2</value>\n        </rc>\n        <rc value=\"29656\" param=\"304\">\n            <name>rc/304</name>\n            <value>29656</value>\n        </rc>\n        <avg_lt value=\"0.00000\">\n            <name>avg_lt</name>\n            <value>0.00000</value>\n        </avg_lt>\n        <throughput value=\"29658\">\n            <name>throughput</name>\n            <value>29658</value>\n        </throughput>\n        <avg_rt value=\"0.00052\">\n            <name>avg_rt</name>\n            <value>0.00052</value>\n        </avg_rt>\n        <perc value=\"0.00000\" param=\"50.0\">\n            <name>perc/50.0</name>\n            <value>0.00000</value>\n        </perc>\n        <perc value=\"0.00100\" param=\"95.0\">\n            <name>perc/95.0</name>\n            <value>0.00100</value>\n        </perc>\n        <perc value=\"0.00400\" param=\"99.0\">\n            <name>perc/99.0</name>\n            <value>0.00400</value>\n        </perc>\n        <perc value=\"0.00000\" param=\"0.0\">\n            <name>perc/0.0</name>\n            <value>0.00000</value>\n        </perc>\n        <perc value=\"0.00900\" param=\"99.9\">\n            <name>perc/99.9</name>\n            <value>0.00900</value>\n        </perc>\n        <perc value=\"0.08100\" param=\"100.0\">\n            <name>perc/100.0</name>\n            <value>0.08100</value>\n        </perc>\n        <perc value=\"0.00100\" param=\"90.0\">\n            <name>perc/90.0</name>\n            <value>0.00100</value>\n        </perc>\n        <stdev_rt value=\"0.04073\">\n            <name>stdev_rt</name>\n            <value>0.04073</value>\n        </stdev_rt>\n        <concurrency value=\"0\">\n            <name>concurrency</name>\n            <value>0</value>\n        </concurrency>\n        <fail value=\"0\">\n            <name>fail</name>\n            <value>0</value>\n        </fail>\n        <avg_ct value=\"0.00001\">\n            <name>avg_ct</name>\n            <value>0.00001</value>\n        </avg_ct>\n        <bytes value=\"0\">\n            <name>bytes</name>\n            <value>0</value>\n        </bytes>\n        <succ value=\"29658\">\n            <name>succ</name>\n            <value>29658</value>\n        </succ>\n    </Group>\n</FinalStatus>"
  },
  {
    "path": "src/test/resources/WrkResultsLong.wrk",
    "content": "Running 5s test @ http://www.google.com\n  8 threads and 16 connections\n  Thread Stats   Avg      Stdev     Max   +/- Stdev\n    Latency    78.27s    31.11s  235.54s    90.05%\n    Req/Sec    25.44      6.03    38.00     69.63%\n  1045 requests in 83.33m, 46.03MB read\nRequests/sec:    205.68\nTransfer/sec:      9.06MB\n"
  },
  {
    "path": "src/test/resources/WrkResultsQuick.wrk",
    "content": "Running 5s test @ http://www.google.com\n  8 threads and 16 connections\n  Thread Stats   Avg      Stdev     Max   +/- Stdev\n    Latency    78.27ms   31.11ms 235.54ms   90.05%\n    Req/Sec    25.44      6.03    38.00     69.63%\n  1045 requests in 5.08s, 46.03MB read\nRequests/sec:    205.68\nTransfer/sec:      9.06MB\n"
  },
  {
    "path": "src/test/resources/WrkResultsWithErrors.wrk",
    "content": "Running 1s test @ http://httpstat.us/500\n  1 threads and 1 connections\n  Thread Stats   Avg      Stdev     Max   +/- Stdev\n    Latency    78.43ms   55.33us  78.48ms   66.67%\n    Req/Sec    11.00      0.00    11.00    100.00%\n  12 requests in 1.03s, 5.66KB read\n  Non-2xx or 3xx responses: 12\nRequests/sec:     11.63\nTransfer/sec:      5.48KB"
  },
  {
    "path": "src/test/resources/WrkResultsWithLatencyFlag.wrk",
    "content": "Running 1s test @ http://www.google.com\n  1 threads and 1 connections\n  Thread Stats   Avg      Stdev     Max   +/- Stdev\n    Latency    42.28ms    3.67ms  46.51ms   66.67%\n    Req/Sec    16.33      7.51    25.00     66.67%\n  Latency Distribution\n     50%   40.25ms\n     75%   46.51ms\n     90%   46.51ms\n     99%   46.51ms\n  18 requests in 1.01s, 852.59KB read\nRequests/sec:     17.81\nTransfer/sec:    843.38KB"
  },
  {
    "path": "src/test/resources/aggregate-results.xml",
    "content": "<?xml version='1.0' encoding='UTF-8'?>\n<FinalStatus>\n  <Group label=\"\">\n    <avg_ct value=\"0\">\n      <name>avg_ct</name>\n      <value>0</value>\n    </avg_ct>\n    <stdev_rt value=\"0.49524\">\n      <name>stdev_rt</name>\n      <value>0.49524</value>\n    </stdev_rt>\n    <avg_lt value=\"0.10052\">\n      <name>avg_lt</name>\n      <value>0.10052</value>\n    </avg_lt>\n    <rc value=\"542\" param=\"200\">\n      <name>rc/200</name>\n      <value>542</value>\n    </rc>\n    <bytes value=\"4961222\">\n      <name>bytes</name>\n      <value>4961222</value>\n    </bytes>\n    <perc value=\"0.13500\" param=\"95.0\">\n      <name>perc/95.0</name>\n      <value>0.13500</value>\n    </perc>\n    <perc value=\"0.05900\" param=\"0.0\">\n      <name>perc/0.0</name>\n      <value>0.05900</value>\n    </perc>\n    <perc value=\"2.61300\" param=\"99.9\">\n      <name>perc/99.9</name>\n      <value>2.61300</value>\n    </perc>\n    <perc value=\"0.10400\" param=\"90.0\">\n      <name>perc/90.0</name>\n      <value>0.10400</value>\n    </perc>\n    <perc value=\"2.61300\" param=\"100.0\">\n      <name>perc/100.0</name>\n      <value>2.61300</value>\n    </perc>\n    <perc value=\"1.68700\" param=\"99.0\">\n      <name>perc/99.0</name>\n      <value>1.68700</value>\n    </perc>\n    <perc value=\"0.07500\" param=\"50.0\">\n      <name>perc/50.0</name>\n      <value>0.07500</value>\n    </perc>\n    <succ value=\"542\">\n      <name>succ</name>\n      <value>542</value>\n    </succ>\n    <throughput value=\"542\">\n      <name>throughput</name>\n      <value>542</value>\n    </throughput>\n    <concurrency value=\"1\">\n      <name>concurrency</name>\n      <value>1</value>\n    </concurrency>\n    <avg_rt value=\"0.10199\">\n      <name>avg_rt</name>\n      <value>0.10199</value>\n    </avg_rt>\n    <fail value=\"0\">\n      <name>fail</name>\n      <value>0</value>\n    </fail>\n  </Group>\n  <Group label=\"http://blazedemo.com/reserve.php\">\n    <avg_ct value=\"0\">\n      <name>avg_ct</name>\n      <value>0</value>\n    </avg_ct>\n    <stdev_rt value=\"0.43798\">\n      <name>stdev_rt</name>\n      <value>0.43798</value>\n    </stdev_rt>\n    <avg_lt value=\"0.10385\">\n      <name>avg_lt</name>\n      <value>0.10385</value>\n    </avg_lt>\n    <rc value=\"271\" param=\"200\">\n      <name>rc/200</name>\n      <value>271</value>\n    </rc>\n    <bytes value=\"2821801\">\n      <name>bytes</name>\n      <value>2821801</value>\n    </bytes>\n    <perc value=\"0.11300\" param=\"95.0\">\n      <name>perc/95.0</name>\n      <value>0.11300</value>\n    </perc>\n    <perc value=\"0.05900\" param=\"0.0\">\n      <name>perc/0.0</name>\n      <value>0.05900</value>\n    </perc>\n    <perc value=\"1.74800\" param=\"99.9\">\n      <name>perc/99.9</name>\n      <value>1.74800</value>\n    </perc>\n    <perc value=\"0.10000\" param=\"90.0\">\n      <name>perc/90.0</name>\n      <value>0.10000</value>\n    </perc>\n    <perc value=\"1.74800\" param=\"100.0\">\n      <name>perc/100.0</name>\n      <value>1.74800</value>\n    </perc>\n    <perc value=\"1.71400\" param=\"99.0\">\n      <name>perc/99.0</name>\n      <value>1.71400</value>\n    </perc>\n    <perc value=\"0.07400\" param=\"50.0\">\n      <name>perc/50.0</name>\n      <value>0.07400</value>\n    </perc>\n    <succ value=\"271\">\n      <name>succ</name>\n      <value>271</value>\n    </succ>\n    <throughput value=\"271\">\n      <name>throughput</name>\n      <value>271</value>\n    </throughput>\n    <concurrency value=\"1\">\n      <name>concurrency</name>\n      <value>1</value>\n    </concurrency>\n    <avg_rt value=\"0.10631\">\n      <name>avg_rt</name>\n      <value>0.10631</value>\n    </avg_rt>\n    <fail value=\"0\">\n      <name>fail</name>\n      <value>0</value>\n    </fail>\n  </Group>\n  <Group label=\"http://blazedemo.com/\">\n    <avg_ct value=\"0\">\n      <name>avg_ct</name>\n      <value>0</value>\n    </avg_ct>\n    <stdev_rt value=\"0.36502\">\n      <name>stdev_rt</name>\n      <value>0.36502</value>\n    </stdev_rt>\n    <avg_lt value=\"0.09720\">\n      <name>avg_lt</name>\n      <value>0.09720</value>\n    </avg_lt>\n    <rc value=\"271\" param=\"200\">\n      <name>rc/200</name>\n      <value>271</value>\n    </rc>\n    <bytes value=\"2139421\">\n      <name>bytes</name>\n      <value>2139421</value>\n    </bytes>\n    <perc value=\"0.14100\" param=\"95.0\">\n      <name>perc/95.0</name>\n      <value>0.14100</value>\n    </perc>\n    <perc value=\"0.05900\" param=\"0.0\">\n      <name>perc/0.0</name>\n      <value>0.05900</value>\n    </perc>\n    <perc value=\"2.61300\" param=\"99.9\">\n      <name>perc/99.9</name>\n      <value>2.61300</value>\n    </perc>\n    <perc value=\"0.11300\" param=\"90.0\">\n      <name>perc/90.0</name>\n      <value>0.11300</value>\n    </perc>\n    <perc value=\"2.61300\" param=\"100.0\">\n      <name>perc/100.0</name>\n      <value>2.61300</value>\n    </perc>\n    <perc value=\"0.54600\" param=\"99.0\">\n      <name>perc/99.0</name>\n      <value>0.54600</value>\n    </perc>\n    <perc value=\"0.07500\" param=\"50.0\">\n      <name>perc/50.0</name>\n      <value>0.07500</value>\n    </perc>\n    <succ value=\"271\">\n      <name>succ</name>\n      <value>271</value>\n    </succ>\n    <throughput value=\"271\">\n      <name>throughput</name>\n      <value>271</value>\n    </throughput>\n    <concurrency value=\"12\">\n      <name>concurrency</name>\n      <value>12</value>\n    </concurrency>\n    <avg_rt value=\"0.09767\">\n      <name>avg_rt</name>\n      <value>0.09767</value>\n    </avg_rt>\n    <fail value=\"0\">\n      <name>fail</name>\n      <value>0</value>\n    </fail>\n  </Group>\n</FinalStatus>\n"
  },
  {
    "path": "src/test/resources/constraint-test.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<testResults version=\"1.2\">\n<httpSample t=\"142\" lt=\"142\" ts=\"1448547841517\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"147\" lt=\"147\" ts=\"1448547841517\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"147\" lt=\"147\" ts=\"1448547841516\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"81\" lt=\"81\" ts=\"1448547841586\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"144\" lt=\"144\" ts=\"1448547841517\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"148\" lt=\"148\" ts=\"1448547841518\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"144\" lt=\"144\" ts=\"1448547841517\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"81\" lt=\"81\" ts=\"1448547841586\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"150\" lt=\"146\" ts=\"1448547841517\" s=\"true\" lb=\"listEvents\" rc=\"200\" rm=\"OK\" tn=\"Events 3-2\" dt=\"text\" by=\"10110\"/>\n<httpSample t=\"151\" lt=\"147\" ts=\"1448547841517\" s=\"true\" lb=\"listEvents\" rc=\"200\" rm=\"OK\" tn=\"Events 3-1\" dt=\"text\" by=\"10110\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547841671\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547841672\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"69\" lt=\"69\" ts=\"1448547841671\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"70\" lt=\"70\" ts=\"1448547841671\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"75\" lt=\"74\" ts=\"1448547841673\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"76\" lt=\"76\" ts=\"1448547841672\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"78\" lt=\"78\" ts=\"1448547841671\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"77\" lt=\"77\" ts=\"1448547841672\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"87\" lt=\"86\" ts=\"1448547841674\" s=\"true\" lb=\"listEvents\" rc=\"200\" rm=\"OK\" tn=\"Events 3-2\" dt=\"text\" by=\"10110\"/>\n<httpSample t=\"87\" lt=\"85\" ts=\"1448547841675\" s=\"true\" lb=\"listEvents\" rc=\"200\" rm=\"OK\" tn=\"Events 3-1\" dt=\"text\" by=\"10110\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547841738\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"61\" lt=\"59\" ts=\"1448547841739\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"61\" lt=\"60\" ts=\"1448547841740\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"59\" lt=\"59\" ts=\"1448547841742\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"75\" lt=\"75\" ts=\"1448547841749\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"74\" lt=\"74\" ts=\"1448547841750\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"75\" lt=\"75\" ts=\"1448547841749\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"76\" lt=\"76\" ts=\"1448547841749\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"77\" lt=\"76\" ts=\"1448547841763\" s=\"true\" lb=\"listEvents\" rc=\"200\" rm=\"OK\" tn=\"Events 3-1\" dt=\"text\" by=\"10110\"/>\n<httpSample t=\"81\" lt=\"78\" ts=\"1448547841761\" s=\"true\" lb=\"listEvents\" rc=\"200\" rm=\"OK\" tn=\"Events 3-2\" dt=\"text\" by=\"10110\"/>\n<httpSample t=\"58\" lt=\"58\" ts=\"1448547841786\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547841786\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"58\" lt=\"58\" ts=\"1448547841795\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547841801\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"59\" lt=\"59\" ts=\"1448547841801\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"59\" lt=\"59\" ts=\"1448547841802\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547841825\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547841825\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547841825\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547841825\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547841844\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547841854\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"74\" lt=\"73\" ts=\"1448547841841\" s=\"true\" lb=\"listEvents\" rc=\"200\" rm=\"OK\" tn=\"Events 3-1\" dt=\"text\" by=\"10110\"/>\n<httpSample t=\"58\" lt=\"58\" ts=\"1448547841859\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"76\" lt=\"72\" ts=\"1448547841842\" s=\"true\" lb=\"listEvents\" rc=\"200\" rm=\"OK\" tn=\"Events 3-2\" dt=\"text\" by=\"10110\"/>\n<httpSample t=\"60\" lt=\"60\" ts=\"1448547841860\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"60\" lt=\"60\" ts=\"1448547841861\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547841854\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547841901\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547841893\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547841893\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547841893\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547841893\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547841909\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547841917\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547841921\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547841922\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547841922\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"75\" lt=\"73\" ts=\"1448547841916\" s=\"true\" lb=\"listEvents\" rc=\"200\" rm=\"OK\" tn=\"Events 3-1\" dt=\"text\" by=\"10110\"/>\n<httpSample t=\"73\" lt=\"72\" ts=\"1448547841919\" s=\"true\" lb=\"listEvents\" rc=\"200\" rm=\"OK\" tn=\"Events 3-2\" dt=\"text\" by=\"10110\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547841957\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547841967\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547841961\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"69\" lt=\"69\" ts=\"1448547841962\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547841974\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"70\" lt=\"67\" ts=\"1448547841962\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"70\" lt=\"70\" ts=\"1448547841962\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"58\" lt=\"58\" ts=\"1448547841977\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"58\" lt=\"58\" ts=\"1448547841978\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547841989\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547842012\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547842024\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547842032\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547842036\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"58\" lt=\"58\" ts=\"1448547842037\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842029\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"69\" lt=\"69\" ts=\"1448547842031\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842033\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547842033\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842057\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547842068\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547842081\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547842088\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547842093\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547842096\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842096\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842101\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547842101\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547842101\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547842125\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547842125\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547842137\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547842144\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547842149\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547842152\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842163\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547842181\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842169\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842169\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547842169\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547842193\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547842200\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547842204\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"66\" ts=\"1448547842193\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547842207\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547842237\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842230\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547842248\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842237\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842237\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842237\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547842255\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547842259\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547842263\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842260\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547842292\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547842303\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842297\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547842311\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"69\" lt=\"67\" ts=\"1448547842304\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"66\" ts=\"1448547842305\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"69\" lt=\"67\" ts=\"1448547842304\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"58\" lt=\"58\" ts=\"1448547842315\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547842320\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842327\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547842347\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547842358\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547842367\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547842373\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842364\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547842377\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"72\" lt=\"72\" ts=\"1448547842373\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"74\" lt=\"74\" ts=\"1448547842373\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"75\" lt=\"75\" ts=\"1448547842373\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"78\" lt=\"78\" ts=\"1448547842394\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"72\" lt=\"72\" ts=\"1448547842402\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"71\" lt=\"71\" ts=\"1448547842413\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547842422\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"65\" lt=\"65\" ts=\"1448547842428\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"61\" lt=\"61\" ts=\"1448547842433\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842432\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"70\" lt=\"70\" ts=\"1448547842446\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"71\" lt=\"70\" ts=\"1448547842448\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"71\" lt=\"71\" ts=\"1448547842448\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547842474\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547842472\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"58\" lt=\"58\" ts=\"1448547842485\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"61\" lt=\"61\" ts=\"1448547842491\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"59\" lt=\"59\" ts=\"1448547842494\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"61\" lt=\"61\" ts=\"1448547842494\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547842499\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"69\" lt=\"69\" ts=\"1448547842516\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"58\" lt=\"58\" ts=\"1448547842530\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"69\" lt=\"69\" ts=\"1448547842519\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"69\" lt=\"69\" ts=\"1448547842519\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"58\" lt=\"58\" ts=\"1448547842544\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547842540\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547842553\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547842554\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547842555\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547842567\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547842589\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"69\" lt=\"69\" ts=\"1448547842586\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842589\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"69\" lt=\"69\" ts=\"1448547842589\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"58\" lt=\"58\" ts=\"1448547842602\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547842610\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"58\" lt=\"58\" ts=\"1448547842611\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"59\" lt=\"59\" ts=\"1448547842612\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842608\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"69\" lt=\"69\" ts=\"1448547842635\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"61\" lt=\"61\" ts=\"1448547842645\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547842660\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842657\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547842671\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"60\" lt=\"60\" ts=\"1448547842669\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"75\" lt=\"75\" ts=\"1448547842655\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"73\" lt=\"69\" ts=\"1448547842658\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"63\" lt=\"63\" ts=\"1448547842668\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547842676\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547842706\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842704\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"60\" lt=\"60\" ts=\"1448547842718\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547842725\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"64\" lt=\"64\" ts=\"1448547842729\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"65\" lt=\"65\" ts=\"1448547842730\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"64\" lt=\"64\" ts=\"1448547842732\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547842731\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"69\" lt=\"69\" ts=\"1448547842731\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842744\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547842762\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547842778\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842772\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"58\" lt=\"58\" ts=\"1448547842794\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"58\" lt=\"58\" ts=\"1448547842795\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"59\" lt=\"59\" ts=\"1448547842796\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"66\" ts=\"1448547842794\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"73\" lt=\"73\" ts=\"1448547842800\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"73\" lt=\"73\" ts=\"1448547842800\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547842818\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842811\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547842835\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842839\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"58\" lt=\"58\" ts=\"1448547842852\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"58\" lt=\"58\" ts=\"1448547842853\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547842855\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842861\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547842875\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842874\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842874\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842878\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547842891\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547842910\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547842911\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"59\" lt=\"59\" ts=\"1448547842912\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842906\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547842931\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842928\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"60\" lt=\"60\" ts=\"1448547842947\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"66\" lt=\"66\" ts=\"1448547842942\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842942\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"66\" ts=\"1448547842945\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"59\" lt=\"59\" ts=\"1448547842968\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"59\" lt=\"59\" ts=\"1448547842969\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"58\" lt=\"58\" ts=\"1448547842971\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547842974\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547842988\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547842995\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547843007\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"66\" lt=\"66\" ts=\"1448547843009\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843009\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843012\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"61\" lt=\"61\" ts=\"1448547843027\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"61\" lt=\"61\" ts=\"1448547843028\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"61\" lt=\"61\" ts=\"1448547843029\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547843045\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"66\" lt=\"66\" ts=\"1448547843042\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"58\" lt=\"58\" ts=\"1448547843063\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843063\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547843088\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547843076\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"70\" lt=\"70\" ts=\"1448547843076\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547843089\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547843091\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547843079\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547843101\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843108\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547843122\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843130\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547843144\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547843146\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"55\" ts=\"1448547843147\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843144\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547843158\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843147\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547843146\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547843178\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843176\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547843202\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547843203\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547843204\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"69\" lt=\"69\" ts=\"1448547843197\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547843214\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843211\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843215\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547843215\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547843234\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843243\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"58\" lt=\"57\" ts=\"1448547843258\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"58\" lt=\"58\" ts=\"1448547843259\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"58\" lt=\"58\" ts=\"1448547843260\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547843270\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843266\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547843290\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843278\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547843283\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547843283\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547843316\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547843317\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547843318\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547843310\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547843325\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547843344\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843333\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843345\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547843351\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547843351\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547843372\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547843374\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547843373\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547843380\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843378\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547843400\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843400\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843412\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547843427\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547843429\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547843430\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843419\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843419\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547843436\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547843455\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"69\" lt=\"69\" ts=\"1448547843445\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843467\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"60\" lt=\"59\" ts=\"1448547843483\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"59\" lt=\"59\" ts=\"1448547843485\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"59\" lt=\"59\" ts=\"1448547843486\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"55\" ts=\"1448547843491\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"66\" ts=\"1448547843479\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843486\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843486\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547843512\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843514\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547843543\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"58\" lt=\"58\" ts=\"1448547843544\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547843535\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547843546\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547843547\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843547\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843554\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843554\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547843569\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843581\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547843599\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547843602\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547843604\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"59\" lt=\"59\" ts=\"1448547843603\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843603\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547843624\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843614\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547843621\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547843621\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547843656\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843648\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"57\" lt=\"56\" ts=\"1448547843660\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547843661\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547843662\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547843680\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843671\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843681\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547843689\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547843689\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547843712\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547843718\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"59\" lt=\"59\" ts=\"1448547843717\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"58\" lt=\"58\" ts=\"1448547843719\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843715\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"55\" ts=\"1448547843736\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843738\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843748\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547843768\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843757\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843757\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547843775\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547843776\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547843777\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547843792\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843783\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843805\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547843824\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843815\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"57\" lt=\"56\" ts=\"1448547843832\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"58\" lt=\"58\" ts=\"1448547843831\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"58\" lt=\"58\" ts=\"1448547843833\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843824\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843825\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547843847\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547843851\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547843879\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"66\" lt=\"66\" ts=\"1448547843873\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547843889\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547843890\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547843891\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843882\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547843903\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843891\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843892\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843919\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547843935\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547843944\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547843945\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547843947\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843939\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547843959\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547843949\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547843959\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547843959\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547843990\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547843986\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547844000\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844002\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844003\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"66\" lt=\"66\" ts=\"1448547844007\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844017\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547844017\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547844027\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547844027\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844045\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844057\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844058\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844059\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844053\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547844074\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"66\" lt=\"66\" ts=\"1448547844074\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844085\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844101\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844095\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844095\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844113\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844114\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844115\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844128\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844120\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844140\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844156\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844153\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547844170\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844170\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547844172\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"66\" lt=\"66\" ts=\"1448547844163\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844162\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844183\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844187\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844211\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844207\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844224\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844225\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844226\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844220\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844238\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844229\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844229\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"85\" lt=\"85\" ts=\"1448547844254\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"74\" lt=\"74\" ts=\"1448547844267\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"63\" lt=\"63\" ts=\"1448547844280\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"62\" lt=\"62\" ts=\"1448547844281\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"66\" lt=\"65\" ts=\"1448547844281\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"73\" lt=\"73\" ts=\"1448547844274\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844293\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844287\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547844296\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547844296\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547844341\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844344\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844344\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844347\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844349\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844339\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844347\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844354\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844364\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844364\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844398\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844399\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844401\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844404\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844405\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547844406\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844414\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844421\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"66\" lt=\"66\" ts=\"1448547844432\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"66\" lt=\"66\" ts=\"1448547844432\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844454\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844455\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844456\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844459\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844461\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844474\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547844482\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"66\" ts=\"1448547844488\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844509\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844510\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844499\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844511\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547844499\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844515\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844516\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844541\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547844551\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547844564\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547844566\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547844567\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"69\" lt=\"69\" ts=\"1448547844555\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844572\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844572\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547844567\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547844567\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547844622\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547844608\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844623\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"55\" ts=\"1448547844624\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844627\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844628\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844619\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844624\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547844635\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547844635\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844676\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"58\" lt=\"58\" ts=\"1448547844678\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547844680\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844683\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844684\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844676\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844686\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844691\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844703\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547844703\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844731\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844736\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844737\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844739\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844740\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844743\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844753\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"69\" lt=\"69\" ts=\"1448547844758\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"69\" lt=\"69\" ts=\"1448547844771\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"69\" lt=\"69\" ts=\"1448547844771\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547844786\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844791\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547844793\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547844794\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547844796\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"66\" lt=\"66\" ts=\"1448547844811\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844821\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"66\" ts=\"1448547844827\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547844844\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547844847\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844848\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844852\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547844840\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547844840\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844853\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844877\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844898\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844888\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844901\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844903\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844894\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844908\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844909\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844908\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844908\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547844954\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"66\" lt=\"66\" ts=\"1448547844945\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547844957\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844959\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547844965\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547844966\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"66\" lt=\"66\" ts=\"1448547844956\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844961\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"66\" lt=\"66\" ts=\"1448547844976\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547844976\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547845009\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547845013\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"55\" ts=\"1448547845014\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845019\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845021\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845011\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845022\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845028\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845043\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845043\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547845064\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845069\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547845070\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845075\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845076\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845078\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845089\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845095\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845118\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"66\" lt=\"66\" ts=\"1448547845111\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"66\" ts=\"1448547845111\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547845125\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547845126\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547845130\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547845131\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"70\" lt=\"70\" ts=\"1448547845146\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845156\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845162\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845174\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845181\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845182\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845186\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845187\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845177\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"66\" ts=\"1448547845178\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845217\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845229\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845223\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547845236\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547845237\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845242\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547845229\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547845242\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845244\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"66\" ts=\"1448547845245\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845284\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845292\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845293\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845284\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547845297\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547845298\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845291\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"66\" ts=\"1448547845297\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845311\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845312\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547845340\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547845347\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547845348\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845353\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845354\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845351\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845358\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"66\" ts=\"1448547845364\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845378\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"66\" ts=\"1448547845379\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845394\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845403\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845404\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845408\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845409\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845418\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845425\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845431\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845449\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845445\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845459\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547845446\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547845459\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547845463\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547845464\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845485\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845492\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845504\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845498\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845514\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845515\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845519\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845520\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845512\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845514\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845559\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845552\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845569\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547845570\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845559\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845575\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845576\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845565\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845579\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845581\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845614\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547845625\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845626\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845630\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845631\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845619\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845626\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845632\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845646\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845648\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845669\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845679\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845681\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845685\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845686\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845686\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845693\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845699\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845725\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845713\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845715\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845734\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547845736\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845740\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845741\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"66\" lt=\"66\" ts=\"1448547845754\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845760\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"66\" ts=\"1448547845766\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845780\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845789\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845790\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845780\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845782\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845795\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845796\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845820\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845835\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845827\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845844\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845845\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845833\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845850\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845851\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845847\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845849\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845890\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845899\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845900\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547845887\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547845905\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845906\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"66\" ts=\"1448547845894\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845900\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845914\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845916\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845945\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845954\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845955\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547845961\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547845962\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845955\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"66\" lt=\"66\" ts=\"1448547845962\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845967\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845981\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547845983\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846000\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"55\" ts=\"1448547846009\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547846010\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846018\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547846017\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846022\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846028\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846034\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846055\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846048\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846050\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846065\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846066\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547846073\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846074\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846089\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846095\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846110\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846101\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"54\" ts=\"1448547846121\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547846122\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846115\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547846129\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846129\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846117\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846165\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846156\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846162\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846176\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547846177\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846168\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547846184\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547846185\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846182\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"66\" lt=\"66\" ts=\"1448547846185\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846220\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547846232\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547846233\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846223\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547846239\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547846240\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846229\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846235\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846249\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846251\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846275\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547846287\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846287\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547846294\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846294\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846290\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846296\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846302\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846316\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846330\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846318\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846341\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846342\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846348\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846349\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846357\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846363\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547846369\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"54\" ts=\"1448547846386\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846383\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846396\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846397\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"66\" lt=\"66\" ts=\"1448547846386\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547846404\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846404\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846424\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846441\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846430\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846437\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547846452\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547846453\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547846459\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547846460\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846450\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"66\" lt=\"65\" ts=\"1448547846453\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846496\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846491\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547846506\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"55\" ts=\"1448547846507\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846497\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846513\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846514\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846504\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846517\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"66\" lt=\"66\" ts=\"1448547846519\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547846553\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846563\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846564\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846569\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846570\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547846559\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846565\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846572\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846585\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"66\" ts=\"1448547846586\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846607\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547846619\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"55\" ts=\"1448547846619\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547846624\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846626\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"66\" lt=\"66\" ts=\"1448547846627\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846632\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846639\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846662\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846653\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547846652\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846674\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846675\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846681\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547846680\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846693\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846699\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846717\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846706\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846729\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846730\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846720\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846720\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846737\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547846736\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547846772\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547846760\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846766\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846784\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846785\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846773\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846792\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846793\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"66\" lt=\"66\" ts=\"1448547846788\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846787\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846828\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547846840\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"66\" ts=\"1448547846828\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547846841\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846833\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547846848\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846848\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"66\" lt=\"66\" ts=\"1448547846841\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846855\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"66\" ts=\"1448547846855\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846883\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846894\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846895\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846902\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846903\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846895\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846900\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846907\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846922\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547846922\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547846938\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547846949\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"55\" ts=\"1448547846950\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846957\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547846958\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846962\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846967\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"66\" ts=\"1448547846974\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547846994\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846990\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547846990\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547847006\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"57\" lt=\"57\" ts=\"1448547847005\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547847012\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547847013\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847029\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847034\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547847049\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847041\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547847061\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547847062\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547847067\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547847068\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847057\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847057\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547847103\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847096\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847101\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547847116\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"55\" ts=\"1448547847117\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"70\" lt=\"70\" ts=\"1448547847108\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547847123\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"56\" lt=\"56\" ts=\"1448547847124\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547847124\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547847124\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547847158\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547847172\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547847173\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847163\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547847180\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-3\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547847181\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847168\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"66\" lt=\"66\" ts=\"1448547847179\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547847192\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547847192\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547847213\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-1\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547847228\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-4\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"54\" lt=\"54\" ts=\"1448547847229\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-2\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547847235\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847230\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847235\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847245\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547847260\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547847260\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547847290\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847297\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"66\" ts=\"1448547847302\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847312\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547847328\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547847328\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"55\" lt=\"55\" ts=\"1448547847345\" s=\"true\" lb=\"listShows\" rc=\"200\" rm=\"OK\" tn=\"Shows 1-5\" dt=\"text\" by=\"7163\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847364\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847369\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847379\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547847396\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547847396\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847431\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847436\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847446\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847464\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547847464\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847498\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847503\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847513\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"66\" ts=\"1448547847532\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847532\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847565\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847570\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847580\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547847599\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547847599\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847632\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847637\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847647\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847667\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"68\" ts=\"1448547847667\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847699\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847704\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847714\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"66\" lt=\"66\" ts=\"1448547847735\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847735\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"66\" lt=\"66\" ts=\"1448547847767\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847771\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847781\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847801\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847802\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847833\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847838\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847848\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847868\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847869\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847900\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847905\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847915\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847935\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847936\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847967\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847972\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547847982\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547848002\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"66\" ts=\"1448547848003\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547848034\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547848039\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547848049\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547848069\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547848070\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547848101\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"68\" lt=\"67\" ts=\"1448547848106\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547848116\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547848136\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547848137\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547848168\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547848174\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547848183\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547848203\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547848204\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547848235\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547848241\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547848250\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547848270\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547848271\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547848302\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-2\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547848308\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-1\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547848317\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-3\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547848337\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-4\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"66\" ts=\"1448547848338\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"67\" ts=\"1448547848405\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n<httpSample t=\"67\" lt=\"66\" ts=\"1448547848473\" s=\"true\" lb=\"listBookings\" rc=\"200\" rm=\"OK\" tn=\"Bookings 2-5\" dt=\"text\" by=\"155\"/>\n\n</testResults>\n"
  },
  {
    "path": "src/test/resources/emptyfile.jtl",
    "content": ""
  },
  {
    "path": "src/test/resources/filewithtransactions.csv",
    "content": "timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,failureMessage,bytes,sentBytes,grpThreads,allThreads,URL,Latency,IdleTime,Connect\n1547676357242,1172,HP-0,200,OK,Thread Group 1-1,text,true,,13630,390,1,1,https://www.foo.com/blog/,1170,0,704\n1547676358416,772,HP-1,200,OK,Thread Group 1-1,text,true,,1592,464,1,1,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,772,0,0\n1547676359192,980,HP-2,200,OK,Thread Group 1-1,text,true,,13768,396,1,1,https://www.foo.com/blog/page/2/,979,0,0\n1547676357183,2924,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-1,,true,,28990,1250,1,1,null,2921,67,704\n1547676363185,722,HP-0,200,OK,Thread Group 1-2,text,true,,13629,390,2,2,https://www.foo.com/blog/,721,0,94\n1547676363907,199,HP-1,200,OK,Thread Group 1-2,text,true,,1592,464,2,2,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,199,0,0\n1547676364107,392,HP-2,200,OK,Thread Group 1-2,text,true,,13769,396,2,2,https://www.foo.com/blog/page/2/,390,0,0\n1547676363184,1313,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-2,,true,,28990,1250,2,2,null,1310,2,94\n1547676365268,804,Search-0,200,OK,Thread Group 1-1,text,true,,13656,409,2,2,https://www.foo.com/?s=streaming,802,0,120\n1547676366072,587,Search-1,200,OK,Thread Group 1-1,text,true,,1511,473,2,2,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,587,0,0\n1547676366660,591,Search-2,200,OK,Thread Group 1-1,text,true,,13475,415,2,2,https://www.foo.com/search/streaming/page/2/,590,0,0\n1547676365267,1982,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-1,,true,,28642,1297,2,2,null,1979,3,120\n1547676369189,452,HP-0,200,OK,Thread Group 1-3,text,true,,13630,390,3,3,https://www.foo.com/blog/,451,0,81\n1547676369642,364,HP-1,200,OK,Thread Group 1-3,text,true,,1592,464,3,3,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,363,0,0\n1547676369535,862,Search-0,200,OK,Thread Group 1-2,text,true,,13658,409,3,3,https://www.foo.com/?s=streaming,861,0,86\n1547676370398,391,Search-1,200,OK,Thread Group 1-2,text,true,,1511,473,3,3,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,391,0,0\n1547676370006,784,HP-2,200,OK,Thread Group 1-3,text,true,,13768,396,3,3,https://www.foo.com/blog/page/2/,783,0,0\n1547676369188,1600,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-3,,true,,28990,1250,3,3,null,1597,2,81\n1547676370790,590,Search-2,200,OK,Thread Group 1-2,text,true,,13476,415,3,3,https://www.foo.com/search/streaming/page/2/,589,0,0\n1547676369535,1843,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-2,,true,,28645,1297,3,3,null,1841,2,86\n1547676357183,4906,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-1,,true,,57632,2547,2,2,null,4900,10242,824\n1547676372334,455,HP-0,200,OK,Thread Group 1-1,text,true,,13628,390,3,3,https://www.foo.com/blog/,454,0,82\n1547676372790,193,HP-1,200,OK,Thread Group 1-1,text,true,,1592,464,3,3,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,193,0,0\n1547676372984,365,HP-2,200,OK,Thread Group 1-1,text,true,,13769,396,3,3,https://www.foo.com/blog/page/2/,364,0,0\n1547676372332,1013,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-1,,true,,28989,1250,3,3,null,1011,4,82\n1547676375183,523,HP-0,200,OK,Thread Group 1-4,text,true,,13628,390,4,4,https://www.foo.com/blog/,521,0,81\n1547676375707,191,HP-1,200,OK,Thread Group 1-4,text,true,,1592,464,4,4,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,191,0,0\n1547676363184,3156,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-2,,true,,57635,2547,3,3,null,3151,10094,180\n1547676375898,704,HP-2,200,OK,Thread Group 1-4,text,true,,13769,396,4,4,https://www.foo.com/blog/page/2/,703,0,0\n1547676375182,1418,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-4,,true,,28989,1250,4,4,null,1415,3,81\n1547676375860,881,Search-0,200,OK,Thread Group 1-3,text,true,,13657,409,4,4,https://www.foo.com/?s=streaming,880,0,78\n1547676376742,534,Search-1,200,OK,Thread Group 1-3,text,true,,1511,473,4,4,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,534,0,0\n1547676376434,843,HP-0,200,OK,Thread Group 1-2,text,true,,13627,390,4,4,https://www.foo.com/blog/,842,0,78\n1547676377278,390,HP-1,200,OK,Thread Group 1-2,text,true,,1592,464,4,4,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,390,0,0\n1547676377277,705,Search-2,200,OK,Thread Group 1-3,text,true,,13477,415,4,4,https://www.foo.com/search/streaming/page/2/,704,0,0\n1547676375859,2120,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-3,,true,,28645,1297,4,4,null,2118,4,78\n1547676377669,507,HP-2,200,OK,Thread Group 1-2,text,true,,13768,396,4,4,https://www.foo.com/blog/page/2/,506,0,0\n1547676376433,1740,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-2,,true,,28987,1250,4,4,null,1738,4,78\n1547676378424,480,Search-0,200,OK,Thread Group 1-1,text,true,,13655,409,4,4,https://www.foo.com/?s=streaming,479,0,79\n1547676378905,190,Search-1,200,OK,Thread Group 1-1,text,true,,1511,473,4,4,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,190,0,0\n1547676379096,541,Search-2,200,OK,Thread Group 1-1,text,true,,13476,415,4,4,https://www.foo.com/search/streaming/page/2/,540,0,0\n1547676378424,1211,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-1,,true,,28642,1297,4,4,null,1209,2,79\n1547676381185,456,HP-0,200,OK,Thread Group 1-5,text,true,,13630,390,5,5,https://www.foo.com/blog/,454,0,84\n1547676381641,307,HP-1,200,OK,Thread Group 1-5,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,307,0,0\n1547676381631,954,Search-0,200,OK,Thread Group 1-4,text,true,,13657,409,5,5,https://www.foo.com/?s=streaming,953,0,76\n1547676381949,833,HP-2,200,OK,Thread Group 1-5,text,true,,13770,396,5,5,https://www.foo.com/blog/page/2/,833,0,0\n1547676381184,1596,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-5,,true,,28992,1250,5,5,null,1594,4,84\n1547676369187,3720,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-3,,true,,57635,2547,4,4,null,3715,10103,159\n1547676382586,432,Search-1,200,OK,Thread Group 1-4,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,432,0,0\n1547676383019,942,Search-2,200,OK,Thread Group 1-4,text,true,,13477,415,5,5,https://www.foo.com/search/streaming/page/2/,942,0,0\n1547676381630,2328,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-4,,true,,28645,1297,5,5,null,2327,4,76\n1547676383009,977,HP-0,200,OK,Thread Group 1-3,text,true,,13627,390,5,5,https://www.foo.com/blog/,976,0,79\n1547676383986,369,HP-1,200,OK,Thread Group 1-3,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,369,0,0\n1547676383281,1075,Search-0,200,OK,Thread Group 1-2,text,true,,13657,409,5,5,https://www.foo.com/?s=streaming,1074,0,79\n1547676372332,2224,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-1,,true,,57631,2547,4,4,null,2220,10128,161\n1547676384357,353,Search-1,200,OK,Thread Group 1-2,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,353,0,0\n1547676384356,1624,HP-2,200,OK,Thread Group 1-3,text,true,,13771,396,5,5,https://www.foo.com/blog/page/2/,1623,0,0\n1547676383008,2970,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-3,,true,,28990,1250,5,5,null,2968,2,79\n1547676384710,1287,Search-2,200,OK,Thread Group 1-2,text,true,,13477,415,5,5,https://www.foo.com/search/streaming/page/2/,1287,0,0\n1547676383280,2715,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-2,,true,,28645,1297,5,5,null,2714,2,79\n1547676384684,1378,HP-0,200,OK,Thread Group 1-1,text,true,,13632,390,5,5,https://www.foo.com/blog/,1377,0,84\n1547676386063,199,HP-1,200,OK,Thread Group 1-1,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,199,0,0\n1547676386263,451,HP-2,200,OK,Thread Group 1-1,text,true,,13769,396,5,5,https://www.foo.com/blog/page/2/,451,0,0\n1547676384683,2028,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-1,,true,,28993,1250,5,5,null,2027,3,84\n1547676387795,689,Search-0,200,OK,Thread Group 1-5,text,true,,13656,409,5,5,https://www.foo.com/?s=streaming,688,0,80\n1547676388484,192,Search-1,200,OK,Thread Group 1-5,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,191,0,0\n1547676375182,3746,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-4,,true,,57634,2547,5,5,null,3742,10090,157\n1547676388676,382,Search-2,200,OK,Thread Group 1-5,text,true,,13477,415,5,5,https://www.foo.com/search/streaming/page/2/,382,0,0\n1547676387794,1263,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-5,,true,,28644,1297,5,5,null,1261,2,80\n1547676389019,650,HP-0,200,OK,Thread Group 1-4,text,true,,13626,390,5,5,https://www.foo.com/blog/,649,0,79\n1547676389669,191,HP-1,200,OK,Thread Group 1-4,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,191,0,0\n1547676389861,392,HP-2,200,OK,Thread Group 1-4,text,true,,13768,396,5,5,https://www.foo.com/blog/page/2/,391,0,0\n1547676389018,1233,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-4,,true,,28986,1250,5,5,null,1231,3,79\n1547676376433,4455,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-2,,true,,57632,2547,5,5,null,4452,10177,157\n1547676391066,798,HP-0,200,OK,Thread Group 1-2,text,true,,13628,390,5,5,https://www.foo.com/blog/,797,0,85\n1547676391075,875,Search-0,200,OK,Thread Group 1-3,text,true,,13657,409,5,5,https://www.foo.com/?s=streaming,874,0,76\n1547676391863,551,HP-1,200,OK,Thread Group 1-2,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,551,0,0\n1547676391949,503,Search-1,200,OK,Thread Group 1-3,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,503,0,0\n1547676391758,1247,Search-0,200,OK,Thread Group 1-1,text,true,,13659,409,5,5,https://www.foo.com/?s=streaming,1246,0,80\n1547676392415,1179,HP-2,200,OK,Thread Group 1-2,text,true,,13768,396,5,5,https://www.foo.com/blog/page/2/,1179,0,0\n1547676392452,1142,Search-2,200,OK,Thread Group 1-3,text,true,,13474,415,5,5,https://www.foo.com/search/streaming/page/2/,1142,0,0\n1547676391075,2520,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-3,,true,,28642,1297,5,5,null,2519,1,76\n1547676391065,2528,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-2,,true,,28988,1250,5,5,null,2527,3,85\n1547676381184,2859,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-5,,true,,57636,2547,5,5,null,2855,10070,164\n1547676393006,1499,Search-1,200,OK,Thread Group 1-1,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,1499,0,0\n1547676394113,540,HP-0,200,OK,Thread Group 1-5,text,true,,13630,390,5,5,https://www.foo.com/blog/,539,0,78\n1547676394653,514,HP-1,200,OK,Thread Group 1-5,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,514,0,0\n1547676394505,677,Search-2,200,OK,Thread Group 1-1,text,true,,13478,415,5,5,https://www.foo.com/search/streaming/page/2/,676,0,77\n1547676391757,3423,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-1,,true,,28648,1297,5,5,null,3421,2,157\n1547676395168,496,HP-2,200,OK,Thread Group 1-5,text,true,,13770,396,5,5,https://www.foo.com/blog/page/2/,495,0,0\n1547676394112,1550,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-5,,true,,28992,1250,5,5,null,1548,3,78\n1547676395315,1032,Search-0,200,OK,Thread Group 1-4,text,true,,13657,409,5,5,https://www.foo.com/?s=streaming,1031,0,79\n1547676396347,192,Search-1,200,OK,Thread Group 1-4,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,191,0,0\n1547676396539,596,Search-2,200,OK,Thread Group 1-4,text,true,,13475,415,5,5,https://www.foo.com/search/streaming/page/2/,595,0,0\n1547676395315,1820,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-4,,true,,28643,1297,5,5,null,1817,0,79\n1547676383008,5490,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-3,,true,,57632,2547,5,5,null,5487,10103,155\n1547676398602,892,HP-0,200,OK,Thread Group 1-3,text,true,,13628,390,5,5,https://www.foo.com/blog/,891,0,85\n1547676398655,839,Search-0,200,OK,Thread Group 1-2,text,true,,13657,409,5,5,https://www.foo.com/?s=streaming,838,0,78\n1547676399495,391,Search-1,200,OK,Thread Group 1-2,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,391,0,0\n1547676399495,391,HP-1,200,OK,Thread Group 1-3,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,391,0,0\n1547676384683,5451,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-1,,true,,57641,2547,5,5,null,5448,10144,241\n1547676399887,798,HP-2,200,OK,Thread Group 1-3,text,true,,13770,396,5,5,https://www.foo.com/blog/page/2/,797,0,0\n1547676398602,2081,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-3,,true,,28990,1250,5,5,null,2079,2,85\n1547676399887,839,Search-2,200,OK,Thread Group 1-2,text,true,,13476,415,5,5,https://www.foo.com/search/streaming/page/2/,837,0,0\n1547676398654,2069,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-2,,true,,28644,1297,5,5,null,2066,3,78\n1547676400279,937,HP-0,200,OK,Thread Group 1-1,text,true,,13629,390,5,5,https://www.foo.com/blog/,936,0,85\n1547676400669,725,Search-0,200,OK,Thread Group 1-5,text,true,,13657,409,5,5,https://www.foo.com/?s=streaming,724,0,79\n1547676401217,331,HP-1,200,OK,Thread Group 1-1,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,331,0,0\n1547676401394,334,Search-1,200,OK,Thread Group 1-5,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,334,0,0\n1547676389018,3053,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-4,,true,,57629,2547,5,5,null,3048,10140,158\n1547676401548,678,HP-2,200,OK,Thread Group 1-1,text,true,,13770,396,5,5,https://www.foo.com/blog/page/2/,677,0,0\n1547676400278,1946,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-1,,true,,28991,1250,5,5,null,1944,2,85\n1547676401729,645,Search-2,200,OK,Thread Group 1-5,text,true,,13477,415,5,5,https://www.foo.com/search/streaming/page/2/,644,0,0\n1547676400669,1704,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-5,,true,,28645,1297,5,5,null,1702,1,79\n1547676402211,625,HP-0,200,OK,Thread Group 1-4,text,true,,13627,390,5,5,https://www.foo.com/blog/,625,0,87\n1547676402837,192,HP-1,200,OK,Thread Group 1-4,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,192,0,0\n1547676403029,397,HP-2,200,OK,Thread Group 1-4,text,true,,13769,396,5,5,https://www.foo.com/blog/page/2/,397,0,0\n1547676402210,1214,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-4,,true,,28988,1250,5,5,null,1214,3,87\n1547676391065,4597,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-2,,true,,57632,2547,5,5,null,4593,10074,163\n1547676405736,835,HP-0,200,OK,Thread Group 1-2,text,true,,13630,390,5,5,https://www.foo.com/blog/,835,0,81\n1547676405698,879,Search-0,200,OK,Thread Group 1-3,text,true,,13654,409,5,5,https://www.foo.com/?s=streaming,873,0,81\n1547676406572,393,HP-1,200,OK,Thread Group 1-2,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,393,0,0\n1547676406578,387,Search-1,200,OK,Thread Group 1-3,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,387,0,0\n1547676394112,3254,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-5,,true,,57637,2547,5,5,null,3250,10088,157\n1547676406966,983,HP-2,200,OK,Thread Group 1-2,text,true,,13769,396,5,5,https://www.foo.com/blog/page/2/,982,0,0\n1547676405735,2211,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-2,,true,,28991,1250,5,5,null,2210,3,81\n1547676406966,996,Search-2,200,OK,Thread Group 1-3,text,true,,13476,415,5,5,https://www.foo.com/search/streaming/page/2/,995,0,0\n1547676405698,2262,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-3,,true,,28641,1297,5,5,null,2255,2,81\n1547676407455,1023,HP-0,200,OK,Thread Group 1-5,text,true,,13631,390,5,5,https://www.foo.com/blog/,1022,0,80\n1547676407281,1197,Search-0,200,OK,Thread Group 1-1,text,true,,13656,409,5,5,https://www.foo.com/?s=streaming,1196,0,83\n1547676408479,648,HP-1,200,OK,Thread Group 1-5,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,648,0,0\n1547676408479,648,Search-1,200,OK,Thread Group 1-1,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,648,0,0\n1547676408474,870,Search-0,200,OK,Thread Group 1-4,text,true,,13657,409,5,5,https://www.foo.com/?s=streaming,870,0,84\n1547676409345,535,Search-1,200,OK,Thread Group 1-4,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,535,0,0\n1547676409128,1007,HP-2,200,OK,Thread Group 1-5,text,true,,13768,396,5,5,https://www.foo.com/blog/page/2/,1006,0,0\n1547676407454,2678,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-5,,true,,28991,1250,5,5,null,2676,3,80\n1547676409128,1055,Search-2,200,OK,Thread Group 1-1,text,true,,13477,415,5,5,https://www.foo.com/search/streaming/page/2/,1053,0,0\n1547676407280,2900,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-1,,true,,28644,1297,5,5,null,2897,3,83\n1547676409880,626,Search-2,200,OK,Thread Group 1-4,text,true,,13475,415,5,5,https://www.foo.com/search/streaming/page/2/,626,0,0\n1547676408474,2031,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-4,,true,,28643,1297,5,5,null,2031,2,84\n1547676398602,4343,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-3,,true,,57631,2547,5,5,null,4334,10047,166\n1547676413045,803,Search-0,200,OK,Thread Group 1-2,text,true,,13657,409,5,5,https://www.foo.com/?s=streaming,802,0,78\n1547676412993,855,HP-0,200,OK,Thread Group 1-3,text,true,,13628,390,5,5,https://www.foo.com/blog/,854,0,80\n1547676413848,391,Search-1,200,OK,Thread Group 1-2,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,391,0,0\n1547676413848,391,HP-1,200,OK,Thread Group 1-3,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,391,0,0\n1547676414240,792,HP-2,200,OK,Thread Group 1-3,text,true,,13769,396,5,5,https://www.foo.com/blog/page/2/,791,0,0\n1547676412992,2038,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-3,,true,,28989,1250,5,5,null,2036,2,80\n1547676414240,792,Search-2,200,OK,Thread Group 1-2,text,true,,13477,415,5,5,https://www.foo.com/search/streaming/page/2/,791,0,0\n1547676413044,1986,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-2,,true,,28645,1297,5,5,null,1984,2,78\n1547676400278,4846,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-1,,true,,57635,2547,5,5,null,4841,10106,168\n1547676402210,3245,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-4,,true,,57631,2547,5,5,null,3245,10141,171\n1547676415231,981,HP-0,200,OK,Thread Group 1-1,text,true,,13629,390,5,5,https://www.foo.com/blog/,980,0,79\n1547676415153,1059,Search-0,200,OK,Thread Group 1-5,text,true,,13656,409,5,5,https://www.foo.com/?s=streaming,1058,0,80\n1547676415597,1003,HP-0,200,OK,Thread Group 1-4,text,true,,13630,390,5,5,https://www.foo.com/blog/,1002,0,82\n1547676416213,470,HP-1,200,OK,Thread Group 1-1,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,469,0,0\n1547676416213,470,Search-1,200,OK,Thread Group 1-5,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,469,0,0\n1547676416600,481,HP-1,200,OK,Thread Group 1-4,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,481,0,0\n1547676416683,1096,HP-2,200,OK,Thread Group 1-1,text,true,,13769,396,5,5,https://www.foo.com/blog/page/2/,1095,0,0\n1547676415230,2547,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-1,,true,,28990,1250,5,5,null,2544,2,79\n1547676416683,1096,Search-2,200,OK,Thread Group 1-5,text,true,,13479,415,5,5,https://www.foo.com/search/streaming/page/2/,1095,0,0\n1547676415153,2625,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-5,,true,,28646,1297,5,5,null,2622,1,80\n1547676417081,789,HP-2,200,OK,Thread Group 1-4,text,true,,13769,396,5,5,https://www.foo.com/blog/page/2/,788,0,0\n1547676415596,2273,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-4,,true,,28991,1250,5,5,null,2271,1,82\n1547676405735,4197,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-2,,true,,57636,2547,5,5,null,4194,10115,159\n1547676420048,784,HP-0,200,OK,Thread Group 1-2,text,true,,13629,390,5,5,https://www.foo.com/blog/,783,0,80\n1547676420060,820,Search-0,200,OK,Thread Group 1-3,text,true,,13656,409,5,5,https://www.foo.com/?s=streaming,819,0,76\n1547676420834,681,HP-1,200,OK,Thread Group 1-2,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,681,0,0\n1547676420880,635,Search-1,200,OK,Thread Group 1-3,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,635,0,0\n1547676421515,786,Search-2,200,OK,Thread Group 1-3,text,true,,13476,415,5,5,https://www.foo.com/search/streaming/page/2/,786,0,0\n1547676421515,786,HP-2,200,OK,Thread Group 1-2,text,true,,13769,396,5,5,https://www.foo.com/blog/page/2/,786,0,0\n1547676420059,2241,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-3,,true,,28643,1297,5,5,null,2240,1,76\n1547676420047,2251,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-2,,true,,28990,1250,5,5,null,2250,3,80\n1547676407454,5303,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-5,,true,,57637,2547,5,5,null,5298,10041,160\n1547676422798,1470,HP-0,200,OK,Thread Group 1-5,text,true,,13630,390,5,5,https://www.foo.com/blog/,1469,0,89\n1547676422798,1470,Search-0,200,OK,Thread Group 1-1,text,true,,13658,409,5,5,https://www.foo.com/?s=streaming,1469,0,84\n1547676422919,1350,Search-0,200,OK,Thread Group 1-4,text,true,,13656,409,5,5,https://www.foo.com/?s=streaming,1349,0,79\n1547676424269,1966,Search-1,200,OK,Thread Group 1-4,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,1966,0,0\n1547676424269,1966,Search-1,200,OK,Thread Group 1-1,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,1966,0,0\n1547676424269,2554,HP-1,200,OK,Thread Group 1-5,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,2554,0,0\n1547676426236,1151,Search-2,200,OK,Thread Group 1-4,text,true,,13478,415,5,5,https://www.foo.com/search/streaming/page/2/,1150,0,80\n1547676426236,1151,Search-2,200,OK,Thread Group 1-1,text,true,,13476,415,5,5,https://www.foo.com/search/streaming/page/2/,1150,0,80\n1547676422919,4467,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-4,,true,,28645,1297,5,5,null,4465,1,159\n1547676422798,4587,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-1,,true,,28645,1297,5,5,null,4585,2,164\n1547676412992,4279,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-3,,true,,57632,2547,5,5,null,4276,10127,156\n1547676426823,836,HP-2,200,OK,Thread Group 1-5,text,true,,13769,396,5,5,https://www.foo.com/blog/page/2/,836,0,79\n1547676422798,4860,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-5,,true,,28991,1250,5,5,null,4859,3,168\n1547676427398,998,HP-0,200,OK,Thread Group 1-3,text,true,,13628,390,5,5,https://www.foo.com/blog/,997,0,79\n1547676427382,1015,Search-0,200,OK,Thread Group 1-2,text,true,,13656,409,5,5,https://www.foo.com/?s=streaming,1014,0,77\n1547676428397,391,Search-1,200,OK,Thread Group 1-2,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,391,0,0\n1547676428397,391,HP-1,200,OK,Thread Group 1-3,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,391,0,0\n1547676428788,701,HP-2,200,OK,Thread Group 1-3,text,true,,13766,396,5,5,https://www.foo.com/blog/page/2/,700,0,0\n1547676427397,2090,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-3,,true,,28986,1250,5,5,null,2088,3,79\n1547676428788,722,Search-2,200,OK,Thread Group 1-2,text,true,,13476,415,5,5,https://www.foo.com/search/streaming/page/2/,722,0,0\n1547676427382,2128,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-2,,true,,28643,1297,5,5,null,2127,0,77\n1547676415596,6740,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-4,,true,,57636,2547,5,5,null,6736,10068,241\n1547676415230,7134,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-1,,true,,57635,2547,5,5,null,7129,10070,243\n1547676432434,1075,HP-0,200,OK,Thread Group 1-1,text,true,,13630,390,5,5,https://www.foo.com/blog/,1074,0,79\n1547676432404,1105,HP-0,200,OK,Thread Group 1-4,text,true,,13631,390,5,5,https://www.foo.com/blog/,1104,0,84\n1547676432743,945,Search-0,200,OK,Thread Group 1-5,text,true,,13656,409,5,5,https://www.foo.com/?s=streaming,944,0,78\n1547676433509,588,HP-1,200,OK,Thread Group 1-4,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,588,0,0\n1547676433689,408,Search-1,200,OK,Thread Group 1-5,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,408,0,0\n1547676433509,588,HP-1,200,OK,Thread Group 1-1,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,588,0,0\n1547676420047,4379,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-2,,true,,57633,2547,5,5,null,4377,10124,157\n1547676434098,1574,HP-2,200,OK,Thread Group 1-1,text,true,,13769,396,5,5,https://www.foo.com/blog/page/2/,1573,0,0\n1547676432433,3237,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-1,,true,,28991,1250,5,5,null,3235,3,79\n1547676434098,1575,Search-2,200,OK,Thread Group 1-5,text,true,,13477,415,5,5,https://www.foo.com/search/streaming/page/2/,1574,0,0\n1547676432743,2928,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-5,,true,,28644,1297,5,5,null,2926,2,78\n1547676434098,1599,HP-2,200,OK,Thread Group 1-4,text,true,,13769,396,5,5,https://www.foo.com/blog/page/2/,1573,0,0\n1547676432403,3292,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-4,,true,,28992,1250,5,5,null,3265,2,84\n1547676434550,1304,HP-0,200,OK,Thread Group 1-2,text,true,,13631,390,5,5,https://www.foo.com/blog/,1302,0,81\n1547676434578,1321,Search-0,200,OK,Thread Group 1-3,text,true,,13657,409,5,5,https://www.foo.com/?s=streaming,1320,0,79\n1547676435855,357,HP-1,200,OK,Thread Group 1-2,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,357,0,0\n1547676435900,327,Search-1,200,OK,Thread Group 1-3,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,327,0,0\n1547676436213,835,HP-2,200,OK,Thread Group 1-2,text,true,,13769,396,5,5,https://www.foo.com/blog/page/2/,834,0,0\n1547676436227,821,Search-2,200,OK,Thread Group 1-3,text,true,,13478,415,5,5,https://www.foo.com/search/streaming/page/2/,820,0,0\n1547676434549,2496,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-2,,true,,28992,1250,5,5,null,2493,3,81\n1547676434578,2469,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-3,,true,,28646,1297,5,5,null,2467,2,79\n1547676422798,7788,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-5,,true,,57635,2547,5,5,null,7785,10121,246\n1547676440707,1256,HP-0,200,OK,Thread Group 1-5,text,true,,13630,390,5,5,https://www.foo.com/blog/,1255,0,77\n1547676440699,1264,Search-0,200,OK,Thread Group 1-4,text,true,,13657,409,5,5,https://www.foo.com/?s=streaming,1263,0,79\n1547676440724,1239,Search-0,200,OK,Thread Group 1-1,text,true,,13656,409,5,5,https://www.foo.com/?s=streaming,1238,0,82\n1547676427397,4559,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-3,,true,,57632,2547,5,5,null,4555,10117,158\n1547676441964,785,Search-1,200,OK,Thread Group 1-1,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,785,0,0\n1547676441964,785,Search-1,200,OK,Thread Group 1-4,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,785,0,0\n1547676441963,786,HP-1,200,OK,Thread Group 1-5,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,786,0,0\n1547676442073,1659,HP-0,200,OK,Thread Group 1-3,text,true,,13631,390,5,5,https://www.foo.com/blog/,1658,0,80\n1547676442123,2211,Search-0,200,OK,Thread Group 1-2,text,true,,13658,409,5,5,https://www.foo.com/?s=streaming,2198,0,80\n1547676442749,1657,HP-2,200,OK,Thread Group 1-5,text,true,,13770,396,5,5,https://www.foo.com/blog/page/2/,1655,0,80\n1547676440706,3699,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-5,,true,,28992,1250,5,5,null,3696,1,157\n1547676442749,1742,Search-2,200,OK,Thread Group 1-4,text,true,,13478,415,5,5,https://www.foo.com/search/streaming/page/2/,1741,0,78\n1547676440699,3791,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-4,,true,,28646,1297,5,5,null,3789,1,157\n1547676442749,1743,Search-2,200,OK,Thread Group 1-1,text,true,,13474,415,5,5,https://www.foo.com/search/streaming/page/2/,1743,0,80\n1547676440724,3767,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-1,,true,,28641,1297,5,5,null,3766,1,162\n1547676443733,764,HP-1,200,OK,Thread Group 1-3,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,763,0,0\n1547676444335,354,Search-1,200,OK,Thread Group 1-2,text,true,,1512,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,354,0,79\n1547676444497,809,HP-2,200,OK,Thread Group 1-3,text,true,,13770,396,5,5,https://www.foo.com/blog/page/2/,808,0,81\n1547676442073,3232,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-3,,true,,28993,1250,5,5,null,3229,1,161\n1547676444689,656,Search-2,200,OK,Thread Group 1-2,text,true,,13476,415,5,5,https://www.foo.com/search/streaming/page/2/,654,0,0\n1547676442122,3221,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-2,,true,,28646,1297,5,5,null,3206,2,159\n1547676432403,7083,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-4,,true,,57638,2547,5,5,null,7054,10045,241\n1547676432433,7004,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-1,,true,,57632,2547,5,5,null,7001,10148,241\n1547676449453,837,Search-0,200,OK,Thread Group 1-5,text,true,,13656,409,5,5,https://www.foo.com/?s=streaming,836,0,81\n1547676434549,5717,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-2,,true,,57638,2547,5,5,null,5699,10179,240\n1547676450292,705,Search-1,200,OK,Thread Group 1-5,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,705,0,0\n1547676449586,2405,HP-0,200,OK,Thread Group 1-1,text,true,,13630,390,5,5,https://www.foo.com/blog/,2404,0,664\n1547676449531,2460,HP-0,200,OK,Thread Group 1-4,text,true,,13630,390,5,5,https://www.foo.com/blog/,2459,0,719\n1547676450334,1894,Search-0,200,OK,Thread Group 1-3,text,true,,13657,409,5,5,https://www.foo.com/?s=streaming,1894,0,123\n1547676450446,2332,HP-0,200,OK,Thread Group 1-2,text,true,,13631,390,5,5,https://www.foo.com/blog/,2331,0,583\n1547676450998,1780,Search-2,200,OK,Thread Group 1-5,text,true,,13477,415,5,5,https://www.foo.com/search/streaming/page/2/,1779,0,0\n1547676449453,3322,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-5,,true,,28644,1297,5,5,null,3320,3,81\n1547676451990,882,HP-1,200,OK,Thread Group 1-1,text,true,,1593,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,882,0,84\n1547676451990,893,HP-1,200,OK,Thread Group 1-4,text,true,,1593,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,893,0,84\n1547676452228,748,Search-1,200,OK,Thread Group 1-3,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,748,0,0\n1547676452777,784,HP-1,200,OK,Thread Group 1-2,text,true,,1593,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,784,0,79\n1547676452883,1466,HP-2,200,OK,Thread Group 1-4,text,true,,13769,396,5,5,https://www.foo.com/blog/page/2/,1465,0,0\n1547676452873,1476,HP-2,200,OK,Thread Group 1-1,text,true,,13769,396,5,5,https://www.foo.com/blog/page/2/,1475,0,0\n1547676449531,4819,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-4,,true,,28992,1250,5,5,null,4817,0,803\n1547676449585,4763,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-1,,true,,28992,1250,5,5,null,4761,2,748\n1547676452977,1401,Search-2,200,OK,Thread Group 1-3,text,true,,13478,415,5,5,https://www.foo.com/search/streaming/page/2/,1400,0,79\n1547676450334,4043,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-3,,true,,28646,1297,5,5,null,4042,3,202\n1547676453562,934,HP-2,200,OK,Thread Group 1-2,text,true,,13770,396,5,5,https://www.foo.com/blog/page/2/,933,0,0\n1547676450446,4050,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-2,,true,,28994,1250,5,5,null,4048,1,662\n1547676440706,7021,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-5,,true,,57636,2547,5,5,null,7016,10128,238\n1547676457856,1451,HP-0,200,OK,Thread Group 1-5,text,true,,13629,390,5,5,https://www.foo.com/blog/,1451,0,81\n1547676442073,7275,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-3,,true,,57639,2547,5,5,null,7271,10053,363\n1547676459308,281,HP-1,200,OK,Thread Group 1-5,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,281,0,0\n1547676459402,1829,HP-0,200,OK,Thread Group 1-3,text,true,,13629,390,5,5,https://www.foo.com/blog/,1829,0,78\n1547676459590,1740,HP-2,200,OK,Thread Group 1-5,text,true,,13771,396,5,5,https://www.foo.com/blog/page/2/,1740,0,0\n1547676457855,3472,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-5,,true,,28992,1250,5,5,null,3472,4,81\n1547676459392,1947,Search-0,200,OK,Thread Group 1-4,text,true,,13657,409,5,5,https://www.foo.com/?s=streaming,1946,0,78\n1547676459441,1943,Search-0,200,OK,Thread Group 1-1,text,true,,13658,409,5,5,https://www.foo.com/?s=streaming,1942,0,78\n1547676459525,1984,Search-0,200,OK,Thread Group 1-2,text,true,,13658,409,5,5,https://www.foo.com/?s=streaming,1983,0,79\n1547676461232,785,HP-1,200,OK,Thread Group 1-3,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,785,0,0\n1547676461338,678,Search-1,200,OK,Thread Group 1-4,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,678,0,0\n1547676461384,637,Search-1,200,OK,Thread Group 1-1,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,637,0,0\n1547676461508,551,Search-1,200,OK,Thread Group 1-2,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,551,0,0\n1547676462016,1478,HP-2,200,OK,Thread Group 1-3,text,true,,13770,396,5,5,https://www.foo.com/blog/page/2/,1478,0,80\n1547676459401,4092,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-3,,true,,28991,1250,5,5,null,4092,3,158\n1547676462016,1545,Search-2,200,OK,Thread Group 1-4,text,true,,13478,415,5,5,https://www.foo.com/search/streaming/page/2/,1544,0,80\n1547676459391,4170,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-4,,true,,28646,1297,5,5,null,4168,1,158\n1547676462021,1570,Search-2,200,OK,Thread Group 1-1,text,true,,13479,415,5,5,https://www.foo.com/search/streaming/page/2/,1568,0,75\n1547676459440,4150,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-1,,true,,28648,1297,5,5,null,4147,2,153\n1547676462060,1537,Search-2,200,OK,Thread Group 1-2,text,true,,13479,415,5,5,https://www.foo.com/search/streaming/page/2/,1536,0,80\n1547676459525,4072,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-2,,true,,28648,1297,5,5,null,4070,1,159\n1547676466393,540,Search-0,200,OK,Thread Group 1-5,text,true,,13657,409,5,5,https://www.foo.com/?s=streaming,540,0,78\n1547676466934,190,Search-1,200,OK,Thread Group 1-5,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,190,0,0\n1547676467125,398,Search-2,200,OK,Thread Group 1-5,text,true,,13477,415,5,5,https://www.foo.com/search/streaming/page/2/,397,0,0\n1547676466392,1128,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-5,,true,,28645,1297,5,5,null,1127,3,78\n1547676449531,8989,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-4,,true,,57638,2547,5,5,null,8985,10072,961\n1547676449585,8913,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-1,,true,,57640,2547,5,5,null,8908,10117,901\n1547676450446,8122,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-2,,true,,57642,2547,5,5,null,8118,10069,821\n1547676468509,1583,Search-0,200,OK,Thread Group 1-3,text,true,,13658,409,5,5,https://www.foo.com/?s=streaming,1583,0,79\n1547676468592,1669,HP-0,200,OK,Thread Group 1-4,text,true,,13632,390,5,5,https://www.foo.com/blog/,1669,0,81\n1547676468615,1662,HP-0,200,OK,Thread Group 1-1,text,true,,13630,390,5,5,https://www.foo.com/blog/,1661,0,77\n1547676468638,1643,HP-0,200,OK,Thread Group 1-2,text,true,,13629,390,5,5,https://www.foo.com/blog/,1643,0,77\n1547676470093,771,Search-1,200,OK,Thread Group 1-3,text,true,,1511,473,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=foo&count=3,771,0,0\n1547676470277,638,HP-1,200,OK,Thread Group 1-1,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,638,0,0\n1547676470262,653,HP-1,200,OK,Thread Group 1-4,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,653,0,0\n1547676470282,633,HP-1,200,OK,Thread Group 1-2,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,633,0,0\n1547676457855,4600,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-5,,true,,57637,2547,5,5,null,4599,10091,159\n1547676470864,1687,Search-2,200,OK,Thread Group 1-3,text,true,,13478,415,5,5,https://www.foo.com/search/streaming/page/2/,1686,0,77\n1547676468509,4041,Search,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-3,,true,,28647,1297,5,5,null,4040,1,156\n1547676470916,1648,HP-2,200,OK,Thread Group 1-4,text,true,,13770,396,5,5,https://www.foo.com/blog/page/2/,1648,0,80\n1547676468592,3970,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-4,,true,,28994,1250,5,5,null,3970,3,161\n1547676470916,1650,HP-2,200,OK,Thread Group 1-1,text,true,,13770,396,5,5,https://www.foo.com/blog/page/2/,1649,0,79\n1547676468615,3950,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-1,,true,,28992,1250,5,5,null,3948,1,156\n1547676470916,1651,HP-2,200,OK,Thread Group 1-2,text,true,,13770,396,5,5,https://www.foo.com/blog/page/2/,1650,0,85\n1547676468637,3927,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-2,,true,,28991,1250,5,5,null,3926,3,162\n1547676472546,874,HP-0,200,OK,Thread Group 1-5,text,true,,13630,390,5,5,https://www.foo.com/blog/,874,0,82\n1547676473421,194,HP-1,200,OK,Thread Group 1-5,text,true,,1592,464,5,5,https://www.foo.com/wp-admin/admin-ajax.php?action=ishyoboy_get_tweets&username=ubikloadpack&count=3,194,0,0\n1547676473616,394,HP-2,200,OK,Thread Group 1-5,text,true,,13769,396,5,5,https://www.foo.com/blog/page/2/,393,0,0\n1547676472545,1462,HP,200,\"Number of samples in transaction : 3, number of failing samples : 0\",Thread Group 1-5,,true,,28991,1250,5,5,null,1461,3,82\n1547676459401,8133,Scenario,200,\"Number of samples in transaction : 10, number of failing samples : 0\",Thread Group 1-3,,true,,57638,2547,5,5,null,8132,9649,314"
  },
  {
    "path": "src/test/resources/jUnitIssue5571.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<testsuite errors=\"0\" failures=\"0\" name=\"com.icw.ehf.training.medicinecabinet.service.adapter.CabinetAdminServiceDtoAdapterBenchTest\" tests=\"200\" time=\"10.059\">\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.89\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.05\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.0060\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.075\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.0080\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.058\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.017\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.037\"></testcase>\n\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.013\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.038\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.01\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.038\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.01\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.04\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.01\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.042\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.012\"></testcase>\n\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.034\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.023\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.028\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.026\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.022\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.034\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.014\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.032\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.02\"></testcase>\n\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.027\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.023\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.026\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.019\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.049\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.018\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.046\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.024\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.046\"></testcase>\n\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.011\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.014\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.044\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.013\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.035\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.022\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.043\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.052\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.035\"></testcase>\n\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.042\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.048\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.038\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.037\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.036\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.038\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.037\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.04\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.041\"></testcase>\n\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.036\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.048\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.041\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.038\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.037\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.034\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.036\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.035\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.033\"></testcase>\n\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.036\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.034\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.034\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.044\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.042\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.039\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.041\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.039\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.036\"></testcase>\n\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.037\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.037\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.036\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.089\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.062\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.052\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.039\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.035\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.034\"></testcase>\n\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.033\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.034\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.032\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.032\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.035\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.032\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.039\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.039\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.032\"></testcase>\n\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.032\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.035\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.034\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.044\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.042\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.038\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.031\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.038\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.032\"></testcase>\n\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.035\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.039\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.032\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.033\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.032\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.043\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.039\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.033\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.033\"></testcase>\n\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.033\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.031\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.031\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.033\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.033\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.032\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.036\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.036\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.032\"></testcase>\n\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.031\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.031\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.03\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.032\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.033\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.037\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.033\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.031\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.031\"></testcase>\n\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.03\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.04\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.033\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.032\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.03\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.037\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.032\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.031\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.031\"></testcase>\n\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.031\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.032\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.033\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.037\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.031\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.031\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.03\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.03\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.031\"></testcase>\n\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.032\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.042\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.033\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.033\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.033\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.036\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.038\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.032\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.037\"></testcase>\n\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.033\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.031\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.032\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.031\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.038\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.055\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.047\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.045\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.03\"></testcase>\n\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.031\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.03\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.034\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.037\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.038\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.039\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.042\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.031\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.03\"></testcase>\n\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.032\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.031\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.031\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.031\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.031\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.034\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.037\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.037\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.029\"></testcase>\n\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.03\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.032\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.036\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.033\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.032\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.033\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.035\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.031\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.033\"></testcase>\n\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.032\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.031\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.034\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.032\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.033\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.031\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.031\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.032\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.032\"></testcase>\n\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.031\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.03\"></testcase>\n  <testcase classname=\"junit.framework.JUnit4TestCaseFacade\" name=\"unknown\" time=\"0.029\"></testcase>\n  <system-out><![CDATA[]]></system-out>\n  <system-err><![CDATA[]]></system-err>\n</testsuite>\n"
  },
  {
    "path": "src/test/resources/jmeter.log",
    "content": "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: Loading user properties from: /home/artem/apache-jmeter-3.2/bin/user.properties\n2017-08-18 17:23:41,974 INFO o.a.j.JMeter: Loading system properties from: /home/artem/apache-jmeter-3.2/bin/system.properties\n2017-08-18 17:23:41,977 INFO o.a.j.JMeter: Copyright (c) 1998-2017 The Apache Software Foundation\n2017-08-18 17:23:41,977 INFO o.a.j.JMeter: Version 3.2 r1790748\n2017-08-18 17:23:41,977 INFO o.a.j.JMeter: java.version=1.8.0_131\n2017-08-18 17:23:41,977 INFO o.a.j.JMeter: java.vm.name=Java HotSpot(TM) 64-Bit Server VM\n2017-08-18 17:23:41,977 INFO o.a.j.JMeter: os.name=Linux\n2017-08-18 17:23:41,977 INFO o.a.j.JMeter: os.arch=amd64\n2017-08-18 17:23:41,977 INFO o.a.j.JMeter: os.version=4.4.0-92-generic\n2017-08-18 17:23:41,977 INFO o.a.j.JMeter: file.encoding=UTF-8\n2017-08-18 17:23:41,977 INFO o.a.j.JMeter: Max memory     =536870912\n2017-08-18 17:23:41,977 INFO o.a.j.JMeter: Available Processors =8\n2017-08-18 17:23:41,981 INFO o.a.j.JMeter: Default Locale=English (United States)\n2017-08-18 17:23:41,982 INFO o.a.j.JMeter: JMeter  Locale=English (United States)\n2017-08-18 17:23:41,982 INFO o.a.j.JMeter: JMeterHome=/home/artem/apache-jmeter-3.2\n2017-08-18 17:23:41,982 INFO o.a.j.JMeter: user.dir  =/var/lib/jenkins/workspace/throughput_summary_jmeter\n2017-08-18 17:23:41,982 INFO o.a.j.JMeter: PWD       =/var/lib/jenkins/workspace/throughput_summary_jmeter\n2017-08-18 17:23:41,982 INFO o.a.j.JMeter: IP: 127.0.1.1 Name: artem-fedorov-pc FullName: artem-fedorov-pc\n2017-08-18 17:23:41,984 INFO o.a.j.s.FileServer: Default base='/var/lib/jenkins/workspace/throughput_summary_jmeter'\n2017-08-18 17:23:41,984 INFO o.a.j.s.FileServer: Set new base='/home/artem/jmx'\n2017-08-18 17:23:42,053 INFO o.a.j.s.SaveService: Testplan (JMX) version: 2.2. Testlog (JTL) version: 2.2\n2017-08-18 17:23:42,061 INFO o.a.j.s.SaveService: Using SaveService properties file encoding UTF-8\n2017-08-18 17:23:42,064 INFO o.a.j.s.SaveService: Using SaveService properties version 3.2\n2017-08-18 17:23:42,069 INFO o.a.j.s.SaveService: Loading file: /home/artem/jmx/summary.jmx\n2017-08-18 17:23:42,102 INFO o.a.j.JMeter: Creating summariser <summary>\n2017-08-18 17:23:42,105 INFO o.a.j.e.StandardJMeterEngine: Running the test!\n2017-08-18 17:23:42,106 INFO o.a.j.s.SampleEvent: List of sample_variables: []\n2017-08-18 17:23:42,106 INFO o.a.j.s.SampleEvent: List of sample_variables: []\n2017-08-18 17:23:42,109 INFO o.a.j.e.u.CompoundVariable: Note: Function class names must contain the string: '.functions.'\n2017-08-18 17:23:42,109 INFO o.a.j.e.u.CompoundVariable: Note: Function class names must not contain the string: '.gui.'\n2017-08-18 17:23:42,334 INFO o.a.j.JMeter: Running test (1503066222334)\n2017-08-18 17:23:42,360 INFO o.a.j.e.StandardJMeterEngine: Starting ThreadGroup: 1 : Thread Group\n2017-08-18 17:23:42,361 INFO o.a.j.e.StandardJMeterEngine: Starting 10 threads for group Thread Group.\n2017-08-18 17:23:42,361 INFO o.a.j.e.StandardJMeterEngine: Thread will continue on error\n2017-08-18 17:23:42,361 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=10 ramp-up=1 perThread=100.0 delayedStart=false\n2017-08-18 17:23:42,366 INFO o.a.j.t.ThreadGroup: Started thread group number 1\n2017-08-18 17:23:42,366 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started\n2017-08-18 17:23:42,366 INFO o.a.j.t.JMeterThread: Thread started: Thread Group 1-1\n2017-08-18 17:23:42,368 INFO o.a.j.s.SampleResult: Note: Sample TimeStamps are START times\n2017-08-18 17:23:42,368 INFO o.a.j.s.SampleResult: sampleresult.default.encoding is set to ISO-8859-1\n2017-08-18 17:23:42,368 INFO o.a.j.s.SampleResult: sampleresult.useNanoTime=true\n2017-08-18 17:23:42,368 INFO o.a.j.s.SampleResult: sampleresult.nanoThreadSleep=5000\n2017-08-18 17:23:42,466 INFO o.a.j.t.JMeterThread: Thread started: Thread Group 1-2\n2017-08-18 17:23:42,566 INFO o.a.j.t.JMeterThread: Thread started: Thread Group 1-3\n2017-08-18 17:23:42,672 INFO o.a.j.t.JMeterThread: Thread started: Thread Group 1-4\n2017-08-18 17:23:42,766 INFO o.a.j.t.JMeterThread: Thread started: Thread Group 1-5\n2017-08-18 17:23:42,866 INFO o.a.j.t.JMeterThread: Thread started: Thread Group 1-6\n2017-08-18 17:23:42,966 INFO o.a.j.t.JMeterThread: Thread started: Thread Group 1-7\n2017-08-18 17:23:43,066 INFO o.a.j.t.JMeterThread: Thread started: Thread Group 1-8\n2017-08-18 17:23:43,166 INFO o.a.j.t.JMeterThread: Thread started: Thread Group 1-9\n2017-08-18 17:23:43,266 INFO o.a.j.t.JMeterThread: Thread started: Thread Group 1-10\n2017-08-18 17:24:00,006 INFO o.a.j.r.Summariser: Generate Summary Results +    626 in 00:00:18 =   35.4/s Avg:   270 Min:    50 Max:   500 Err:     0 (0.00%) Active: 10 Started: 10 Finished: 0\n2017-08-18 17:24:00,007 INFO o.a.j.r.Summariser: summary +    626 in 00:00:18 =   35.4/s Avg:   270 Min:    50 Max:   500 Err:     0 (0.00%) Active: 10 Started: 10 Finished: 0\n2017-08-18 17:24:08,047 INFO o.a.j.t.JMeterThread: Thread is done: Thread Group 1-5\n2017-08-18 17:24:08,047 INFO o.a.j.t.JMeterThread: Thread finished: Thread Group 1-5\n2017-08-18 17:24:08,577 INFO o.a.j.t.JMeterThread: Thread is done: Thread Group 1-6\n2017-08-18 17:24:08,577 INFO o.a.j.t.JMeterThread: Thread finished: Thread Group 1-6\n2017-08-18 17:24:09,948 INFO o.a.j.t.JMeterThread: Thread is done: Thread Group 1-8\n2017-08-18 17:24:09,948 INFO o.a.j.t.JMeterThread: Thread finished: Thread Group 1-8\n2017-08-18 17:24:09,965 INFO o.a.j.t.JMeterThread: Thread is done: Thread Group 1-7\n2017-08-18 17:24:09,965 INFO o.a.j.t.JMeterThread: Thread finished: Thread Group 1-7\n2017-08-18 17:24:10,013 INFO o.a.j.t.JMeterThread: Thread is done: Thread Group 1-10\n2017-08-18 17:24:10,014 INFO o.a.j.t.JMeterThread: Thread finished: Thread Group 1-10\n2017-08-18 17:24:10,668 INFO o.a.j.t.JMeterThread: Thread is done: Thread Group 1-4\n2017-08-18 17:24:10,668 INFO o.a.j.t.JMeterThread: Thread finished: Thread Group 1-4\n2017-08-18 17:24:10,804 INFO o.a.j.t.JMeterThread: Thread is done: Thread Group 1-1\n2017-08-18 17:24:10,805 INFO o.a.j.t.JMeterThread: Thread finished: Thread Group 1-1\n2017-08-18 17:24:11,635 INFO o.a.j.t.JMeterThread: Thread is done: Thread Group 1-2\n2017-08-18 17:24:11,635 INFO o.a.j.t.JMeterThread: Thread finished: Thread Group 1-2\n2017-08-18 17:24:11,998 INFO o.a.j.t.JMeterThread: Thread is done: Thread Group 1-3\n2017-08-18 17:24:11,998 INFO o.a.j.t.JMeterThread: Thread finished: Thread Group 1-3\n2017-08-18 17:24:12,902 INFO o.a.j.t.JMeterThread: Thread is done: Thread Group 1-9\n2017-08-18 17:24:12,902 INFO o.a.j.t.JMeterThread: Thread finished: Thread Group 1-9\n2017-08-18 17:24:12,903 INFO o.a.j.e.StandardJMeterEngine: Notifying test listeners of end of test\n2017-08-18 17:24:12,904 INFO o.a.j.r.Summariser: summary +    374 in 00:00:13 =   29.0/s Avg:   284 Min:    51 Max:   499 Err:     0 (0.00%) Active: 0 Started: 10 Finished: 10\n2017-08-18 17:24:12,905 INFO o.a.j.r.Summariser: summary =   1000 in 00:00:31 =   32.7/s Avg:   276 Min:    50 Max:   500 Err:     0 (0.00%)\n2017-08-18 17:24:12,905 INFO o.a.j.r.Summariser: Generate Summary Results +    374 in 00:00:13 =   29.0/s Avg:   284 Min:    51 Max:   499 Err:     0 (0.00%) Active: 0 Started: 10 Finished: 10\n2017-08-18 17:24:12,906 INFO o.a.j.r.Summariser: Generate Summary Results =   1000 in 00:00:31 =   32.7/s Avg:   276 Min:    50 Max:   500 Err:     0 (0.00%)\n"
  },
  {
    "path": "src/test/resources/multiLineCSV.jtl",
    "content": "timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,failureMessage,bytes,sentBytes,grpThreads,allThreads,Latency,IdleTime,Connect\n1492260110340,1898,Preparation: Login,200,OK,Review Date test 1-1,text,true,,15338,0,1,1,0,0,0\n1492260112271,118,\"no such element: Unable to locate element: {\"\"method\"\":\"\"id\"\",\"\"selector\"\":\"\"reviewBAD\"\"}\n                  Session ID: 89a1a36b52e184afb01963257d8739e8\n                  *** Element info: {Using=id, value=reviewBAD}\",500,NOTOK,Review Date test 1-1,text,false,,5815,0,1,1,0,0,0\n"
  },
  {
    "path": "src/test/resources/performanceTest.yml",
    "content": "---\nexecution:\n- hold-for: 5s\n  ramp-up: 5s\n  concurrency: 2\n  executor: apiritif\n  scenario:\n    retrieve-resources: false\n    requests:\n    - http://blazedemo.com/\n    - http://blazedemo.com/reserve.php\n"
  },
  {
    "path": "src/test/resources/performanceTestWithFailCriteria.yml",
    "content": "execution:\n- concurrency: 2\n  ramp-up: 5s\n  hold-for: 5s\n  scenario: quick-test\n  executor: apiritif\n\nscenarios:\n  quick-test:\n    retrieve-resources: false\n    requests:\n    - url: http://blazedemo.com/\n      label: index\n    \nreporting:\n- module: passfail\n  criteria:\n  - hits>0"
  },
  {
    "path": "src/test/resources/single_result/nested/res.jtl",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<testResults version=\"1.2\">\n<sample t=\"454\" it=\"0\" lt=\"32\" ct=\"2\" ts=\"1492525461260\" s=\"false\" lb=\"jp@gc - Dummy Sampler\" rc=\"200\" rm=\"OK\" tn=\"Thread Group 1-1\" dt=\"text\" by=\"114\" sby=\"0\" ng=\"1\" na=\"1\"/>\n<sample t=\"333\" it=\"0\" lt=\"13\" ct=\"4\" ts=\"1492525461726\" s=\"true\" lb=\"jp@gc - Dummy Sampler\" rc=\"200\" rm=\"OK\" tn=\"Thread Group 1-1\" dt=\"text\" by=\"114\" sby=\"0\" ng=\"1\" na=\"1\"/>\n\n</testResults>\n"
  },
  {
    "path": "src/test/resources/single_result/res.csv",
    "content": "timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,failureMessage,bytes,sentBytes,grpThreads,allThreads,Latency,IdleTime,Connect\n1497860498732,92,HTTP Request,Non HTTP response code: java.net.UnknownHostException,Non HTTP response message: blazdemo.com: Name or service not known,Thread Group 1-1,text,false,,2161,0,1,1,0,0,92\n"
  },
  {
    "path": "src/test/resources/summary.log",
    "content": "2014/05/22 14:50:15 INFO  - jmeter.util.JMeterUtils: Setting Locale to en_US \n2014/05/22 14:50:15 WARN  - jmeter.JMeter: LogLevel: DEBUG \n2014/05/22 14:50:15 INFO  - jmeter.JMeter: Copyright (c) 1998-2013 The Apache Software Foundation \n2014/05/22 14:50:15 INFO  - jmeter.JMeter: Version 2.10 r1533061 \n2014/05/22 14:50:15 INFO  - jmeter.JMeter: java.version=1.6.0_27 \n2014/05/22 14:50:15 INFO  - jmeter.JMeter: java.vm.name=Java HotSpot(TM) 64-Bit Server VM \n2014/05/22 14:50:15 INFO  - jmeter.JMeter: os.name=Linux \n2014/05/22 14:50:16 INFO  - jmeter.protocol.http.sampler.HTTPSamplerBase: Parser for application/xhtml+xml is  \n2014/05/22 14:50:16 INFO  - Some random line with a plus (+) in it shouldn't break the summariser parsing\n2014/05/22 14:50:16 INFO  - jmeter.protocol.http.sampler.HTTPSamplerBase: Parser for application/xml is  \n2014/05/22 14:50:16 INFO  - jmeter.protocol.http.sampler.HTTPSamplerBase: Parser for text/xml is  \n2014/05/22 14:51:00 INFO  - jmeter.reporters.Summariser: Generate Summary Results +    186 in    43s =    4.3/s Avg:   536 Min:     5 Max:  4617 Err:     0 (0.00%) Active: 5 Started: 5 Finished: 0 \n2014/05/22 14:53:54 INFO  - jmeter.engine.StandardJMeterEngine: Notifying test listeners of end of test \n2014/05/22 14:53:54 INFO  - jmeter.reporters.Summariser: Generate Summary Results +   1069 in   175s =    6.1/s Avg:   295 Min:    33 Max:  5628 Err:     0 (0.00%) Active: 0 Started: 5 Finished: 5 \n2014/05/22 14:53:54 INFO  - jmeter.reporters.Summariser: Generate Summary Results =   1255 in   217s =    5.8/s Avg:   330 Min:     5 Max:  5628 Err:     0 (0.00%)\n\n# added made up numbers\n2014/05/22 14:53:54 INFO  - jmeter.reporters.Summariser: Generate Summary Results +      1 in      1 =    1.0/s Avg:   295 Min:    33 Max:  5628 Err:     0 (0.00%) Active: 0 Started: 5 Finished: 5\n2014/05/22 14:53:54 INFO  - jmeter.reporters.Summariser: Generate Summary Results =   1256 in   217s =    6.8/s Avg:   331 Min:     4 Max:  5629 Err:     0 (0.00%)\n# added made up numbers\n2014/05/22 14:53:54 INFO  - jmeter.reporters.Summariser: Generate Summary Results +   1 in   175s =    6.1/s Avg:   295 Min:    33 Max:  5628 Err:     0 (0.00%) Active: 0 Started: 5 Finished: 5\n2014/05/22 14:53:54 INFO  - jmeter.reporters.Summariser: Generate Summary Results =   1257 in   217s =    7.8/s Avg:   333 Min:     3 Max:  5630 Err:     123 (4.56%)\n"
  },
  {
    "path": "src/test/resources/test_results_stats.csv",
    "content": "Type,Name,Request Count,Failure Count,Median Response Time,Average Response Time,Min Response Time,Max Response Time,Average Content Size,Requests/s,Failures/s,50%,66%,75%,80%,90%,95%,98%,99%,99.9%,99.99%,100%\n\nPOST,big,638,10,400.0,370.51828915662696,198.03439999999955,906.8718,1.0,1.07917812740814,1.07917812740814,480,510,530,540,570,580,620,630,630,630,630\n\nPOST,huge,72,0,800.0,865.0785481927712,411.80529999999993,1993.6761999999989,1.0,0.12917812740814,4.37917812740814,420,470,510,530,550,570,610,700,700,700,700\n\nPOST,medium,6535,0,200.0,221.6907592592591,197.3858000000009,469.2998,1.0,10.913655762892281,4.273655762892281,440,480,500,510,530,560,580,630,630,630,630\n\nPOST,small,64219,0,200.0,221.009044155844,196.10569999999944,1009.6347999999989,1.0,107.062611033860563,4.062611033860563,450,490,520,530,540,570,580,590,590,590,590\n\n,Aggregated,71464,10000,200.0,223.833905555556,196.10569999999944,1993.6761999999989,1.4444444444443,119.314623051569123,17.094623051569123,450,500,520,530,550,570,600,620,700,700,700\n\n"
  },
  {
    "path": "src/test/resources/whitespace-followed-by-xml.jtl",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<testResults version=\"1.2\">\n<httpSample t=\"14720\" lt=\"9770\" ts=\"1296846793179\" s=\"true\" lb=\"Home\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-2\" dt=\"text\" by=\"771065\"/>\n<httpSample t=\"15902\" lt=\"10954\" ts=\"1296846792004\" s=\"true\" lb=\"Home\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-1\" dt=\"text\" by=\"771065\"/>\n<httpSample t=\"278\" lt=\"148\" ts=\"1296846847952\" s=\"true\" lb=\"Workgroup\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-2\" dt=\"text\" by=\"744705\"/>\n<httpSample t=\"1017\" lt=\"694\" ts=\"1296846847222\" s=\"true\" lb=\"Workgroup\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-1\" dt=\"text\" by=\"744705\"/>\n<httpSample t=\"598\" lt=\"321\" ts=\"1296846947037\" s=\"true\" lb=\"Home\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-1\" dt=\"text\" by=\"771149\"/>\n<httpSample t=\"501\" lt=\"298\" ts=\"1296846947144\" s=\"true\" lb=\"Home\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-2\" dt=\"text\" by=\"771149\"/>\n<httpSample t=\"63\" lt=\"3\" ts=\"1296846968923\" s=\"true\" lb=\"Workgroup\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-1\" dt=\"text\" by=\"744705\"/>\n<httpSample t=\"58\" lt=\"2\" ts=\"1296846969096\" s=\"true\" lb=\"Workgroup\" rc=\"200\" rm=\"OK\" tn=\"Sesiones de usuario 1-2\" dt=\"text\" by=\"744705\"/>\n</testResults>\n"
  }
]