Merge "PAP S3P documentation"
[policy/parent.git] / docs / development / devtools / apex-s3p.rst
index 6143e16..6a3be84 100644 (file)
 Policy APEX PDP component
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Setting up Stability Tests in APEX
-++++++++++++++++++++++++++++++++++
+Both the Stability and the Performance tests were executed in a full ONAP OOM deployment in Nordix lab.
 
-Introduction
-------------
-
-The 72 hour Stability Test for apex-pdp has the goal of introducing a steady flow of transactions initiated from a test client server running JMeter. The pdp is configured to start a rest server inside it and take input from rest clients (JMeter) and send back output to the rest clients (JMeter).
-
-The input events will be submitted through rest interface of apex-pdp and the results are verified using the rest responses coming out from apex-pdp.
-
-The test will be performed in a multi-threaded environment where 20 threads running in JMeter will keep sending events to apex-pdp in every 500 milliseconds for the duration of 72 hours.
-
-Setup details
--------------
-
-The stability test is performed on VM's running in OpenStack cloud environment. There are 2 seperate VM's, one for running apex pdp & other one for running JMeter to simulate steady flow of transactions.
-
-**OpenStack environment details**
-
-Version: Mitaka
-
-**apex-pdp VM details**
-
-OS:Ubuntu 18.04 LTS
-
-CPU: 4 core
-
-RAM: 4 GB
-
-HardDisk: 40 GB
-
-Docker Version: 19.03.8, build afacb8b7f0
-
-Java: openjdk version "11.0.7"
-
-**JMeter VM details**
-
-OS: Ubuntu 18.04 LTS
-
-CPU: 4 core
-
-RAM: 4 GB
-
-HardDisk: 40 GB
-
-Java: openjdk version "11.0.7"
-
-JMeter: 5.2.1
-
-Install JMeter in virtual machine
----------------------------------
-
-Make the etc/hosts entries
-
-.. code-block:: bash
-
-    echo $(hostname -I | cut -d\  -f1) $(hostname) | sudo tee -a /etc/hosts
-
-Make the DNS entries
-
-.. code-block:: bash
-
-    echo "nameserver <PrimaryDNSIPIP>" >> sudo /etc/resolvconf/resolv.conf.d/head
+Setup Details
++++++++++++++
 
-    echo "nameserver <SecondaryDNSIP>" >> sudo /etc/resolvconf/resolv.conf.d/head
+Deploying ONAP using OOM
+------------------------
 
-    resolvconf -u
+APEX-PDP along with all policy components are deployed as part of a full ONAP OOM deployment.
+At a minimum, the following ONAP components are needed: policy, mariadb-galera, aai, cassandra, aaf, and dmaap.
 
-Update the ubuntu software installer
+Before deploying, the values.yaml files are changed to use NodePort instead of ClusterIP for policy-api,
+policy-pap, and policy-apex-pdp, so that they are accessible from jmeter::
 
-.. code-block:: bash
-
-    apt-get update
-
-Check & Install Java
-
-.. code-block:: bash
+  policy-apex-pdp              NodePort    10.43.131.43    <none>        6969:31739/TCP
+  policy-api                   NodePort    10.43.67.153    <none>        6969:30430/TCP
+  policy-pap                   NodePort    10.43.200.57    <none>        6969:30585/TCP
 
-    apt-get install -y openjdk-11-jdk
-
-    java -version
-
-Download & install JMeter
-
-.. code-block:: bash
+The node ports (31739, 30430 and 30585 above) are used in JMeter.
+The HOSTNAMEs for JMeter are set to the IPs returned by running "kubectl get node -o wide"
+and to find the applications for each node by running "kubectl describe node <node-name>".
 
-    mkdir jMeter
+Set up policy-models-simulator
+------------------------------
 
+Policy-models-simulator is deployed to use CDS and DMaaP simulators during policy execution.
+    Simulator configurations used are available in apex-pdp repository:
+      testsuites/apex-pdp-stability/src/main/resources/simulatorConfig/
 
