diff --git a/.circleci/config.yml b/.circleci/config.yml
index d9851d0d..d47e9423 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -102,23 +102,63 @@ jobs:
APPNAME: "projects-api"
steps: *deploy_steps
+ Connect-Performance-Testing:
+ docker:
+ # specify the version you desire here
+ - image: circleci/openjdk:8-jdk
+
+ # Specify service dependencies here if necessary
+ # CircleCI maintains a library of pre-built images
+ # documented at https://circleci.com/docs/2.0/circleci-images/
+ # - image: circleci/postgres:9.4
+
+ working_directory: ~/repo
+
+ environment:
+ # Customize the JVM maximum heap limit
+ MAVEN_OPTS: -Xmx3200m
+
+ steps:
+ - checkout
+
+ # Download and cache dependencies
+ - restore_cache:
+ keys:
+ - v1-dependencies-{{ checksum "pom.xml" }}
+ # fallback to using the latest cache if no exact match is found
+ - v1-dependencies-
+
+ - run: mvn dependency:go-offline
+
+ - save_cache:
+ paths:
+ - ~/.m2
+ key: v1-dependencies-{{ checksum "pom.xml" }}
+
+ - run: mvn verify
+
+ - store_artifacts:
+ path: target/jmeter/reports
+
workflows:
version: 2
- build:
+ Connect Project Services:
jobs:
- - test:
- context : org-global
- deployDev:
context : org-global
- requires:
- - test
filters:
branches:
- only: ['develop']
+ only: ['develop', 'connect-performance-testing']
- deployProd:
context : org-global
- requires:
- - test
filters:
branches:
- only: ['master']
+ only: ['master']
+ - Hold [Performance-Testing]:
+ type: approval
+ requires:
+ - deployDev
+ - deployProd
+ - Connect-Performance-Testing:
+ requires:
+ - Hold [Performance-Testing]
\ No newline at end of file
diff --git a/JMeter_README.md b/JMeter_README.md
new file mode 100644
index 00000000..64e2e085
--- /dev/null
+++ b/JMeter_README.md
@@ -0,0 +1,153 @@
+# Performance Testing for Topcoder Connect App
+
+## Description
+
+Topcoder Connect is a web application that makes it easy to tap into the power of crowdsourcing to get more work done faster. Connect is ideal for projects that include application design and/or development work. You can crowdsource the entire application development lifecycle or just the specific stages where you need help. Common deliverables include application wireframes, UI/UX designs, prototypes, MVPs, and production-ready apps for any kind of device—mobile, wearables, or the web.
+
+## Dependencies
+
+- Jmeter maven plugin 2.9.0
+- Maven 3.5.2
+- JDK between 8 and 11
+
+## Prerequisite
+
+- We have already included the workflow into the circleci conf file with the usual dev builds.
+
+## Directory Structure
+
+- .circleci (Circleci configuration file)
+- \src\test\jmeter - Includes the JMX file(s) and CSV data files
+- pom file
+
+### **Setup and Runtime**
+
+Add the plugin to your project: Add the plugin to the build section of your pom's project
+
+```
+
+ com.lazerycode.jmeter
+ jmeter-maven-plugin
+ 3.2.0
+
+
+
+ configuration
+
+ configure
+
+
+
+
+ jmeter-tests
+
+ jmeter
+
+
+
+
+ jmeter-check-results
+
+ results
+
+
+
+
+```
+
+This simple load test is already integrated with the current build process
+
+```
+workflows:
+ version: 2
+ Connect Project Services:
+ jobs:
+ - build:
+ context : org-global
+ - deployDev:
+ context : org-global
+ requires:
+ - build
+ filters:
+ branches:
+ only: ['develop']
+ - deployProd:
+ context : org-global
+ requires:
+ - build
+ filters:
+ branches:
+ only: ['master']
+ - Hold [Performance-Testing]:
+ type: approval
+ requires:
+ - build
+ - deployDev
+ - deployProd
+ - Connect-Performance-Testing:
+ requires:
+ - Hold [Performance-Testing]
+```
+
+- Hold [Performance-Testing] - This is the approval job we needs manual interaction.
+- It requires `build`, `deployDev` and `deployProd` jobs to run first.
+- Actual performance testing job is `Connect-Performance-Testing` and it requires `Hold [Performance-Testing]` job to finish.
+
+### **Configuration**
+
+
+
+
+This performance test is for 15 virtual users. The parameters for this test plan is as below;
+
+- Start Thread Count
+- Initial Deplay, sec (Startup Time + Hold Load For)
+- Startup Time, sec (Start Thread Count = Startup Time)
+- Hold Load For, sec
+- Shutdown Time (Next row `Initial Deplay`)
+
+**Formulas:**
+
+```
+Initial time of a record = initialtime + start up time/ramp-up time + holdtime of the previous record
+```
+
+```
+start up time/ramp-up time = Shutdown time/ramp-down time of the previous record
+```
+
+This setup is configured to run 6min with 15 UVs.
+
+**Token Details**
+
+- `audience` - https://m2m.topcoder-dev.com/
+- `grant_type` - client_credentials
+- `content-type` - application/json
+- `client_id` - jGIf2pd3f44B1jqvOai30BIKTZanYBfU
+- `client_secret` - ldzqVaVEbqhwjM5KtZ79sG8djZpAVK8Z7qieVcC3vRjI4NirgcinKSBpPwk6mYYP
+
+To extract the token we are using the variable `access_token`
+
+TO pass the `access_token` varaible globally we are using the beanshell Assertion
+
+`${__setProperty(access_token, ${access_token})};`
+
+**Random Controller**
+
+We are using Random Controller to randomize the requests sent to the server to simulate the different request.
+
+**Think Time**
+
+We are using this parameter to implement a random wait time in betweent the request to simulate the real user experience.
+
+**HTTP Requets**
+
+- Access Tabs - Simulate user accessing different tabs
+- Access Projects - Simulate user accessing different projetcs
+- Assets Library (Link Insert) - Add Links to the projects
+
+## Check the reports and data
+
+After running the job using the circleci user can view the report by clicking on the Job: `Connect-Performance-Testing` > Artifacts > `target/jmeter/reports/15UV Ultimate Thread-Group/index.html`
+
+eg: https://2728-60865675-gh.circle-artifacts.com/0/target/jmeter/reports/15UV%20Ultimate%20Thread-Group/index.html
diff --git a/README.md b/README.md
index 9302d11a..152763b1 100644
--- a/README.md
+++ b/README.md
@@ -357,6 +357,10 @@ eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlcyI6WyJhZG1pbmlzdHJhdG9yIl0sImlzcyI
```
It's been signed with the secret 'secret'. This secret should match your entry in config/local.js. You can generate your own token using https://jwt.io
+## Performance Testing
+
+- [Performance Testing Readme](README.md)
+
## Documentation
- [Projects Service Architecture](./docs/guides/architercture/architecture.md)
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 00000000..8cb902e2
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,241 @@
+
+ 4.0.0
+ com.ubikingenierie.ubikloadpack
+ jmeter-maven-plugin-demo
+ 0.0.1-SNAPSHOT
+
+ UTF-8
+
+ 2.9.0
+
+
+
+ commons-codec
+ commons-codec
+ 1.11
+
+
+ org.slf4j
+ slf4j-api
+ 1.7.25
+
+
+ org.apache.jmeter
+ ApacheJMeter_core
+ 5.1
+
+
+
+
+
+
+
+
+
+ standalone
+
+ true
+
+
+
+
+ com.lazerycode.jmeter
+ jmeter-maven-plugin
+ ${jmeter-maven-plugin.version}
+
+ true
+ 60
+ false
+
+ ${project.version}
+ 7
+ 30
+
+
+ kg.apc:jmeter-plugins-casutg:2.8
+
+
+ com.ubikingenierie.ubikloadpack:jmeter-maven-plugin-demo:${project.version}
+
+
+ org.slf4j:slf4j-nop
+ avalon-framework:*
+ org.apache.tika:*
+ excalibur-datasource:excalibur-datasource
+ excalibur-instrument:excalibur-instrument
+ excalibur-logger:excalibur-logger
+ excalibur-pool:*
+ org.beanshell:bsh:jar:2.0b5
+
+
+
+ -XX:MaxMetaspaceSize=256m
+ -Xmx1024m
+ -Xms1024m
+
+
+
+
+
+ jmeter-tests
+ verify
+
+
+
+ jmeter
+ results
+
+
+
+
+
+
+
+
+ worker
+
+
+
+ org.codehaus.groovy.maven
+ gmaven-plugin
+ 1.0
+
+
+ generate-resources
+
+ execute
+
+
+
+ project.properties["hostname"] = InetAddress.getLocalHost().getHostName()
+
+
+
+
+
+
+ com.lazerycode.jmeter
+ jmeter-maven-plugin
+ ${jmeter-maven-plugin.version}
+
+
+ true
+
+
+ kg.apc:jmeter-plugins-casutg:2.8
+
+
+ com.ubikingenierie.ubikloadpack:jmeter-maven-plugin-demo:${project.version}
+
+
+ org.slf4j:slf4j-nop
+ avalon-framework:*
+ org.apache.tika:*
+ excalibur-datasource:excalibur-datasource
+ excalibur-instrument:excalibur-instrument
+ excalibur-logger:excalibur-logger
+ excalibur-pool:*
+ org.beanshell:bsh:jar:2.0b5
+
+
+
+ -XX:MaxMetaspaceSize=256m
+ -Xmx1024m
+ -Xms1024m
+
+
+ ${hostname}
+ 3010
+
+
+
+ start-jmeter-server
+
+
+
+ remote-server
+
+ verify
+
+ false
+
+
+
+
+
+
+
+
+
+ controller
+
+
+
+ com.lazerycode.jmeter
+ jmeter-maven-plugin
+ ${jmeter-maven-plugin.version}
+
+
+ true
+
+
+ ${project.version}
+ 7
+ 30
+
+ true
+
+ kg.apc:jmeter-plugins-casutg:2.8
+
+
+ com.ubikingenierie.ubikloadpack:jmeter-maven-plugin-demo:${project.version}
+
+
+ org.slf4j:slf4j-nop
+ avalon-framework:*
+ org.apache.tika:*
+ excalibur-datasource:excalibur-datasource
+ excalibur-instrument:excalibur-instrument
+ excalibur-logger:excalibur-logger
+ excalibur-pool:*
+ org.beanshell:bsh:jar:2.0b5
+
+
+
+ -XX:MaxMetaspaceSize=256m
+ -Xmx1024m
+ -Xms1024m
+
+
+
+ ${serverList}
+ true
+
+
+
+
+ performance-test
+
+
+
+ jmeter
+ results
+
+ verify
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/jmeter/15UV Ultimate Thread-Group.jmx b/src/test/jmeter/15UV Ultimate Thread-Group.jmx
new file mode 100644
index 00000000..2135f040
--- /dev/null
+++ b/src/test/jmeter/15UV Ultimate Thread-Group.jmx
@@ -0,0 +1,357 @@
+
+
+
+
+ Check the Performance of the Connect App
+ false
+ true
+ false
+
+
+
+
+
+
+
+ Retrive the token
+ continue
+
+ false
+ 1
+
+ 1
+ 1
+ false
+
+
+ true
+
+
+
+
+
+
+ false
+ https://m2m.topcoder-dev.com/
+ =
+ true
+ audience
+
+
+ false
+ client_credentials
+ =
+ true
+ grant_type
+
+
+ false
+ application/json
+ =
+ true
+ content-type
+
+
+ false
+ jGIf2pd3f44B1jqvOai30BIKTZanYBfU
+ =
+ true
+ client_id
+
+
+ false
+ ldzqVaVEbqhwjM5KtZ79sG8djZpAVK8Z7qieVcC3vRjI4NirgcinKSBpPwk6mYYP
+ =
+ true
+ client_secret
+
+
+
+ topcoder-dev.auth0.com
+
+ https
+
+ /oauth/token
+ POST
+ true
+ false
+ true
+ false
+
+
+
+
+
+
+ Get the {access_token}
+ access_token
+ access_token
+
+
+
+
+ Set the {access_token} globally
+ ${__setProperty(access_token, ${access_token})};
+
+
+ false
+
+
+
+
+
+
+ 5
+ 0
+ 5
+ 60
+ 10
+
+
+ 10
+ 65
+ 10
+ 60
+ 10
+
+
+ 10
+ 135
+ 10
+ 120
+ 10
+
+
+ 10
+ 265
+ 10
+ 60
+ 10
+
+
+ 5
+ 335
+ 5
+ 60
+ 0
+
+
+
+ false
+ -1
+
+ Check the server is holding for 25 VU at any point
+
+Initial time of a record = initialtime + start up time/ramp-up time + holdtime of the previous record
+start up time/ramp-up time = Shutdown time/ramp-down time of the previous record
+ continue
+
+
+
+ 1
+
+
+
+ 1
+ 0
+ 0
+
+
+
+ 1000
+ 100
+
+
+
+
+
+
+
+ api.topcoder-dev.com
+
+ https
+
+ ${path}
+ GET
+ true
+ false
+ true
+ false
+
+
+
+ User accessing different tabs All Projects, Active, In Review, Reviewed, Completed, Cancelled and Paused
+
+
+
+ path.csv
+
+
+ false
+ ,
+ false
+ true
+ false
+ shareMode.all
+
+
+
+
+
+ Authorization
+ Bearer ${__property(access_token)}
+
+
+
+
+
+
+
+
+
+ api.topcoder-dev.com
+
+ https
+
+ /v5/projects/${projects}
+ GET
+ true
+ false
+ true
+ false
+
+
+
+ User accessing different projects from the list
+
+
+
+
+ projects.csv
+
+
+ false
+ ,
+ false
+ true
+ false
+ shareMode.all
+
+
+
+
+
+ Authorization
+ Bearer ${__property(access_token)}
+
+
+
+
+
+
+
+
+
+ false
+ link
+ =
+ true
+ type
+
+
+ false
+ JMeter Performance Test Link Addition
+ =
+ true
+ title
+
+
+ false
+ https://connect.topcoder-dev.com/
+ =
+ true
+ path
+
+
+
+ api.topcoder-dev.com
+
+ https
+
+ /v5/projects/${projects}/attachments
+ POST
+ true
+ false
+ true
+ false
+
+
+
+ User accessing different projects from the list
+
+
+
+
+ projects.csv
+
+
+ false
+ ,
+ false
+ true
+ false
+ shareMode.all
+
+
+
+
+
+ Authorization
+ Bearer ${__property(access_token)}
+
+
+
+
+
+
+
+ false
+
+ saveConfig
+
+
+ true
+ true
+ true
+
+ true
+ true
+ true
+ true
+ false
+ true
+ true
+ false
+ false
+ false
+ true
+ false
+ false
+ false
+ true
+ 0
+ true
+ true
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
diff --git a/src/test/jmeter/path.csv b/src/test/jmeter/path.csv
new file mode 100644
index 00000000..330442cc
--- /dev/null
+++ b/src/test/jmeter/path.csv
@@ -0,0 +1,9 @@
+path
+/v5/projects/?fields=id,name,description,members,invites,status,type,actualPrice,estimatedPrice,createdAt,updatedAt,createdBy,updatedBy,details,lastActivityAt,lastActivityUserId,version,templateId&sort=lastActivityAt+desc&perPage=20&page=1
+/v5/projects/?fields=id,name,description,members,invites,status,type,actualPrice,estimatedPrice,createdAt,updatedAt,createdBy,updatedBy,details,lastActivityAt,lastActivityUserId,version,templateId&sort=lastActivityAt+desc&perPage=20&page=1&status=in_review
+/v5/projects/?fields=id,name,description,members,invites,status,type,actualPrice,estimatedPrice,createdAt,updatedAt,createdBy,updatedBy,details,lastActivityAt,lastActivityUserId,version,templateId&sort=lastActivityAt+desc&perPage=20&page=1&status=active
+/v5/projects/?fields=id,name,description,members,invites,status,type,actualPrice,estimatedPrice,createdAt,updatedAt,createdBy,updatedBy,details,lastActivityAt,lastActivityUserId,version,templateId&sort=lastActivityAt+desc&perPage=20&page=1&status=reviewed4
+/v5/projects/?fields=id,name,description,members,invites,status,type,actualPrice,estimatedPrice,createdAt,updatedAt,createdBy,updatedBy,details,lastActivityAt,lastActivityUserId,version,templateId&sort=lastActivityAt+desc&perPage=20&page=1&status=completed
+/v5/projects/?fields=id,name,description,members,invites,status,type,actualPrice,estimatedPrice,createdAt,updatedAt,createdBy,updatedBy,details,lastActivityAt,lastActivityUserId,version,templateId&sort=lastActivityAt+desc&perPage=20&page=1&status=cancelled
+/v5/projects/?fields=id,name,description,members,invites,status,type,actualPrice,estimatedPrice,createdAt,updatedAt,createdBy,updatedBy,details,lastActivityAt,lastActivityUserId,version,templateId&sort=lastActivityAt+desc&perPage=20&page=1&status=paused
+/v5/projects/metadata/orgConfig?orgId=20000001,20000014,d6bf6bb6-457c-461c-a4d6-0a6b1a87fde9,f325869a-ab0d-47b1-af28-4e117709ca71
\ No newline at end of file
diff --git a/src/test/jmeter/projects.csv b/src/test/jmeter/projects.csv
new file mode 100644
index 00000000..1c3e75f7
--- /dev/null
+++ b/src/test/jmeter/projects.csv
@@ -0,0 +1,101 @@
+projects
+16685
+16684
+16683
+16682
+16681
+16680
+16679
+16678
+16677
+16676
+16675
+16674
+16673
+16672
+16671
+16670
+16669
+16668
+16667
+16666
+16665
+16664
+16663
+16662
+16661
+16660
+16659
+16658
+16657
+16656
+16655
+16654
+16653
+16652
+16651
+16650
+16649
+16648
+16647
+16646
+16645
+16644
+16643
+16642
+16641
+16640
+16639
+16638
+16637
+16636
+16635
+16634
+16633
+16632
+16631
+16630
+16629
+16628
+16627
+16626
+16625
+16624
+16623
+16622
+16621
+16620
+16619
+16618
+16617
+16616
+16615
+16614
+16613
+16612
+16611
+16610
+16609
+16608
+16607
+16606
+16605
+16604
+16603
+16602
+16601
+16600
+16599
+16598
+16597
+16596
+16595
+16594
+16593
+16592
+16591
+16590
+16589
+16588
+16587
+16586
\ No newline at end of file