3 # Copyright 2023-2024 Nordix Foundation.
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
18 set -o errexit # Exit on most errors
19 set -o nounset # Disallow expansion of unset variables
20 set -o pipefail # Use last non-zero exit code in a pipeline
21 #set -o xtrace # Trace logging - disabled to avoid producing gigabytes of logs
23 #############################################################################################################################
24 ################################################ F U N C T I O N S ##########################################################
25 #############################################################################################################################
27 cps_test_names=("Delete data nodes for anchor" "Delete one large node" "Batch delete 100 lists elements" "Batch delete 100 containers" "Query across anchors top element" "Delete root node" "Query across anchors ancestors" "Query across anchors leaf condition + an" "Read datatrees using openroadm root" "Read datatrees using openroadm top eleme" "Query 1 anchor leaf condition + ancestor" "Query 1 anchor top element" "Creating 33,000 books" "Replace list of 0 with 100" "Query ancestors with all descendants" "Replace 0 nodes with 100" "Writing 6400 books" "Read datatrees with all descendants" "Query 1 anchor ancestors" "Writing 400 devices" "Writing 3200 books" "Saving list of 100 devices" "Saving list of 50 devices" "Saving list of 400 devices" "Query with all descendants" "Writing 100 devices" "Writing 50 devices" "Writing 200 devices" "Read datatrees for multiple xpaths" "Saving list of 200 devices")
29 ncmp_test_name_names=("Look up CM-handles by module-set-tag")
31 JENKINS_JOB_URL="https://jenkins.nordix.org/job/onap-cps-master-performance-test-java"
33 latestBuildToRecord=""
35 latestRecordedBuild=""
36 timestampOfLatestRecordedBuild=""
38 # Get latest-completed build number from the jenkins job
39 # The number has not been plotted on the graphs yet
40 getLastCompletedBuildNumber() {
41 curl -s "${JENKINS_JOB_URL}/lastCompletedBuild/buildNumber"
44 # Get the last build number from local workspace
45 # The number has already been plotted on the graphs
46 getLastRecordedBuildNumber() {
48 local file_name="Delete root node.txt"
50 # Check if the file exists
51 if [ -f "$file_name" ]; then
52 # Get the last line from the file
53 local last_line=$(tail -n 1 "$file_name")
54 local left_side=$(echo "$last_line" | cut -d ',' -f 1)
57 echo "File '$file_name' not found in the current directory"
61 # Get all builds numbers
62 getAllBuildNumbers() {
63 curl -s "${JENKINS_JOB_URL}/api/json?tree=allBuilds\[id\]" | jq -r '.allBuilds[].id' | sort -n
66 # Get the console text from specific build of the performance job
69 consoleURL="${JENKINS_JOB_URL}/${buildToRead}/consoleText"
70 consoleText=$(curl -s "$consoleURL")
73 # Get and record the percentage (performance job result) for each test name for a build number
74 getAndRecordPerformanceJobResultForBuild() {
76 getConsoleText "$buildNumber"
77 # Loop through each text name
78 for cps_test_name in "${cps_test_names[@]}"; do
79 getAndRecordDataResults "$consoleText" "$cps_test_name" "$cps_test_name.txt" "$buildNumber"
81 for ncmp_test_name in "${ncmp_test_name_names[@]}"; do
82 getAndRecordDataResults "$consoleText" "$ncmp_test_name" "$ncmp_test_name.txt" "$buildNumber"
86 # Calculate the percentage value for a specific test and append into test data file with build number
87 getAndRecordDataResults() {
97 # Get and calculate percentage for the graph
98 if matched_line=$(echo "$consoleText" | grep "$patternToMatch"); then
99 limit_value=$(echo "$matched_line" | grep -o -P 'limit\s*\K\d+(\.\d+)?' | tr -cd '[:digit:].')
100 took_value=$(echo "$matched_line" | grep -o -P 'took\s*\K\d+(\.\d+)?' | tr -cd '[:digit:].')
101 percentage=$(echo "scale=2; $took_value * 100.00 / $limit_value" | bc)
102 new_data="$percentage"
105 # Record result into related test data file
107 lastLine=$(tail -n 1 "$dataFile")
108 newLine="$buildNumber,$new_data"
109 if [ -z "$new_data" ]; then
110 # No data found for this build probably the build failed
111 echo "$buildNumber,0" >>"$dataFile"
112 recordLatestRecordedBuild "$buildNumber"
113 elif [ "$newLine" == "$lastLine" ]; then
114 # Data already exists
115 recordLatestRecordedBuild "$buildNumber"
117 # New data added into the file
118 echo "$buildNumber,$new_data" >>"$dataFile"
119 recordLatestRecordedBuild "$buildNumber"
123 # Save the latest recorded build number with date and time
124 recordLatestRecordedBuild() {
125 latestBuildToRecord="$1"
126 timestampOfLatestRecordedBuild=$(curl -s "${JENKINS_JOB_URL}/${latestBuildToRecord}/api/json?tree=timestamp" | jq -r '.timestamp')
127 formattedTimestampOfLatestRecordedBuild=$(date -d "@$((timestampOfLatestRecordedBuild / 1000))" "+%B %e, %Y at %H:%M")
128 latestRecordedBuild=$latestBuildToRecord
131 # Plot the image (graph) in png format
133 dataFile="$1" # Get the input file name from the function parameter
136 # Create a temporary Gnuplot script
137 cat <<EOT >gnuplot_script.gp
138 set datafile separator ","
139 set terminal pngcairo size 1500,600
140 set output "${chartFileName}"
142 set ylabel "Percentage of limit %"
143 set yrange [0 < * < 80 : 120 < *]
145 plot '$dataFile' using (column(0)):2:xtic(sprintf("%d", column(1))) with linespoints title "measured", \
146 100 with lines linestyle 2 title "100% limit"
149 # Run the temporary Gnuplot script
150 gnuplot gnuplot_script.gp
152 # Remove the temporary Gnuplot script
156 # Builds index.html file (main page)
157 buildMainPageHtmlReport() {
158 cat <<EOT >"index.html"
162 <title>Performance Review</title>
165 <h1 style="text-align: center;">Performance Review</h1>
166 <h4>Last updated for performance job build no. $latestRecordedBuild on $formattedTimestampOfLatestRecordedBuild</h4>
167 <p>The performance tests job runs every two hours, providing performance metrics. The following graphs update at 04:15 UTC.</p>
168 <p>Successful performance tests job build adds new data, but even if a build fails, existing data is retained.</p>
169 <p>Updates occur whenever new successful data is available.</p>
171 <table align="center">
174 # Loop through the test names and chart file names to generate HTML rows for CPS
175 for cps_test_name in "${cps_test_names[@]}"; do
176 cat <<EOF >>index.html
177 <tr> <!-- Row for $cps_test_name -->
178 <td align="center" style="padding: 10px;">
179 <figcaption>"$cps_test_name (CPS)"</figcaption>
180 <img src="$cps_test_name.png" width="750" height="300">
186 # Loop through the test names and chart file names to generate HTML rows for NCMP
187 for ncmp_test_name in "${ncmp_test_name_names[@]}"; do
188 cat <<EOF >>index.html
189 <tr> <!-- Row for $ncmp_test_name -->
190 <td align="center" style="padding: 10px;">
191 <figcaption>"$ncmp_test_name (NCMP)"</figcaption>
192 <img src="$ncmp_test_name.png" width="750" height="300">
198 # Close the HTML file
199 cat <<EOT >>index.html
206 # Builds sub-HTML pages
207 buildSubPageHtmlReport() {
211 cat <<EOT >"$outputFile"
215 <title>$reportTitle</title>
218 <h1>$reportTitle</h1>
219 <h4>Last updated for performance job build no. $latestRecordedBuild on $formattedTimestampOfLatestRecordedBuild</h4>
220 <img src="$chartFileName" alt="Graph Image">
226 #############################################################################################################################
227 ################################################ M A I N ####################################################################
228 #############################################################################################################################
230 # Install dependencies
231 sudo apt-get install -y bc gnuplot jq
233 # Download data from CPS performance Jenkins job
235 if [ -z "$(ls -A)" ]; then
236 # If workspace is empty, pull data from all previous performance job runs
237 for buildNumber in $(getAllBuildNumbers); do
238 getAndRecordPerformanceJobResultForBuild "$buildNumber"
241 # Append new data from latest jobs run
242 lastCompletedBuildNumber=$(getLastCompletedBuildNumber)
243 lastRecordedBuildNumber=$(getLastRecordedBuildNumber)
244 # Check if last completed build number is greater than last recorded build number
245 if [ "$lastCompletedBuildNumber" -gt "$lastRecordedBuildNumber" ]; then
246 for ((i = lastRecordedBuildNumber + 1; i <= lastCompletedBuildNumber; i++)); do
247 getAndRecordPerformanceJobResultForBuild "$i"
250 echo "No new builds to process."
254 # Plot image (graphs) files in png format
255 for cps_test_name in "${cps_test_names[@]}"; do
256 buildPlotImage "$cps_test_name.txt" "$cps_test_name.png"
258 for ncmp_test_name in "${ncmp_test_name_names[@]}"; do
259 buildPlotImage "$ncmp_test_name.txt" "$ncmp_test_name.png"
262 # Build the summary(index.html) page
263 buildMainPageHtmlReport
265 # Build individual html page reports for each test
266 for cps_test_name in "${cps_test_names[@]}"; do
267 buildSubPageHtmlReport "$cps_test_name.png" "$cps_test_name" "$cps_test_name.html"
269 for ncmp_test_name in "${ncmp_test_name_names[@]}"; do
270 buildSubPageHtmlReport "$ncmp_test_name.png" "$ncmp_test_name" "$ncmp_test_name.html"