-    cd jMeter
+It is run as a docker image from a node accessible to the kubernetes cluster::
 
+  docker run -d --rm --publish 6680:6680 --publish 31054:3905 \
+    --volume "apex-pdp/testsuites/apex-pdp-stability/src/main/resources/simulatorConfig:/opt/app/policy/simulators/etc/mounted" \
+    nexus3.onap.org:10001/onap/policy-models-simulator:2.7-SNAPSHOT-latest
 
-    wget http://mirrors.whoishostingthis.com/apache//jmeter/binaries/apache-jmeter-5.2.1.zip
-
-
-    unzip apache-jmeter-5.2.1.zip
-
-Install apex-pdp in virtual machine
------------------------------------
-
-We will be running apex-pdp as docker container. So we need to first install docker and then create the container hosting apex-pdp by pulling the image from ONAP repository.
-
-**Docker Installation**
-
-1. Make the etc/hosts entries
-
-.. code-block:: bash
+The published ports 6680 and 31054 are used in JMeter for CDS and DMaaP simulators.
 
-    echo $(hostname -I | cut -d\  -f1) $(hostname) | sudo tee -a /etc/hosts
-
-2. Make the DNS entries
-
-.. code-block:: bash
-
-    echo "nameserver <PrimaryDNSIPIP>" >> sudo /etc/resolvconf/resolv.conf.d/head
-    echo "nameserver <SecondaryDNSIP>" >> sudo /etc/resolvconf/resolv.conf.d/head
-    resolvconf -u
-
-3. Update the ubuntu software installer
-
-.. code-block:: bash
-
-    apt-get update
-
-4. Check and Install Java
-
-.. code-block:: bash
-
-    apt-get install -y openjdk-11-jdk
-    java -version
-
-Ensure that the Java version that is executing is OpenJDK version 8
-
-5. Check and install docker
-
-.. code-block:: bash
-
-    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
-    sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
-    sudo apt-get update
-    sudo apt-cache policy docker-ce
-    sudo apt-get install -y docker-ce
-    sudo systemctl enable docker
-    sudo systemctl start docker
-    sudo usermod -aG docker <your user id>
-
-6. Logout and re-login to ensure the ``usermod`` command takes effective
-
-7. Check the status of the Docker service and ensure it is running correctly
-
-.. code-block:: bash
-
-    docker ps
-
-**Install apex-pdp**
-
-Run the below command to create the container hosting apex-pdp by pulling the image from ONAP repository.
-
-.. code-block:: bash
-
-    docker run -d --name apex -p 12561:12561 -p 23324:23324 -p 9911:9911 nexus3.onap.org:10001/onap/policy-apex-pdp:2.3.1 /bin/bash -c "/opt/app/policy/apex-pdp/bin/apexApps.sh jmx-test -c /opt/app/policy/apex-pdp/examples/config/SampleDomain/RESTServerJsonEvent.json"
-    docker ps
-
-Note: If you observe that requests from JMeter client is failing due to timeout, then modify the "RESTServerJsonEvent.json" mentioned in the above command and increase the "synchronousTimeout" property as per needed.
-
-Install & Configure VisualVM
+Creation of VNF & PNF in AAI
 ----------------------------
 
-VisualVM needs to be installed in the virtual machine having apex-pdp. It will be used to monitor CPU, Memory, GC for apex-pdp while stability test is running.
+In order for APEX-PDP engine to fetch the resource details from AAI during runtime execution, we need to create dummy
+VNF & PNF entities in AAI. In a real control loop flow, the entities in AAI will be either created during orchestration
+phase or provisioned in AAI separately.
 
-Install visualVM
+Download & execute the steps in postman collection for creating the entities along with it’s dependencies.
+The steps needs to be performed sequentially one after another. And no input is required from user.
 
