1 #!/bin/bash 2 3 # Copyright 2013 The Chromium Authors. All rights reserved. 4 # Use of this source code is governed by a BSD-style license that can be 5 # found in the LICENSE file. 6 7 # Produce metrics analyzing the output of a stress test 8 9 source "$(dirname ${0})/stress_test_common" 10 11 set -e 12 13 # Given a token, search for and compute the percentiles from logfile. 14 compute_percentiles() { 15 if [ ! -z "${1}" ]; then 16 local pctls=".5 .9 1" 17 local lines=$(count_result ${1}) 18 for p in $pctls; do 19 local count="$(echo "${lines} * $p" | bc -lq | cut -d. -f1)" 20 echo -n $(cat ${log} \ 21 | grep ${1} \ 22 | cut -d' ' -f2 \ 23 | sort -n \ 24 | head -n$count \ 25 | tail -n1) 26 echo -n "s " 27 done 28 fi 29 } 30 31 main() { 32 if [ $# -lt 1 ]; then 33 cat <<EOF 34 35 USAGE: $(basename ${0}) logfile 36 37 Analyze the logfile of a stress test and produce metrics. 38 39 EOF 40 exit 1 41 fi 42 43 local log="${1}" 44 if [ ! -f "${log}" ]; then 45 error "\"${log}\" not found" 46 exit 1 47 fi 48 49 cat <<EOF 50 $(count_result "PASS_COURGETTE") successful courgette patches 51 $(count_result "FAIL_COURGETTE") failed courgette patches 52 $(count_result "FAIL_DISASSEMBLE") failed to disassemble/assemble 53 $(count_result "PASS_BSDIFF") succesful bsdiff patches 54 $(count_result "FAIL_BSDIFF") failed bsdiff patches 55 $(count_result "BEST_COURGETTE") patch(es) where courgette is smaller (bz2) 56 $(count_result "BEST_BSDIFF") patch(es) where bsdiff is smaller (xz) 57 $(count_result "BEST_TIE") patch(es) where both are the same size (bz2) 58 $(count_result "XZBEST_COURGETTE") patch(es) where courgette (xz) is smaller 59 $(count_result "XZBEST_BSDIFF") patch(es) where bsdiff is smaller (xz) 60 $(count_result "XZBEST_TIE") patch(es) where both are the same size (xz) 61 EOF 62 63 # Log file has the format "^SIZE courgette=... bsdiff=..." 64 local courgette_total="$(cat "${log}" \ 65 | grep "^SIZE " \ 66 | cut -d' ' -f2 \ 67 | awk -F= 'BEGIN{sum=0} {sum += $2} END{print sum}')" 68 echo "${courgette_total} bytes for a courgette payload (bz2)" 69 70 local courgette_total_xz="$(cat "${log}" \ 71 | grep "^SIZE " \ 72 | cut -d' ' -f4 \ 73 | awk -F= 'BEGIN{sum=0} {sum += $2} END{print sum}')" 74 echo "${courgette_total_xz} bytes for a courgette payload (xz)" 75 76 local bsdiff_total="$(cat "${log}" \ 77 | grep "^SIZE " \ 78 | cut -d' ' -f3 \ 79 | awk -F= 'BEGIN{sum=0} {sum += $2} END{print sum}')" 80 echo "${bsdiff_total} bytes for a bsdiff payload" 81 82 local best_total="$(cat "${log}" \ 83 | grep "^BEST_" \ 84 | awk 'BEGIN{sum=0} {sum += $2} END{print sum}')" 85 echo "${best_total} bytes for a best-choice payload (bz2)" 86 87 local best_total_xz="$(cat "${log}" \ 88 | grep "^XZBEST_" \ 89 | awk 'BEGIN{sum=0} {sum += $2} END{print sum}')" 90 echo "${best_total_xz} bytes for a best-choice payload (xz)" 91 92 local pct="$(echo "100*${best_total}/${bsdiff_total}" \ 93 | bc -lq \ 94 | awk '{printf "%.2f\n", $0}')" 95 echo "${pct}% of a bsdiff-only payload (bz2)" 96 97 local pct="$(echo "100*${best_total_xz}/${bsdiff_total}" \ 98 | bc -lq \ 99 | awk '{printf "%.2f\n", $0}')" 100 echo "${pct}% of a bsdiff-only payload (xz)" 101 102 local savings="$((bsdiff_total - best_total))" 103 echo "${savings} bytes saved by courgette (bz2)" 104 105 local savings_xz="$((bsdiff_total - best_total_xz))" 106 echo "${savings} bytes saved by courgette (xz)" 107 108 local pct_savings="$(echo "100*${savings}/${bsdiff_total}" \ 109 | bc -lq \ 110 | awk '{printf "%.2f\n", $0}')" 111 echo "${pct_savings}% savings (bz2)" 112 113 local pct_savings="$(echo "100*${savings_xz}/${bsdiff_total}" \ 114 | bc -lq \ 115 | awk '{printf "%.2f\n", $0}')" 116 echo "${pct_savings}% savings (xz)" 117 118 echo "$(compute_percentiles "TIME_GEN")to generate a patch (50th 90th 100th)" 119 echo "$(compute_percentiles "TIME_APPLY")to apply a patch (50th 90th 100th)" 120 echo "$(compute_percentiles "TIME_BSDIFF")for bsdiff (50th 90th 100th)" 121 echo "$(compute_percentiles "TIME_BSPATCH")for bspatch (50th 90th 100th)" 122 } 123 124 main "${@}" 125