97058588969d2d6b115853c7bd6fbf3359ef7391
[infra/cicd.git] / jjb / onap / cps / prepare-performance-tests-data.sh
1 #!/bin/bash
2 #
3 # Copyright 2023-2024 Nordix Foundation.
4 #
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
8 #
9 #     http://www.apache.org/licenses/LICENSE-2.0
10 #
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.
16 #
17
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
22
23 #############################################################################################################################
24 ################################################ F U N C T I O N S ##########################################################
25 #############################################################################################################################
26
27 create_data="create_performance_data.txt"
28 read_data="read_performance_data.txt"
29 update_data="update_performance_data.txt"
30 delete_data="delete_performance_data.txt"
31
32 # Data files headers
33 create_data_title_1="Writing 400 devices"
34 read_data_title_1="Read datatrees using openroadm root"
35 update_data_title_1="Replace 100 with new leaf values"
36 delete_data_title_1="Batch delete 100 containers"
37
38 # Text patterns to match in console log
39 create_pattern="^.*Writing 400 devices.*"
40 read_pattern="^.*Read datatrees using openroadm root.*"
41 update_pattern="^.*Replace 100 with new leaf values.*"
42 delete_pattern="^.*Batch delete 100 containers.*"
43
44 JENKINS_JOB_URL="https://jenkins.nordix.org/job/onap-cps-master-performance-test-java"
45
46 # Get latest build
47 getLatestBuildId() {
48   curl -s "${JENKINS_JOB_URL}/lastBuild/buildNumber"
49 }
50
51 # Get all builds numbers
52 getAllBuildIds() {
53   curl -s "${JENKINS_JOB_URL}/api/json?tree=allBuilds\[id\]" | jq -r '.allBuilds[].id' | sort -n
54 }
55
56 latestBuildToRecord=""
57 consoleText=""
58 latestRecordedBuild=""
59 timestampOfLatestRecordedBuild=""
60
61 # Get the console text from specific build of the performance job
62 getConsoleText() {
63   buildToRead=$1
64   consoleURL="${JENKINS_JOB_URL}/${buildToRead}/consoleText"
65   consoleText=$(curl -s "$consoleURL")
66 }
67
68 getAndRecordDataResults() {
69   consoleText=$1
70   patternToMatch=$2
71   dataFile=$3
72   buildNumber=$4
73   new_data=""
74   matched_line=""
75   limit_value=""
76   took_value=""
77
78   # Get and calculate data for plot
79   if matched_line=$(echo "$consoleText" | grep -o -P "$patternToMatch"); then
80     limit_value=$(echo "$matched_line" | grep -o -P 'limit\s*\K\d+(\.\d+)?' | tr -cd '[:digit:].')
81     took_value=$(echo "$matched_line" | grep -o -P 'took\s*\K\d+(\.\d+)?' | tr -cd '[:digit:].')
82     percentage=$(echo "scale=2; $took_value * 100.00 / $limit_value" | bc)
83     new_data="$percentage"
84   fi
85
86   # Record result
87   touch "$dataFile"
88   lastLine=$(tail -n 1 "$dataFile")
89   newLine="$buildNumber,$new_data"
90   if [ -z "$new_data" ]; then
91     # No data found for this build
92     echo "$buildNumber,0" >>"$dataFile"
93     recordLatestRecordedBuild "$buildNumber"
94   elif [ "$newLine" == "$lastLine" ]; then
95     # Data already exists
96     recordLatestRecordedBuild "$buildNumber"
97   else
98     # New data added
99     echo "$buildNumber,$new_data" >>"$dataFile"
100     recordLatestRecordedBuild "$buildNumber"
101   fi
102 }
103
104 recordLatestRecordedBuild() {
105   latestBuildToRecord="$1"
106   timestampOfLatestRecordedBuild=$(curl -s "${JENKINS_JOB_URL}/${latestBuildToRecord}/api/json?tree=timestamp" | jq -r '.timestamp')
107   formattedTimestampOfLatestRecordedBuild=$(date -d "@$((timestampOfLatestRecordedBuild / 1000))" "+%B %e, %Y at %H:%M")
108   latestRecordedBuild=$latestBuildToRecord
109 }
110
111 buildPlotImage() {
112   dataFile="$1" # Get the input file name from the function parameter
113   chartFileName="$2"
114
115   # Create a temporary Gnuplot script
116   cat <<EOT >gnuplot_script.gp
117 set datafile separator ","
118 set terminal pngcairo size 1500,600
119 set output "${chartFileName}"
120 set xlabel "Build"
121 set ylabel "Percentage of limit %"
122 set yrange [0 < * < 80 : 120 < *]
123 set xtics rotate
124 plot '$dataFile' using (column(0)):2:xtic(sprintf("%d", column(1))) with linespoints title "measured", \
125      100 with lines linestyle 2 title "100% limit"
126 EOT
127
128   # Run the Gnuplot script
129   gnuplot gnuplot_script.gp
130
131   # Remove the temporary script
132   rm gnuplot_script.gp
133 }
134
135 buildHTMLReport() {
136
137   chartTitle1="$1" # i.e Get the chart file name as the first parameter
138   chartFileName1="$2"
139
140   chartTitle2="$3"
141   chartFileName2="$4"
142
143   chartTitle3="$5"
144   chartFileName3="$6"
145
146   chartTitle4="$7"
147   chartFileName4="$8"
148
149   reportTitle="$9" # i.e Get the report title as the ninth parameter
150
151   cat <<EOT >"index.html"
152 <!DOCTYPE html>
153 <html>
154 <head>
155   <title>$reportTitle</title>
156 </head>
157 <body>
158     <h1 style="text-align: center;">$reportTitle</h1>
159     <h4>Last updated for performance job build no. $latestRecordedBuild on $formattedTimestampOfLatestRecordedBuild</h4>
160     <p>The performance tests job runs daily at 02:15 UTC, providing performance metrics. The following graphs update at 04:15 UTC.</p>
161     <p>Successful performance tests job build adds new data, but even if a build fails, existing data is retained.</p>
162     <p>Updates occur whenever new successful data is available.</p>
163
164     <table align="center">
165         <tr> <!-- First Row -->
166             <td align="center">
167                 <figcaption>"$chartTitle1"</figcaption>
168                 <img src="$chartFileName1" alt="Image 1" width="750" height="300">
169             </td>
170             <td align="center" style="padding: 10px;">
171                 <figcaption>"$chartTitle2"</figcaption>
172                 <img src="$chartFileName2" alt="Image 2" width="750" height="300">
173             </td>
174         </tr>
175         <tr> <!-- Second Row -->
176             <td align="center" style="padding: 10px;">
177                 <figcaption>"$chartTitle3"</figcaption>
178                 <img src="$chartFileName3" alt="Image 3" width="750" height="300">
179             </td>
180             <td align="center" style="padding: 10px;">
181                 <figcaption>"$chartTitle4"</figcaption>
182                 <img src="$chartFileName4" alt="Image 4" width="750" height="300">
183             </td>
184         </tr>
185     </table>
186 </body>
187 </html>
188 EOT
189 }
190
191 buildPageReport() {
192   chartFileName="$1"
193   reportTitle="$2"
194   outputFile="$3"
195   cat <<EOT >"$outputFile"
196     <!DOCTYPE html>
197     <html>
198     <head>
199     <title>$reportTitle</title>
200     </head>
201     <body>
202         <h1>$reportTitle</h1>
203         <h4>Last updated for performance job build no. $latestRecordedBuild on $formattedTimestampOfLatestRecordedBuild</h4>
204         <img src="$chartFileName" alt="Graph Image">
205     </body>
206     </html>
207 EOT
208 }
209
210 getAndRecordAllDataResults() {
211   buildNumber="$1"
212   getConsoleText "$buildNumber"
213   getAndRecordDataResults "$consoleText" "$create_pattern" "$create_data" "$buildNumber"
214   getAndRecordDataResults "$consoleText" "$read_pattern" "$read_data" "$buildNumber"
215   getAndRecordDataResults "$consoleText" "$update_pattern" "$update_data" "$buildNumber"
216   getAndRecordDataResults "$consoleText" "$delete_pattern" "$delete_data" "$buildNumber"
217 }
218
219 #############################################################################################################################
220 #############################################################################################################################
221 #############################################################################################################################
222 #############################################################################################################################
223
224 # Install dependencies
225 sudo apt-get install -y bc gnuplot jq
226
227 # Download data from CPS performance Jenkins job
228 cd "$WORKSPACE"
229 if [ -z "$(ls -A)" ]; then
230   # If workspace is empty, pull data from all previous performance job runs
231   for buildNumber in $(getAllBuildIds); do
232     getAndRecordAllDataResults "$buildNumber"
233   done
234 else
235   # Append data from latest job run only
236   buildNumber=$(getLatestBuildId)
237   getAndRecordAllDataResults "$buildNumber"
238 fi
239
240 # Trim to last 30 entries
241 tail -n 30 "$create_data" > file.tmp && mv file.tmp "$create_data"
242 tail -n 30 "$read_data" > file.tmp && mv file.tmp "$read_data"
243 tail -n 30 "$update_data" > file.tmp && mv file.tmp "$update_data"
244 tail -n 30 "$delete_data" > file.tmp && mv file.tmp "$delete_data"
245
246 # Generate plot image files
247 buildPlotImage "$create_data" "createLargeData.png"
248 buildPlotImage "$read_data" "readDataTrees.png"
249 buildPlotImage "$update_data" "updateDatanodes.png"
250 buildPlotImage "$delete_data" "batchDelete.png"
251
252 buildHTMLReport \
253   "$create_data_title_1" "createLargeData.png" \
254   "$read_data_title_1" "readDataTrees.png" \
255   "$update_data_title_1" "updateDatanodes.png" \
256   "$delete_data_title_1" "batchDelete.png" \
257   "Performance Review"
258
259 buildPageReport "createLargeData.png" "$create_data_title_1" "createOperation.html"
260 buildPageReport "readDataTrees.png" "$read_data_title_1" "readOperation.html"
261 buildPageReport "updateDatanodes.png" "$update_data_title_1" "updateOperation.html"
262 buildPageReport "batchDelete.png" "$delete_data_title_1" "deleteOperation.html"