-.. code-block:: bash
-
-    sudo apt-get install visualvm
+:download:`Create VNF & PNF in AAI for Apex S3P  <postman/create-vnf-pnf-aai-for-apex-s3p.postman_collection.json>`
 
-Login to VM using graphical interface in separate terminal window.
-
-.. code-block:: bash
+Make sure to skip the delete VNF & PNF steps.
 
-    ssh -X <user>@<VM-IP-ADDRESS>
-
-Open visualVM
+JMeter Tests
+------------
 
-.. code-block:: bash
+Two APEX policies are executed in the APEX-PDP engine, and are triggered by multiple threads during the tests.
+Both tests were run via jMeter.
 
-    visualvm &
+    Stability test script is available in apex-pdp repository:
+      testsuites/apex-pdp-stability/src/main/resources/apexPdpStabilityTestPlan.jmx
 
-Connect to apex-pdp JVM's JMX agent
-1. Right click on "Local" in the left panel of the screen and select "Add Local JMX Connection..."
-2. Enter localhost:9911 for "Connection", and click OK
-3. Double click on the newly added nodes under "Local" to start monitoring CPU, Memory & GC.
+    Performance test script is available in apex-pdp repository:
+      testsuites/performance/performance-benchmark-test/src/main/resources/apexPdpPerformanceTestPlan.jmx
 
-Sample Screenshot of visualVM
+.. Note::
+   Policy executions are validated in a stricter fashion during the tests.
+   There are test cases where up to 80 events are expected on the DMaaP topic.
+   DMaaP simulator is used to keep it simple and avoid any message pickup timing related issues.
 
-.. image:: images/stability-visualvm1.PNG
-.. image:: images/stability-visualvm2.PNG
+Stability Test of APEX-PDP
+++++++++++++++++++++++++++
 
 Test Plan
 ---------
 
-The 72 hours stability test will run the following steps in 20 threaded loop.
-
-- **Send Input Event** - sends an input message to rest interface of apex-pdp.
-- **Assert Response Code** - assert the response code coming from apex-pdp.
-- **Assert Response Message** - assert the response message coming from apex-pdp.
-
-The following steps can be used to configure the parameters of test plan.
-
-- **HTTP Header Manager** - used to store headers which will be used for making HTTP requests.
-- **HTTP Request Defaults** -  used to store HTTP request details like Server Name or IP, Port, Protocol etc.
-- **User Defined Variables** -  used to store following user defined parameters.
-
-==================  ============================================================================  ============================
-**Name**            **Description**                                                               **Default Value**
-==================  ============================================================================  ============================
-wait                Wait time after each request (in milliseconds)                                500
-threads             Number of threads to run test cases in parallel.                              20
-threadsTimeOutInMs  Synchronization timer for threads running in parallel (in milliseconds).      5000
-==================  ============================================================================  ============================
-
-
-Download and update the jmx file presented in the apex-pdp git repository - `jmx file path <https://gerrit.onap.org/r/gitweb?p=policy/apex-pdp.git;a=tree;f=testsuites/apex-pdp-stability/src/main/resources;h=99d373033a190a690d4e05012bc3a656cae7bc3f;hb=refs/heads/master>`_.
-
-- HTTPSampler.domain - The ip address of VM which the apex container is running
-- HTTPSampler.port - The  listening port, here is 23324
-- ThreadGroup.druation - Set the duration to 72 hours (in seconds)
+The 72 hours stability test ran the following steps.
 
-Use the CLI mode to start the test
+Setup Phase
+"""""""""""
 
-.. code-block:: bash
-
-    ./jmeter.sh -n -t ~/apexPdpStabilityTestPlan.jmx -Jusers=1 -l ~/stability.log
+Policies are created and deployed to APEX-PDP during this phase. Only one thread is in action and this step is done only once.
 
-Stability Test Result
----------------------
+- **Create Policy onap.policies.apex.Simplecontrolloop** - creates the first APEX policy using policy/api component.
+      This is a sample policy used for PNF testing.
+- **Create Policy onap.policies.apex.Example** - creates the second APEX policy using policy/api component.
+      This is a sample policy used for VNF testing.
+- **Deploy Policies** - Deploy both the policies created to APEX-PDP using policy/pap component
 
-**Summary**
+Main Phase
+""""""""""
 
