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
9source "$(dirname ${0})/stress_test_common"
10
11set -e
12
13# Given a token, search for and compute the percentiles from logfile.
14compute_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
31main() {
32  if [ $# -lt 1 ]; then
33    cat <<EOF
34
35USAGE: $(basename ${0}) logfile
36
37Analyze the logfile of a stress test and produce metrics.
38
39EOF
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)
61EOF
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
124main "${@}"
125