blob: ef7c7defab4e3eac16950e1618624bc1e29b926b [file] [log] [blame]
halil.cakal25ff8e82024-05-31 11:18:54 +01001#!/bin/bash
2#
3# Copyright 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
18set -o errexit # Exit on most errors
19set -o nounset # Disallow expansion of unset variables
20set -o pipefail # Use last non-zero exit code in a pipeline
danielhanrahan913c6ea2024-06-28 18:14:14 +010021set -o xtrace # Trace logging
halil.cakal25ff8e82024-05-31 11:18:54 +010022
23#############################################################################################################################
24################################################ F U N C T I O N S ##########################################################
25#############################################################################################################################
26
halil.cakal25ff8e82024-05-31 11:18:54 +010027JENKINS_JOB_URL="https://jenkins.nordix.org/job/onap-cps-performance-test-k6"
28
halil.cakal25ff8e82024-05-31 11:18:54 +010029latestRecordedBuild=""
danielhanrahan913c6ea2024-06-28 18:14:14 +010030formattedTimestampOfLatestRecordedBuild=""
halil.cakal25ff8e82024-05-31 11:18:54 +010031
32# Get last completed build number
33# The number has not been plotted on the graphs yet
34getLastCompletedBuildNumber() {
35 curl -s "${JENKINS_JOB_URL}/lastCompletedBuild/buildNumber"
36}
37
38# Get the last recorded build number from local workspace of the jenkins
39# The number has already been plotted on the graphs
40getLastRecordedBuildNumber() {
danielhanrahan913c6ea2024-06-28 18:14:14 +010041 local file_name="data/1.csv"
halil.cakal25ff8e82024-05-31 11:18:54 +010042 if [ -f "$file_name" ]; then
danielhanrahan913c6ea2024-06-28 18:14:14 +010043 tail -n 1 "$file_name" | cut -d, -f1
halil.cakal25ff8e82024-05-31 11:18:54 +010044 else
danielhanrahan913c6ea2024-06-28 18:14:14 +010045 echo 0
halil.cakal25ff8e82024-05-31 11:18:54 +010046 fi
47}
48
49# Get all builds numbers
50getAllBuildNumbers() {
51 curl -s "${JENKINS_JOB_URL}/api/json?tree=allBuilds\[id\]" | jq -r '.allBuilds[].id' | sort -n
52}
53
danielhanrahan913c6ea2024-06-28 18:14:14 +010054# Extract CSV results from the console text of k6 performance job
55getSummaryCsv() {
halil.cakal25ff8e82024-05-31 11:18:54 +010056 buildToRead=$1
57 consoleURL="${JENKINS_JOB_URL}/${buildToRead}/consoleText"
danielhanrahan913c6ea2024-06-28 18:14:14 +010058 # Extract summary CSV from Jenkins console output
halil.cakal838722c2024-09-06 15:30:10 +010059 curl -s "$consoleURL" | sed -n '/-- BEGIN CSV REPORT/, /-- END CSV REPORT/p' | grep "^[0-9].*,.*,.*,.*,.*$" || true
halil.cakal25ff8e82024-05-31 11:18:54 +010060}
61
62# Get and record the latest k6-job-results with the build number for all tests
63getAndRecordPerformanceJobResultForBuild() {
64 buildNumber="$1"
danielhanrahan913c6ea2024-06-28 18:14:14 +010065 getSummaryCsv "$buildNumber" > summary.csv
66 if [ -s summary.csv ]; then
67 # Store the test cases, names, and units
68 cut -d, -f1,2,3 summary.csv > test-cases.csv
halil.cakalb02a3152024-09-17 15:53:09 +010069 # Process each row in the CSV, storing the limit cps_expectation and actual value for this build
70 while IFS=, read -r test_case test_name units limit cps_expectation actual; do
71 echo "$buildNumber,$limit,$cps_expectation,$actual" >> "data/$test_case.csv"
danielhanrahan913c6ea2024-06-28 18:14:14 +010072 done < summary.csv
halil.cakal25ff8e82024-05-31 11:18:54 +010073 else
danielhanrahan913c6ea2024-06-28 18:14:14 +010074 # No CSV data for this build, so record zeroes for this build in each existing data file
75 for dataFile in data/*.csv; do
halil.cakalb02a3152024-09-17 15:53:09 +010076 echo "$buildNumber,0,0,0" >> "$dataFile"
danielhanrahan913c6ea2024-06-28 18:14:14 +010077 done
halil.cakal25ff8e82024-05-31 11:18:54 +010078 fi
danielhanrahan913c6ea2024-06-28 18:14:14 +010079 recordLatestRecordedBuild "$buildNumber"
halil.cakal25ff8e82024-05-31 11:18:54 +010080}
81
82# Format the date and time of the latest build
83recordLatestRecordedBuild() {
danielhanrahan913c6ea2024-06-28 18:14:14 +010084 local latestBuildToRecord="$1"
85 local timestampOfLatestRecordedBuild
halil.cakal25ff8e82024-05-31 11:18:54 +010086 timestampOfLatestRecordedBuild=$(curl -s "${JENKINS_JOB_URL}/${latestBuildToRecord}/api/json?tree=timestamp" | jq -r '.timestamp')
87 formattedTimestampOfLatestRecordedBuild=$(date -d "@$((timestampOfLatestRecordedBuild / 1000))" "+%B %e, %Y at %H:%M")
88 latestRecordedBuild=$latestBuildToRecord
89}
90
91# Plot the image (graph) in png format
92buildPlotImage() {
93 dataFile="$1"
94 chartFileName="$2"
danielhanrahan913c6ea2024-06-28 18:14:14 +010095 units="$3"
halil.cakalb02a3152024-09-17 15:53:09 +010096 numberOfBuilds="$4"
halil.cakal25ff8e82024-05-31 11:18:54 +010097
danielhanrahanea512782024-08-01 11:14:13 +010098 y_max=$(findMaxPlotRange "$dataFile")
halil.cakal25ff8e82024-05-31 11:18:54 +010099
100 # Create a temporary Gnuplot script
101 cat <<EOT >gnuplot_script.gp
102set datafile separator ","
103set terminal pngcairo size 1500,600
104set output "${chartFileName}"
105set xlabel "Build"
danielhanrahan913c6ea2024-06-28 18:14:14 +0100106set ylabel "${units}"
halil.cakal56b61ea2024-10-03 10:26:56 +0100107EOT
halil.cakal0d4a9c12024-09-10 16:05:36 +0100108
109# Set y-axis range based on y_max
halil.cakal56b61ea2024-10-03 10:26:56 +0100110if [[ "$units" == */second ]]; then
111 echo "set yrange [${y_max} : 0] reverse" >> gnuplot_script.gp
112else
113 echo "set yrange [0 : ${y_max}]" >> gnuplot_script.gp
114fi
halil.cakal0d4a9c12024-09-10 16:05:36 +0100115
halil.cakal56b61ea2024-10-03 10:26:56 +0100116cat <<EOT >>gnuplot_script.gp
halil.cakal0d4a9c12024-09-10 16:05:36 +0100117set style line 1 lc rgb '#d3d3d3' lt 1 lw 1 dashtype 2 # Grid style
118set style line 2 lc rgb '#0000FF' lt 1 lw 1 # threshold - Blue
119set style line 3 lc rgb '#00FF00' lt 1 lw 1 # cps-limit - Green
120set style line 4 lc rgb '#800080' lt 1 lw 1 # measured - Purple
121
danielhanrahanac1fea82024-08-29 12:50:48 +0100122set grid ytics ls 1
halil.cakal7ae89342024-06-14 17:28:29 +0100123set xtics rotate
halil.cakal0d4a9c12024-09-10 16:05:36 +0100124
125# Use plot command with explicit column assignments and lines for all series
halil.cakal25ff8e82024-05-31 11:18:54 +0100126EOT
127
halil.cakalb02a3152024-09-17 15:53:09 +0100128 if [ "$numberOfBuilds" -eq 100 ]; then
129 cat <<EOT >>gnuplot_script.gp
halil.cakal0cca7e22024-11-08 14:44:15 +0000130plot '$dataFile' using 1:2 with lines linestyle 2 title "threshold", \
131 '$dataFile' using 1:3 with lines linestyle 3 title "cps-limit", \
132 '$dataFile' using 1:4:xtic(1) with linespoints linestyle 4 title "measured"
halil.cakalb02a3152024-09-17 15:53:09 +0100133EOT
134 elif [ "$numberOfBuilds" -eq 720 ]; then
135 cat <<EOT >>gnuplot_script.gp
halil.cakal0cca7e22024-11-08 14:44:15 +0000136unset xtics
137plot '$dataFile' using 1:2 with lines linestyle 2 title "threshold", \
138 '$dataFile' using 1:3 with lines linestyle 3 title "cps-limit", \
139 '$dataFile' using 1:4 with lines linestyle 4 title "measured"
halil.cakalb02a3152024-09-17 15:53:09 +0100140EOT
141 fi
142
halil.cakal25ff8e82024-05-31 11:18:54 +0100143 # Run the temporary Gnuplot script
144 gnuplot gnuplot_script.gp
145
146 # Remove the temporary Gnuplot script
147 rm gnuplot_script.gp
148}
149
halil.cakal14089ff2024-09-24 15:35:29 +0100150# To set y-axis based on max of threshold or cps_expectation
danielhanrahanea512782024-08-01 11:14:13 +0100151findMaxPlotRange() {
152 dataFile="$1"
153 awk -F, '{
halil.cakal14089ff2024-09-24 15:35:29 +0100154 if (NF == 4 && $4 != "") {
155 if ($2 > max) max = $2;
156 if ($3 > max) max = $3;
157 }
danielhanrahanea512782024-08-01 11:14:13 +0100158 } END {
halil.cakal0d4a9c12024-09-10 16:05:36 +0100159 if (max == 0) {
halil.cakal14089ff2024-09-24 15:35:29 +0100160 max = 1;
halil.cakal0d4a9c12024-09-10 16:05:36 +0100161 }
halil.cakal0cca7e22024-11-08 14:44:15 +0000162 print max * 1.2;
danielhanrahanea512782024-08-01 11:14:13 +0100163 }' "$dataFile"
164}
halil.cakalb02a3152024-09-17 15:53:09 +0100165
166generateHtmlReport() {
167 local reportTitle="$1"
168 local outputFile="$2"
169 local numberOfBuilds="$3"
170
171 cat <<EOT >"$outputFile"
172 <!DOCTYPE html>
173 <html>
174 <head>
175 <title>$reportTitle</title>
176 </head>
177 <body>
178 <h1 style="text-align: center;">$reportTitle</h1>
179 <h4>Last updated for performance job build no. $latestRecordedBuild on $formattedTimestampOfLatestRecordedBuild</h4>
180 <table align="center">
181EOT
182
183 # Loop through the tests to generate the HTML rows which consists of the plot-image
184 while IFS=, read -r test_case test_name units; do
185 dataFile="data/$test_case.csv"
186 # Plot the image (graph) in png format
halil.cakal0cca7e22024-11-08 14:44:15 +0000187 csvFile="data/${test_case}_${numberOfBuilds}.csv"
188 pngFile="data/${test_case}_${numberOfBuilds}.png"
189 tail -n $numberOfBuilds $dataFile > "$csvFile"
190 buildPlotImage "$csvFile" "$pngFile" "$units" "$numberOfBuilds"
halil.cakalb02a3152024-09-17 15:53:09 +0100191 # Output to HTML
192 cat <<EOF >>"$outputFile"
193 <tr>
194 <td align="center" style="padding: 10px;">
195 <figcaption>$test_case. $test_name ($units)</figcaption>
196 <img src="data/${test_case}_${numberOfBuilds}.png" width="750" height="300">
197 </td>
198 </tr>
199EOF
200 done < test-cases.csv
201
202 # Close the HTML file
203 cat <<EOT >>"$outputFile"
204 </table>
205 <p>The plots are generated from the output of the Nordix Jenkins job:
206 <a href="https://jenkins.nordix.org/job/onap-cps-performance-test-k6/">onap-cps-performance-test-k6</a>.</p>
207 <p>The k6 performance tests run are described in the
208 <a href="https://wiki.onap.org/display/DW/CPS-391Spike%3A+Define+and+Agree+NCMP+REST+Interface#CPS391Spike:DefineandAgreeNCMPRESTInterface-Characteristics">NCMP REST Interface Characteristics</a> documentation.</p>
209 </body>
210 </html>
211EOT
212}
213
214
halil.cakal25ff8e82024-05-31 11:18:54 +0100215#############################################################################################################################
216################################################ M A I N ####################################################################
217#############################################################################################################################
218
219# Install dependencies
220sudo apt-get install -y bc gnuplot jq
221
222# Download data from CPS performance Jenkins job
223cd "$WORKSPACE"
danielhanrahan913c6ea2024-06-28 18:14:14 +0100224if [ ! -d data ]; then
halil.cakal25ff8e82024-05-31 11:18:54 +0100225 # If workspace is empty, pull data from all previous performance job runs
danielhanrahan913c6ea2024-06-28 18:14:14 +0100226 mkdir -p data
halil.cakal25ff8e82024-05-31 11:18:54 +0100227 for buildNumber in $(getAllBuildNumbers); do
228 getAndRecordPerformanceJobResultForBuild "$buildNumber"
229 done
230else
231 # Append new data from latest jobs run
232 lastCompletedBuildNumber=$(getLastCompletedBuildNumber)
233 lastRecordedBuildNumber=$(getLastRecordedBuildNumber)
234 # Check if last completed build number is greater than last recorded build number
235 if [ "$lastCompletedBuildNumber" -gt "$lastRecordedBuildNumber" ]; then
236 for ((i = lastRecordedBuildNumber + 1; i <= lastCompletedBuildNumber; i++)); do
237 # Process the new builds which hasn't been recorded yet
238 getAndRecordPerformanceJobResultForBuild "$i"
239 done
240 else
241 echo "No new builds to process."
242 fi
243fi
244
halil.cakalb02a3152024-09-17 15:53:09 +0100245reportTitleDaily="daily k6 tests performance review"
246outputFileDaily="k6TestsPerformanceReview.html"
247generateHtmlReport "$reportTitleDaily" "$outputFileDaily" "100"
halil.cakal25ff8e82024-05-31 11:18:54 +0100248
halil.cakalb02a3152024-09-17 15:53:09 +0100249reportTitleMonthly="monthly k6 tests performance review"
250outputFileMonthly="k6TestsPerformanceReviewMonthly.html"
251generateHtmlReport "$reportTitleMonthly" "$outputFileMonthly" "720"