-Stability test plan was triggered for 72 hours injecting input events to apex-pdp from 20 client threads running in JMeter.
+Once the policies are created and deployed to APEX-PDP by the setup thread, five threads execute the below tests for 72 hours.
 
-After the test stop, we can generate a HTML test report via command
+- **Healthcheck** - checks the health status of APEX-PDP
+- **Prometheus Metrics** - checks that APEX-PDP is exposing prometheus metrics
+- **Test Simplecontrolloop policy success case** - Send a trigger event to *unauthenticated.DCAE_CL_OUTPUT* DMaaP topic.
+    If the policy execution is successful, 3 different notification events are sent to *APEX-CL-MGT* topic by each one of the 5 threads.
+    So, it is checked if 15 notification messages are received in total on *APEX-CL-MGT* topic with the relevant messages.
+- **Test Simplecontrolloop policy failure case** - Send a trigger event with invalid pnfName to *unauthenticated.DCAE_CL_OUTPUT* DMaaP topic.
+    The policy execution is expected to fail due to AAI failure response. 2 notification events are expected on *APEX-CL-MGT* topic by a thread in this case.
+    It is checked if 10 notification messages are received in total on *APEX-CL-MGT* topic with the relevant messages.
+- **Test Example policy success case** - Send a trigger event to *unauthenticated.DCAE_POLICY_EXAMPLE_OUTPUT* DMaaP topic.
+    If the policy execution is successful, 4 different notification events are sent to *APEX-CL-MGT* topic by each one of the 5 threads.
+    So, it is checked if 20 notification messages are received in total on *APEX-CL-MGT* topic with the relevant messages.
+- **Test Example policy failure case** - Send a trigger event with invalid vnfName to *unauthenticated.DCAE_POLICY_EXAMPLE_OUTPUT* DMaaP topic.
+    The policy execution is expected to fail due to AAI failure response. 2 notification events are expected on *APEX-CL-MGT* topic by a thread in this case.
+    So, it is checked if 10 notification messages are received in total on *APEX-CL-MGT* topic with the relevant messages.
+- **Clean up DMaaP notification topic** - DMaaP notification topic which is *APEX-CL-MGT* is cleaned up after each test to make sure that one failure doesn't lead to cascading errors.
 
-.. code-block:: bash
 
-    ~/jMeter/apache-jmeter-5.2.1/bin/jmeter -g stability.log -o ./result/
+Teardown Phase
+""""""""""""""
 
-==============================================  ===================================================  ================================  =============  ============
-**Number of Client Threads running in JMeter**  **Number of Server Threads running in Apex engine**  **Total number of input events**  **Success %**  **Error %**
-==============================================  ===================================================  ================================  =============  ============
-20                                              4                                                    8594220                           100%           0%
-==============================================  ===================================================  ================================  =============  ============
+Policies are undeployed from APEX-PDP and deleted during this phase.
+Only one thread is in action and this step is done only once after the Main phase is complete.
 
-.. image:: images/stability-jmeter.PNG
+- **Undeploy Policies** - Undeploy both the policies from APEX-PDP using policy/pap component
+- **Delete Policy onap.policies.apex.Simplecontrolloop** - delete the first APEX policy using policy/api component.
+- **Delete Policy onap.policies.apex.Example** - delete the second APEX policy also using policy/api component.
 
-:download:`result.zip <zip/frankfurt/apex_s3p_result.tar.gz>`
+Test Configuration
+------------------
 
+The following steps can be used to configure the parameters of test plan.
 
