| #!/bin/bash |
| # |
| # Copyright 2023-2024 Nordix Foundation. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| # |
| |
| set -o errexit # Exit on most errors |
| set -o nounset # Disallow expansion of unset variables |
| set -o pipefail # Use last non-zero exit code in a pipeline |
| #set -o xtrace # Trace logging - disabled to avoid producing gigabytes of logs |
| |
| ############################################################################################################################# |
| ################################################ F U N C T I O N S ########################################################## |
| ############################################################################################################################# |
| |
| create_data="create_performance_data.txt" |
| read_data="read_performance_data.txt" |
| update_data="update_performance_data.txt" |
| delete_data="delete_performance_data.txt" |
| |
| # Data files headers |
| create_data_title_1="Writing 400 devices" |
| read_data_title_1="Read datatrees using openroadm root" |
| update_data_title_1="Replace 100 with new leaf values" |
| delete_data_title_1="Batch delete 100 containers" |
| |
| # Text patterns to match in console log |
| create_pattern="^.*Writing 400 devices.*" |
| read_pattern="^.*Read datatrees using openroadm root.*" |
| update_pattern="^.*Replace 100 with new leaf values.*" |
| delete_pattern="^.*Batch delete 100 containers.*" |
| |
| JENKINS_JOB_URL="https://jenkins.nordix.org/job/onap-cps-master-performance-test-java" |
| |
| # Get latest build |
| getLatestBuildId() { |
| curl -s "${JENKINS_JOB_URL}/lastBuild/buildNumber" |
| } |
| |
| # Get all builds numbers |
| getAllBuildIds() { |
| curl -s "${JENKINS_JOB_URL}/api/json?tree=allBuilds\[id\]" | jq -r '.allBuilds[].id' | sort -n |
| } |
| |
| latestBuildToRecord="" |
| consoleText="" |
| latestRecordedBuild="" |
| timestampOfLatestRecordedBuild="" |
| |
| # Get the console text from specific build of the performance job |
| getConsoleText() { |
| buildToRead=$1 |
| consoleURL="${JENKINS_JOB_URL}/${buildToRead}/consoleText" |
| consoleText=$(curl -s "$consoleURL") |
| } |
| |
| getAndRecordDataResults() { |
| consoleText=$1 |
| patternToMatch=$2 |
| dataFile=$3 |
| buildNumber=$4 |
| new_data="" |
| matched_line="" |
| limit_value="" |
| took_value="" |
| |
| # Get and calculate data for plot |
| if matched_line=$(echo "$consoleText" | grep -o -P "$patternToMatch"); then |
| limit_value=$(echo "$matched_line" | grep -o -P 'limit\s*\K\d+(\.\d+)?' | tr -cd '[:digit:].') |
| took_value=$(echo "$matched_line" | grep -o -P 'took\s*\K\d+(\.\d+)?' | tr -cd '[:digit:].') |
| percentage=$(echo "scale=2; $took_value * 100.00 / $limit_value" | bc) |
| new_data="$percentage" |
| fi |
| |
| # Record result |
| touch "$dataFile" |
| lastLine=$(tail -n 1 "$dataFile") |
| newLine="$buildNumber,$new_data" |
| if [ -z "$new_data" ]; then |
| # No data found for this build |
| echo "$buildNumber,0" >>"$dataFile" |
| recordLatestRecordedBuild "$buildNumber" |
| elif [ "$newLine" == "$lastLine" ]; then |
| # Data already exists |
| recordLatestRecordedBuild "$buildNumber" |
| else |
| # New data added |
| echo "$buildNumber,$new_data" >>"$dataFile" |
| recordLatestRecordedBuild "$buildNumber" |
| fi |
| } |
| |
| recordLatestRecordedBuild() { |
| latestBuildToRecord="$1" |
| timestampOfLatestRecordedBuild=$(curl -s "${JENKINS_JOB_URL}/${latestBuildToRecord}/api/json?tree=timestamp" | jq -r '.timestamp') |
| formattedTimestampOfLatestRecordedBuild=$(date -d "@$((timestampOfLatestRecordedBuild / 1000))" "+%B %e, %Y at %H:%M") |
| latestRecordedBuild=$latestBuildToRecord |
| } |
| |
| buildPlotImage() { |
| dataFile="$1" # Get the input file name from the function parameter |
| chartFileName="$2" |
| |
| # Create a temporary Gnuplot script |
| cat <<EOT >gnuplot_script.gp |
| set datafile separator "," |
| set terminal pngcairo size 1500,600 |
| set output "${chartFileName}" |
| set xlabel "Build" |
| set ylabel "Percentage of limit %" |
| set yrange [0 < * < 80 : 120 < *] |
| set xtics rotate |
| plot '$dataFile' using (column(0)):2:xtic(sprintf("%d", column(1))) with linespoints title "measured", \ |
| 100 with lines linestyle 2 title "100% limit" |
| EOT |
| |
| # Run the Gnuplot script |
| gnuplot gnuplot_script.gp |
| |
| # Remove the temporary script |
| rm gnuplot_script.gp |
| } |
| |
| buildHTMLReport() { |
| |
| chartTitle1="$1" # i.e Get the chart file name as the first parameter |
| chartFileName1="$2" |
| |
| chartTitle2="$3" |
| chartFileName2="$4" |
| |
| chartTitle3="$5" |
| chartFileName3="$6" |
| |
| chartTitle4="$7" |
| chartFileName4="$8" |
| |
| reportTitle="$9" # i.e Get the report title as the ninth parameter |
| |
| cat <<EOT >"index.html" |
| <!DOCTYPE html> |
| <html> |
| <head> |
| <title>$reportTitle</title> |
| </head> |
| <body> |
| <h1 style="text-align: center;">$reportTitle</h1> |
| <h4>Last updated for performance job build no. $latestRecordedBuild on $formattedTimestampOfLatestRecordedBuild</h4> |
| <p>The performance tests job runs daily at 02:15 UTC, providing performance metrics. The following graphs update at 04:15 UTC.</p> |
| <p>Successful performance tests job build adds new data, but even if a build fails, existing data is retained.</p> |
| <p>Updates occur whenever new successful data is available.</p> |
| |
| <table align="center"> |
| <tr> <!-- First Row --> |
| <td align="center"> |
| <figcaption>"$chartTitle1"</figcaption> |
| <img src="$chartFileName1" alt="Image 1" width="750" height="300"> |
| </td> |
| <td align="center" style="padding: 10px;"> |
| <figcaption>"$chartTitle2"</figcaption> |
| <img src="$chartFileName2" alt="Image 2" width="750" height="300"> |
| </td> |
| </tr> |
| <tr> <!-- Second Row --> |
| <td align="center" style="padding: 10px;"> |
| <figcaption>"$chartTitle3"</figcaption> |
| <img src="$chartFileName3" alt="Image 3" width="750" height="300"> |
| </td> |
| <td align="center" style="padding: 10px;"> |
| <figcaption>"$chartTitle4"</figcaption> |
| <img src="$chartFileName4" alt="Image 4" width="750" height="300"> |
| </td> |
| </tr> |
| </table> |
| </body> |
| </html> |
| EOT |
| } |
| |
| buildPageReport() { |
| chartFileName="$1" |
| reportTitle="$2" |
| outputFile="$3" |
| cat <<EOT >"$outputFile" |
| <!DOCTYPE html> |
| <html> |
| <head> |
| <title>$reportTitle</title> |
| </head> |
| <body> |
| <h1>$reportTitle</h1> |
| <h4>Last updated for performance job build no. $latestRecordedBuild on $formattedTimestampOfLatestRecordedBuild</h4> |
| <img src="$chartFileName" alt="Graph Image"> |
| </body> |
| </html> |
| EOT |
| } |
| |
| getAndRecordAllDataResults() { |
| buildNumber="$1" |
| getConsoleText "$buildNumber" |
| getAndRecordDataResults "$consoleText" "$create_pattern" "$create_data" "$buildNumber" |
| getAndRecordDataResults "$consoleText" "$read_pattern" "$read_data" "$buildNumber" |
| getAndRecordDataResults "$consoleText" "$update_pattern" "$update_data" "$buildNumber" |
| getAndRecordDataResults "$consoleText" "$delete_pattern" "$delete_data" "$buildNumber" |
| } |
| |
| ############################################################################################################################# |
| ############################################################################################################################# |
| ############################################################################################################################# |
| ############################################################################################################################# |
| |
| # Install dependencies |
| sudo apt-get install -y bc gnuplot jq |
| |
| # Download data from CPS performance Jenkins job |
| cd "$WORKSPACE" |
| if [ -z "$(ls -A)" ]; then |
| # If workspace is empty, pull data from all previous performance job runs |
| for buildNumber in $(getAllBuildIds); do |
| getAndRecordAllDataResults "$buildNumber" |
| done |
| else |
| # Append data from latest job run only |
| buildNumber=$(getLatestBuildId) |
| getAndRecordAllDataResults "$buildNumber" |
| fi |
| |
| # Trim to last 30 entries |
| tail -n 30 "$create_data" > file.tmp && mv file.tmp "$create_data" |
| tail -n 30 "$read_data" > file.tmp && mv file.tmp "$read_data" |
| tail -n 30 "$update_data" > file.tmp && mv file.tmp "$update_data" |
| tail -n 30 "$delete_data" > file.tmp && mv file.tmp "$delete_data" |
| |
| # Generate plot image files |
| buildPlotImage "$create_data" "createLargeData.png" |
| buildPlotImage "$read_data" "readDataTrees.png" |
| buildPlotImage "$update_data" "updateDatanodes.png" |
| buildPlotImage "$delete_data" "batchDelete.png" |
| |
| buildHTMLReport \ |
| "$create_data_title_1" "createLargeData.png" \ |
| "$read_data_title_1" "readDataTrees.png" \ |
| "$update_data_title_1" "updateDatanodes.png" \ |
| "$delete_data_title_1" "batchDelete.png" \ |
| "Performance Review" |
| |
| buildPageReport "createLargeData.png" "$create_data_title_1" "createOperation.html" |
| buildPageReport "readDataTrees.png" "$read_data_title_1" "readOperation.html" |
| buildPageReport "updateDatanodes.png" "$update_data_title_1" "updateOperation.html" |
| buildPageReport "batchDelete.png" "$delete_data_title_1" "deleteOperation.html" |