#!/bin/bash # Copyright 2013 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # Produce metrics analyzing the output of a stress test source "$(dirname ${0})/stress_test_common" set -e # Given a token, search for and compute the percentiles from logfile. compute_percentiles() { if [ ! -z "${1}" ]; then local pctls=".5 .9 1" local lines=$(count_result ${1}) for p in $pctls; do local count="$(echo "${lines} * $p" | bc -lq | cut -d. -f1)" echo -n $(cat ${log} \ | grep ${1} \ | cut -d' ' -f2 \ | sort -n \ | head -n$count \ | tail -n1) echo -n "s " done fi } main() { if [ $# -lt 1 ]; then cat <<EOF USAGE: $(basename ${0}) logfile Analyze the logfile of a stress test and produce metrics. EOF exit 1 fi local log="${1}" if [ ! -f "${log}" ]; then error "\"${log}\" not found" exit 1 fi cat <<EOF $(count_result "PASS_COURGETTE") successful courgette patches $(count_result "FAIL_COURGETTE") failed courgette patches $(count_result "FAIL_DISASSEMBLE") failed to disassemble/assemble $(count_result "PASS_BSDIFF") succesful bsdiff patches $(count_result "FAIL_BSDIFF") failed bsdiff patches $(count_result "BEST_COURGETTE") patch(es) where courgette is smaller (bz2) $(count_result "BEST_BSDIFF") patch(es) where bsdiff is smaller (xz) $(count_result "BEST_TIE") patch(es) where both are the same size (bz2) $(count_result "XZBEST_COURGETTE") patch(es) where courgette (xz) is smaller $(count_result "XZBEST_BSDIFF") patch(es) where bsdiff is smaller (xz) $(count_result "XZBEST_TIE") patch(es) where both are the same size (xz) EOF # Log file has the format "^SIZE courgette=... bsdiff=..." local courgette_total="$(cat "${log}" \ | grep "^SIZE " \ | cut -d' ' -f2 \ | awk -F= 'BEGIN{sum=0} {sum += $2} END{print sum}')" echo "${courgette_total} bytes for a courgette payload (bz2)" local courgette_total_xz="$(cat "${log}" \ | grep "^SIZE " \ | cut -d' ' -f4 \ | awk -F= 'BEGIN{sum=0} {sum += $2} END{print sum}')" echo "${courgette_total_xz} bytes for a courgette payload (xz)" local bsdiff_total="$(cat "${log}" \ | grep "^SIZE " \ | cut -d' ' -f3 \ | awk -F= 'BEGIN{sum=0} {sum += $2} END{print sum}')" echo "${bsdiff_total} bytes for a bsdiff payload" local best_total="$(cat "${log}" \ | grep "^BEST_" \ | awk 'BEGIN{sum=0} {sum += $2} END{print sum}')" echo "${best_total} bytes for a best-choice payload (bz2)" local best_total_xz="$(cat "${log}" \ | grep "^XZBEST_" \ | awk 'BEGIN{sum=0} {sum += $2} END{print sum}')" echo "${best_total_xz} bytes for a best-choice payload (xz)" local pct="$(echo "100*${best_total}/${bsdiff_total}" \ | bc -lq \ | awk '{printf "%.2f\n", $0}')" echo "${pct}% of a bsdiff-only payload (bz2)" local pct="$(echo "100*${best_total_xz}/${bsdiff_total}" \ | bc -lq \ | awk '{printf "%.2f\n", $0}')" echo "${pct}% of a bsdiff-only payload (xz)" local savings="$((bsdiff_total - best_total))" echo "${savings} bytes saved by courgette (bz2)" local savings_xz="$((bsdiff_total - best_total_xz))" echo "${savings} bytes saved by courgette (xz)" local pct_savings="$(echo "100*${savings}/${bsdiff_total}" \ | bc -lq \ | awk '{printf "%.2f\n", $0}')" echo "${pct_savings}% savings (bz2)" local pct_savings="$(echo "100*${savings_xz}/${bsdiff_total}" \ | bc -lq \ | awk '{printf "%.2f\n", $0}')" echo "${pct_savings}% savings (xz)" echo "$(compute_percentiles "TIME_GEN")to generate a patch (50th 90th 100th)" echo "$(compute_percentiles "TIME_APPLY")to apply a patch (50th 90th 100th)" echo "$(compute_percentiles "TIME_BSDIFF")for bsdiff (50th 90th 100th)" echo "$(compute_percentiles "TIME_BSPATCH")for bspatch (50th 90th 100th)" } main "${@}"