-Frankfurt release
-^^^^^^^^^^^^^^^^^^
-
-The 72 hour Stability Test for apex-pdp has the goal of introducing a steady flow of transactions using jMeter.
-
-The input event will be submitted through the rest interface of DMaaP , which then triggers a grpc request to CDS. Based on the response, another DMaaP event is triggered.
-
-This test will be performed in an OOM deployment setup. The test will be performed in a multi-threaded environment where 5 threads running in JMeter will keep sending events for the duration of 72 hours.
-
-Test Plan Frankfurt release
----------------------------
-
-The 72 hours stability test will run the following steps in a 5 threaded loop.
-
-- **Create Policy** - creates a policy using the policy/api component
-- **Deploy Policy** - deploys the policy in the existing PdpGroup
-- **Check Health** - checks the health status of apex
-- **Send Input Event** - trigger 'unauthenticated.DCAE_CL_OUTPUT' event of DMaaP.
-- **Get Output Event Response** - check for the triggered output event.
-- **Undeploy Policy** - undeploys the policy from PdpGroup
-- **Delete Policy** - deletes the policy using the policy/api component
-
-The following steps can be used to configure the parameters of the test plan.
-
+- **HTTP Authorization Manager** - used to store user/password authentication details.
 - **HTTP Header Manager** - used to store headers which will be used for making HTTP requests.
-- **HTTP Request Defaults** -  used to store HTTP request details like Server Name or IP, Port, Protocol etc.
-- **User Defined Variables** -  used to store the following user defined parameters:
-
-==================  ============================================================================  ============================
-**Name**            **Description**                                                               **Default Value**
-==================  ============================================================================  ============================
-wait                Wait time after each request (in milliseconds)                                120000
-threads             Number of threads to run test cases in parallel.                              5
-threadsTimeOutInMs  Synchronization timer for threads running in parallel (in milliseconds).      150000
-==================  ============================================================================  ============================
+- **User Defined Variables** - used to store following user defined parameters.
+
+===================  ===============================================================================
+ **Name**            **Description**
+===================  ===============================================================================
+ HOSTNAME            IP Address or host name to access the components
+ PAP_PORT            Port number of PAP for making REST API calls such as deploy/undeploy of policy
+ API_PORT            Port number of API for making REST API calls such as create/delete of policy
+ APEX_PORT           Port number of APEX for making REST API calls such as healthcheck/metrics
+ SIM_HOST            IP Address or hostname running policy-models-simulator
+ DMAAP_PORT          Port number of DMaaP simulator for making REST API calls such as reading notification events
+ CDS_PORT            Port number of CDS simulator
+ wait                Wait time if required after a request (in milliseconds)
+ threads             Number of threads to run test cases in parallel
+ threadsTimeOutInMs  Synchronization timer for threads running in parallel (in milliseconds)
+===================  ===============================================================================
+
+Run Test
+--------
+
+The test was run in the background via "nohup", to prevent it from being interrupted:
 
+.. code-block:: bash
 
-Download and update the jmx file presented in the apex-pdp git repository - `jmx file path <https://gerrit.onap.org/r/gitweb?p=policy/apex-pdp.git;a=tree;f=testsuites/apex-pdp-stability/src/main/resources;h=99d373033a190a690d4e05012bc3a656cae7bc3f;hb=refs/heads/master>`_.
+    nohup ./apache-jmeter-5.4.3/bin/jmeter.sh -n -t apexPdpStabilityTestPlan.jmx -l stabilityTestResults.jtl
 
-- HTTPSampler.domain - The ip address of the VM in which the apex container is running
-- HTTPSampler.port - The  listening port, here is 23324
-- ThreadGroup.druation - Set the duration to 72 hours (in seconds)
+Test Results
+------------
 
-Use the CLI mode to start the test
+**Summary**
 
-.. code-block:: bash
+Stability test plan was triggered for 72 hours. There were no failures during the 72 hours test.
 
