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