blob: d6b9310344c85ca16a7e3147c9b468a248fed247 [file] [log] [blame]
Gilad Arnold553b0ec2013-01-26 01:00:39 -08001#!/bin/bash
2#
3# Copyright (c) 2013 The Chromium OS 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# A test script for paycheck.py and the update_payload.py library.
8#
9# This script requires three payload files, along with a metadata signature for
10# each, and a public key for verifying signatures. Payload include:
11#
12# - A full payload for release X (old_full_payload)
13#
14# - A full payload for release Y (new_full_payload), where Y > X
15#
16# - A delta payload from X to Y (delta_payload)
17#
18# The test performs the following:
19#
20# - It verifies each payload against its metadata signature, also asserting the
21# payload type. Another artifact is a human-readable payload report, which
22# is output to stdout to be inspected by the user.
23#
24# - It performs a random block trace on the delta payload (both kernel and
25# rootfs blocks), dumping the traces to stdout for the user to inspect.
26#
27# - It applies old_full_payload to yield old kernel (old_kern.part) and rootfs
28# (old_root.part) partitions.
29#
30# - It applies delta_payload to old_{kern,root}.part to yield new kernel
31# (new_delta_kern.part) and rootfs (new_delta_root.part) partitions.
32#
33# - It applies new_full_payload to yield reference new kernel
34# (new_full_kern.part) and rootfs (new_full_root.part) partitions.
35#
36# - It compares new_{delta,full}_kern.part and new_{delta,full}_root.part to
37# ensure that they are binary identical.
38#
39# If all steps have completed successfully we know with high certainty that
40# paycheck.py (and hence update_payload.py) correctly parses both full and
41# delta payloads, and applies them to yield the expected result. We also know
42# that tracing works, to the extent it does not crash. Manual inspection of
43# payload reports and block traces will improve this our confidence and are
44# strongly encouraged. Finally, each paycheck.py execution is timed.
45
46
47OLD_KERN_PART=old_kern.part
48OLD_ROOT_PART=old_root.part
49NEW_DELTA_KERN_PART=new_delta_kern.part
50NEW_DELTA_ROOT_PART=new_delta_root.part
51NEW_FULL_KERN_PART=new_full_kern.part
52NEW_FULL_ROOT_PART=new_full_root.part
53
54# Stop on errors, unset variables.
55set -e
56set -u
57
58log() {
59 echo "$@" >&2
60}
61
62die() {
63 log "$@"
64 exit 1
65}
66
67usage_and_exit() {
68 cat >&2 <<EOF
69Usage: ${0##*/} pubkey old_full_payload old_full_metasig \\
70 delta_payload delta_metasig new_full_payload new_full_metasig
71EOF
72 exit
73}
74
75check_payload() {
76 payload_file=$1
77 metasig_file=$2
78 payload_type=$3
79
80 time ${paycheck} -r - -k ${pubkey_file} -m ${metasig_file} \
81 -t ${payload_type} ${payload_file}
82}
83
84trace_kern_block() {
85 payload_file=$1
86 block=$2
87 time ${paycheck} -B ${block} ${payload_file}
88}
89
90trace_root_block() {
91 payload_file=$1
92 block=$2
93 time ${paycheck} -b ${block} ${payload_file}
94}
95
96apply_full_payload() {
97 payload_file=$1
98 dst_kern_part=$2
99 dst_root_part=$3
100
101 time ${paycheck} ${payload_file} ${dst_kern_part} ${dst_root_part}
102}
103
104apply_delta_payload() {
105 payload_file=$1
106 dst_kern_part=$2
107 dst_root_part=$3
108 src_kern_part=$4
109 src_root_part=$5
110
111 time ${paycheck} ${payload_file} ${dst_kern_part} ${dst_root_part} \
112 ${src_kern_part} ${src_root_part}
113}
114
115main() {
116 # Read command-line arguments.
117 if [ $# == 1 ] && [ "$1" == "-h" ]; then
118 usage_and_exit
119 elif [ $# != 7 ]; then
120 die "Error: unexpected number of arguments"
121 fi
122 pubkey_file="$1"
123 old_full_payload="$2"
124 old_full_metasig="$3"
125 delta_payload="$4"
126 delta_metasig="$5"
127 new_full_payload="$6"
128 new_full_metasig="$7"
129
130 # Find paycheck.py
131 paycheck=${0%/*}/paycheck.py
132 if [ -z "${paycheck}" ] || [ ! -x ${paycheck} ]; then
133 die "cannot find paycheck.py or file is not executable"
134 fi
135
136 log "Checking payloads..."
137 check_payload "${old_full_payload}" "${old_full_metasig}" full
138 check_payload "${new_full_payload}" "${new_full_metasig}" full
139 check_payload "${delta_payload}" "${delta_metasig}" delta
140 log "Done"
141
142 # Pick a random block between 0-1024
143 block=$((RANDOM * 1024 / 32767))
144 log "Tracing a random block (${block}) in full/delta payloads..."
145 trace_kern_block "${new_full_payload}" ${block}
146 trace_root_block "${new_full_payload}" ${block}
147 trace_kern_block "${delta_payload}" ${block}
148 trace_root_block "${delta_payload}" ${block}
149 log "Done"
150
151 log "Apply old full payload..."
152 apply_full_payload "${old_full_payload}" "${OLD_KERN_PART}" "${OLD_ROOT_PART}"
153 log "Done"
154 log "Apply delta payload to old partitions..."
155 time ./paycheck.py "${delta_payload}" "${NEW_DELTA_KERN_PART}" \
156 "${NEW_DELTA_ROOT_PART}" "${OLD_KERN_PART}" "${OLD_ROOT_PART}"
157 log "Done"
158 log "Apply new full payload..."
159 time ./paycheck.py "${new_full_payload}" "${NEW_FULL_KERN_PART}" \
160 "${NEW_FULL_ROOT_PART}"
161 log "Done"
162 log "Comparing results of delta and new full updates..."
163 diff "${NEW_FULL_KERN_PART}" "${NEW_DELTA_KERN_PART}"
164 diff "${NEW_FULL_ROOT_PART}" "${NEW_DELTA_ROOT_PART}"
165 log "Done"
166}
167
168main "$@"