-    ./jmeter.sh -n -t ~/apexPdpStabilityTestPlan.jmx -Jusers=1 -l ~/stability.log
 
+**Test Statistics**
 
-Stability Test Results Frankfurt release
------------------------------------------
+=======================  =================  ==================  ==================================
+**Total # of requests**  **Success %**      **Error %**         **Average time taken per request**
+=======================  =================  ==================  ==================================
+430397                    100 %             0.00 %              151.694 ms
+=======================  =================  ==================  ==================================
 
-The stability test plan was triggered for 72 hours, injecting input events to apex-pdp from 5 client threads running in JMeter.
+.. Note::
 
-After the test stops, we can generate an HTML test report via the command:
+   There were no failures during the 72 hours test.
 
-.. code-block:: bash
+**JMeter Screenshot**
 
-    ~/jMeter/apache-jmeter-5.2.1/bin/jmeter -g stability.log -o ./result/
+.. image:: apex-s3p-results/apex_stability_jmeter_results.png
 
-==============================================  ===================================================  ================================  =============  ============
-**Number of Client Threads running in JMeter**  **Number of Server Threads running in Apex engine**  **Total number of input events**  **Success %**  **Error %**
-==============================================  ===================================================  ================================  =============  ============
-5                                                4                                                    26766                             100%           0%
-==============================================  ===================================================  ================================  =============  ============
+**Memory and CPU usage**
 
-**VisualVM Screenshot**
+The memory and CPU usage can be monitored by running "top" command in the APEX-PDP pod.
+A snapshot is taken before and after test execution to monitor the changes in resource utilization.
+Prometheus metrics is also collected before and after the test execution.
 
-.. image:: images/frankfurt/apex_s3p_vm-1.png
-.. image:: images/frankfurt/apex_s3p_vm-2.png
+Memory and CPU usage before test execution:
 
-**JMeter Screenshot**
+.. image:: apex-s3p-results/apex_top_before_72h.png
 
-.. image:: images/frankfurt/apex_s3p_jm-1.png
-.. image:: images/frankfurt/apex_s3p_jm-2.png
+:download:`Prometheus metrics before 72h test  <apex-s3p-results/apex_metrics_before_72h.txt>`
 
-:download:`result.zip <zip/frankfurt/apex_s3p_result.tar.gz>`
+Memory and CPU usage after test execution:
 
-Setting up Performance Tests in APEX
-++++++++++++++++++++++++++++++++++++
+.. image:: apex-s3p-results/apex_top_after_72h.png
 
-The apex-pdp has built in support for performance testing. A special performance testing REST server is available in the code base for performance testing.
-It is in the module `performance-benchmark-test <https://github.com/onap/policy-apex-pdp/tree/master/testsuites/performance/performance-benchmark-test>`_.
-To execute a benchmark test, you start the REST server, and then configure and run APEX against the server.
-There are example configurations for running tests in the `resources of this module <https://github.com/onap/policy-apex-pdp/tree/master/testsuites/performance/performance-benchmark-test/src/main/resources/examples/benchmark>`_.
+:download:`Prometheus metrics after 72h test  <apex-s3p-results/apex_metrics_after_72h.txt>`
 
-In order to run the test for 72 hours, set the batch count in the `EventGeneratorConfig.json <https://github.com/onap/policy-apex-pdp/blob/master/testsuites/performance/performance-benchmark-test/src/main/resources/examples/benchmark/EventGeneratorConfig.json>`_ file to zero, which causes the REST server to generate batches forever.
+Performance Test of APEX-PDP
+++++++++++++++++++++++++++++
 
-Here is an example of how to do this:
+Introduction
+------------
 
-1. Clone and build the apex-pdp git repo
+Performance test of APEX-PDP is done similar to the stability test, but in a more extreme manner using higher thread count.
 
-2. Go into the performance-benchmark-test module and run the REST server
+Setup Details
+-------------
 
