#!/bin/bash
-sudo apt-get install bc
+#
+# 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 ##########################################################
#############################################################################################################################
delete_data="delete_performance_data.txt"
# Data files headers
-create_data_title_1="Creating openroadm anchors with large data"
+create_data_title_1="Writing 400 devices"
read_data_title_1="Read datatrees using openroadm root"
-update_data_title_1="Update 100 data nodes"
-delete_data_title_1="Batch delete 100 whole lists"
+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
-creating_bookstore_pattern="^.*Creating openroadm anchors with large.*"
-read_datatreees_pattern="^.*Read datatrees using openroadm root.*"
-update_datanodes_pattern="^.*Update 100 data nodes.*"
-batch_delete_pattern="^.*Batch delete 100 whole lists.*"
+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.*"
-new_data=""
JENKINS_JOB_URL="https://jenkins.nordix.org/job/onap-cps-master-performance-test-java"
# Get latest build
-getLatestBuild() {
- latestBuild=$(curl -s "${JENKINS_JOB_URL}/lastBuild/api/json" | jq -r '.number')
- echo "latest build is $latestBuild"
+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
}
-latestBuild=$(getLatestBuild)
latestBuildToRecord=""
consoleText=""
-lastRecordedBuild=""
latestRecordedBuild=""
timestampOfLatestRecordedBuild=""
-# Create and add header to the file
-createAndAddHeader() {
- file="$1"
- header="$2"
- if [[ ! -f "$file" ]]; then
- echo "Creating $file"
- touch "$file"
- echo "Build,$header" > $file
- else
- echo "$file already exists"
- fi
-}
-
# Get the console text from specific build of the performance job
getConsoleText() {
- buildToRead=$1
- consoleURL="${JENKINS_JOB_URL}/${buildToRead}/consoleText"
- consoleText=$(curl -s "$consoleURL")
+ 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
- echo "Matched line: $matched_line"
- limit_value=$(echo "$matched_line" | grep -o -P 'limit\s*\K\d+(\.\d+)?' | tr -cd '[:digit:].')
- echo $limit_value
- took_value=$(echo "$matched_line" | grep -o -P 'took\s*\K\d+(\.\d+)?' | tr -cd '[:digit:].')
- echo $took_value
- percentage=$(echo "scale=2; $took_value * 100.00 / $limit_value" | bc)
-
-
- echo "Limit value: $limit_value"
- echo "Took value: $took_value"
- echo "Percentage: $percentage"
-
- if [ -z "$new_data" ]; then
- new_data="$percentage"
- else
- new_data+=",$percentage"
- fi
- echo "New data: $new_data"
-
- else
- echo "No match found."
- fi
-
- # Record result
- lastLine=$(tail -n 1 "$dataFile")
- newLine="$buildNumber,$new_data"
- if [ -z "$new_data" ]; then
- echo "No new data"
- lastRecordedBuild=$(echo "$lastLine" | awk -F, '{print $1}')
- recordLatestRecordedBuild "$lastRecordedBuild"
- elif [ $newLine == $lastLine ]; then
- echo "Data already exists"
- recordLatestRecordedBuild "$buildNumber"
- else
- echo "$buildNumber,$new_data" >> $dataFile
- echo "New data added"
- recordLatestRecordedBuild "$buildNumber"
- fi
+ 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" | jq -r '.timestamp')
- formattedTimestampOfLatestRecordedBuild=$(date -d "@$((timestampOfLatestRecordedBuild / 1000))" "+%B %e, %Y at %H:%M")
- echo "Latest recorded build: $latestBuildToRecord"
- echo "Date of latest recorded build: $formattedTimestampOfLatestRecordedBuild"
- latestRecordedBuild=$latestBuildToRecord
+ 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
}
-buildStaticReport() {
- dataFile="$1" # Get the input file name from the function parameter
- chartTitle="$2"
-
- sudo apt-get update
- sudo apt-get install -y gnuplot
-
- # Create a temporary Gnuplot script
- cat <<EOT > gnuplot_script.gp
- set datafile separator ","
- set terminal pngcairo size 1500,600
- set output "${chartTitle}.png"
-
- # Set X-axis label
- set xlabel "Build"
-
- # Set Y-axis label
- set ylabel "Percentage of limit %"
-
- # Get stats for min and max
- stats '$dataFile' using 1
- xmin = STATS_min
- freq = 5 #frequency
- xLabel(x) = (int((x - xmin) / freq) % 2 == 0) ? sprintf("%d", x) : ""
-
- plot '$dataFile' using (column(0)+1):2:xtic(xLabel(column(1))) with linespoints title "limit"
+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
+ # Run the Gnuplot script
+ gnuplot gnuplot_script.gp
- # Remove the temporary script
- rm 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"
+ chartTitle1="$1" # i.e Get the chart file name as the first parameter
+ chartFileName1="$2"
- chartTitle2="$3"
- chartFileName2="$4"
+ chartTitle2="$3"
+ chartFileName2="$4"
- chartTitle3="$5"
- chartFileName3="$6"
+ chartTitle3="$5"
+ chartFileName3="$6"
- chartTitle4="$7"
- chartFileName4="$8"
+ chartTitle4="$7"
+ chartFileName4="$8"
- reportTitle="$9" # i.e Get the report title as the ninth parameter
+ reportTitle="$9" # i.e Get the report title as the ninth parameter
-cat <<EOT > "index.html"
+ cat <<EOT >"index.html"
<!DOCTYPE html>
<html>
<head>
}
buildPageReport() {
- chartFileName="$1"
- reportTitle="$2"
- outputFile="$3"
- cat <<EOT > "$outputFile"
+ chartFileName="$1"
+ reportTitle="$2"
+ outputFile="$3"
+ cat <<EOT >"$outputFile"
<!DOCTYPE html>
<html>
<head>
EOT
}
-buildPlotForCreateOperation() {
- buildNumber="$1"
- createAndAddHeader "$create_data" "$create_data_title_1"
- getAndRecordDataResults "$consoleText" "$creating_bookstore_pattern" "$create_data" "$buildNumber"
-}
-
-buildPlotForReadOperation() {
- buildNumber="$1"
- createAndAddHeader "$read_data" "$read_data_title_1"
- getAndRecordDataResults "$consoleText" "$read_datatreees_pattern" "$read_data" "$buildNumber"
-}
-
-buildPlotForUpdateOperation() {
- buildNumber="$1"
- createAndAddHeader "$update_data" "$update_data_title_1"
- getAndRecordDataResults "$consoleText" "$update_datanodes_pattern" "$update_data" "$buildNumber"
-}
-
-buildPlotForBatchOperation() {
- buildNumber="$1"
- createAndAddHeader "$delete_data" "$delete_data_title_1"
- getAndRecordDataResults "$consoleText" "$batch_delete_pattern" "$delete_data" "$buildNumber"
-}
-
-#############################################################################################################################
-#############################################################################################################################
-#############################################################################################################################
-#############################################################################################################################
-
-cd $WORKSPACE
-
-getLatestBuild
-if [ -z "$(ls -A)" ]; then
- # Calculate the starting value for the loop
- startValue=$((latestBuild - 100))
-
- # Start the loop from startValue up to latestBuild
- for ((i=startValue; i<=latestBuild; i++)); do
- getConsoleText "$i"
- buildPlotForCreateOperation "$i"
- buildPlotForReadOperation "$i"
- buildPlotForUpdateOperation "$i"
- buildPlotForBatchOperation "$i"
- done
- buildStaticReport "$create_data" "createLargeData"
- buildStaticReport "$read_data" "readDataTrees"
- buildStaticReport "$update_data" "updateDatanodes"
- buildStaticReport "$delete_data" "batchDelete"
-else
- getConsoleText $latestBuild
- buildPlotForCreateOperation $latestBuild
- buildPlotForReadOperation $latestBuild
- buildPlotForUpdateOperation $latestBuild
- buildPlotForBatchOperation $latestBuild
-
- buildStaticReport "$create_data" "createLargeData"
- buildStaticReport "$read_data" "readDataTrees"
- buildStaticReport "$update_data" "updateDatanodes"
- buildStaticReport "$delete_data" "batchDelete"
-fi
-
-
-touch index.html createOperation.html readOperation.html updateOperation.html deleteOperation.html
-
-buildHTMLReport \
- "Creating openroadm anchors with large data" \
- "createLargeData.png" \
- "Read datatrees using openroadm root" \
- "readDataTrees.png" \
- "Update 100 data nodes" \
- "updateDatanodes.png" \
- "Batch delete 100 whole lists" \
- "batchDelete.png" \
- "Performance Review"
-
-buildPageReport "createLargeData.png" "Creating openroadm anchors with large data" "createOperation.html"
-buildPageReport "readDataTrees.png" "Read datatrees using openroadm root" "readOperation.html"
-buildPageReport "updateDatanodes.png" "Update 100 data nodes" "updateOperation.html"
-buildPageReport "batchDelete.png" "Batch delete 100 whole lists" "deleteOperation.html"
-
-
-buildPlotForCreateOperation() {
- buildNumber="$1"
- createAndAddHeader "$create_data" "$create_data_title_1"
- getAndRecordDataResults "$consoleText" "$creating_bookstore_pattern" "$create_data" "$buildNumber"
-}
-
-buildPlotForReadOperation() {
- buildNumber="$1"
- createAndAddHeader "$read_data" "$read_data_title_1"
- getAndRecordDataResults "$consoleText" "$read_datatreees_pattern" "$read_data" "$buildNumber"
-}
-
-buildPlotForUpdateOperation() {
- buildNumber="$1"
- createAndAddHeader "$update_data" "$update_data_title_1"
- getAndRecordDataResults "$consoleText" "$update_datanodes_pattern" "$update_data" "$buildNumber"
-}
-
-buildPlotForBatchOperation() {
- buildNumber="$1"
- createAndAddHeader "$delete_data" "$delete_data_title_1"
- getAndRecordDataResults "$consoleText" "$batch_delete_pattern" "$delete_data" "$buildNumber"
+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"
}
#############################################################################################################################
#############################################################################################################################
#############################################################################################################################
-cd $WORKSPACE
+# Install dependencies
+sudo apt-get install -y bc gnuplot jq
-getLatestBuild
+# Download data from CPS performance Jenkins job
+cd "$WORKSPACE"
if [ -z "$(ls -A)" ]; then
- # Calculate the starting value for the loop
- startValue=$((latestBuild - 50))
-
- # Start the loop from startValue up to latestBuild
- for ((i=startValue; i<=latestBuild; i++)); do
- getConsoleText "$i"
- buildPlotForCreateOperation "$i"
- buildPlotForReadOperation "$i"
- buildPlotForUpdateOperation "$i"
- buildPlotForBatchOperation "$i"
- done
- buildStaticReport "$create_data" "createLargeData"
- buildStaticReport "$read_data" "readDataTrees"
- buildStaticReport "$update_data" "updateDatanodes"
- buildStaticReport "$delete_data" "batchDelete"
+ # If workspace is empty, pull data from all previous performance job runs
+ for buildNumber in $(getAllBuildIds); do
+ getAndRecordAllDataResults "$buildNumber"
+ done
else
- getConsoleText $latestBuild
- buildPlotForCreateOperation $latestBuild
- buildPlotForReadOperation $latestBuild
- buildPlotForUpdateOperation $latestBuild
- buildPlotForBatchOperation $latestBuild
-
- buildStaticReport "$create_data" "createLargeData"
- buildStaticReport "$read_data" "readDataTrees"
- buildStaticReport "$update_data" "updateDatanodes"
- buildStaticReport "$delete_data" "batchDelete"
+ # 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"
-touch index.html createOperation.html readOperation.html updateOperation.html deleteOperation.html
+# 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 \
- "Creating openroadm anchors with large data" \
- "createLargeData.png" \
- "Read datatrees using openroadm root" \
- "readDataTrees.png" \
- "Update 100 data nodes" \
- "updateDatanodes.png" \
- "Batch delete 100 whole lists" \
- "batchDelete.png" \
- "Performance Review"
-
-buildPageReport "createLargeData.png" "Creating openroadm anchors with large data" "createOperation.html"
-buildPageReport "readDataTrees.png" "Read datatrees using openroadm root" "readOperation.html"
-buildPageReport "updateDatanodes.png" "Update 100 data nodes" "updateOperation.html"
-buildPageReport "batchDelete.png" "Batch delete 100 whole lists" "deleteOperation.html"
+ "$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"