-.. code-block:: bash
+The performance test is performed on a similar setup as Stability test.
 
-    cd testsuites/performance/performance-benchmark-test
-    mvn exec:java -Dexec.mainClass="org.onap.policy.apex.testsuites.performance.benchmark.eventgenerator.EventGenerator" -Dexec.args="-c  src/main/resources/examples/benchmark/EventGeneratorConfig.json"
 
-3. Separately, create a local directory and unzip the APEX tarball
+Test Plan
+---------
 
-.. code-block:: bash
+Performance test plan is the same as the stability test plan above except for the few differences listed below.
 
-    mkdir apex
-    cd apex
-    tar zxvf ~/git/onap/policy/apex-pdp/packages/apex-pdp-package-full/target/*gz
+- Increase the number of threads used in the Main Phase from 5 to 20.
+- Reduce the test time to 2 hours.
 
-4. Run APEX with a configuration that runs against the benchmark REST server, select the configuration that is appropriate for the number of threads for the number of cores on the host on which APEX is running. For example on a 32 core machine, select the "32" configuration, on an 8 core machine, select the "08" configuration.
+Run Test
+--------
 
 .. code-block:: bash
 
-    bin/apexApps.sh engine -c ~/git/onap/policy/apex-pdp/testsuites/performance/performance-benchmark-test/src/main/resources/examples/benchmark/Javascript64.json
-
-5. To get the test results, Issue the following command using CURL or from a browser(also can store the result into a file by setting outfile in the `EventGeneratorConfig.json <https://github.com/onap/policy-apex-pdp/blob/master/testsuites/performance/performance-benchmark-test/src/main/resources/examples/benchmark/EventGeneratorConfig.json>`_ file, statistics would be written into this file after event generator terminated)
+    nohup ./apache-jmeter-5.4.3/bin/jmeter.sh -n -t apexPdpPerformanceTestPlan.jmx -l perftestresults.jtl
 
-.. code-block:: bash
 
-    curl http://localhost:32801/EventGenerator/Stats
+Test Results
+------------
 
-The results are similar to those below:
+Test results are shown as below.
 
-:download:`Example APEX performance metrics <json/example-apex-perf.json>`
+**Test Statistics**
 
-Performance Test Result Frankfurt
----------------------------------
+=======================  =================  ==================  ==================================
+**Total # of requests**  **Success %**      **Error %**         **Average time taken per request**
+=======================  =================  ==================  ==================================
+47567                    100 %              0.00 %              163.841 ms
+=======================  =================  ==================  ==================================
 
-**Summary**
+**JMeter Screenshot**
 
-Performance test was triggered for 2 hours on a 4 core, 4GB RAM virtual machine.
+.. image:: apex-s3p-results/apex_perf_jmeter_results.png
 
-**Test Statistics**
+Summary
++++++++
 
-:download:`Attached result log <json/frankfurt-apex-perf.json>`
-
-===============  =============  =================  ==============  =====================  ==================  =============  ===========
-**batchNumber**  **batchSize**  **eventsNotSent**  **eventsSent**  **eventsNotReceived**  **eventsReceived**  **Success %**  **Error %**
-===============  =============  =================  ==============  =====================  ==================  =============  ===========
--1               431250         0                  431250          0                      431250              100 %          0 %
-===============  =============  =================  ==============  =====================  ==================  =============  ===========
-
-========================  =========================  ========================
-**averageRoundTripNano**  **shortestRoundTripNano**  **longestRoundTripNano**
-========================  =========================  ========================
-148965724                 20169907                   429339393
-========================  =========================  ========================
-
-============================  =============================  ============================
-**averageApexExecutionNano**  **shortestApexExecutionNano**  **longestApexExecutionNano**
-============================  =============================  ============================
-62451899                      3901010                        354528579
-============================  =============================  ============================
+Multiple policies were executed in a multi-threaded fashion for both stability and performance tests.
+Both tests ran smoothly without any issues.