• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/bash
2#
3# Copyright (C) 2013 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17
18# A test script for paycheck.py and the update_payload.py library.
19#
20# This script requires three payload files, along with a metadata signature for
21# each, and a public key for verifying signatures. Payload include:
22#
23# - A full payload for release X (old_full_payload)
24#
25# - A full payload for release Y (new_full_payload), where Y > X
26#
27# - A delta payload from X to Y (delta_payload)
28#
29# The test performs the following:
30#
31# - It verifies each payload against its metadata signature, also asserting the
32#   payload type. Another artifact is a human-readable payload report, which
33#   is output to stdout to be inspected by the user.
34#
35# - It applies old_full_payload to yield old kernel (old_kern.part) and rootfs
36#   (old_root.part) partitions.
37#
38# - It applies delta_payload to old_{kern,root}.part to yield new kernel
39#   (new_delta_kern.part) and rootfs (new_delta_root.part) partitions.
40#
41# - It applies new_full_payload to yield reference new kernel
42#   (new_full_kern.part) and rootfs (new_full_root.part) partitions.
43#
44# - It compares new_{delta,full}_kern.part and new_{delta,full}_root.part to
45#   ensure that they are binary identical.
46#
47# If all steps have completed successfully we know with high certainty that
48# paycheck.py (and hence update_payload.py) correctly parses both full and delta
49# payloads, and applies them to yield the expected result. Finally, each
50# paycheck.py execution is timed.
51
52
53# Stop on errors, unset variables.
54set -e
55set -u
56
57# Temporary image files.
58OLD_KERN_PART=old_kern.part
59OLD_ROOT_PART=old_root.part
60NEW_DELTA_KERN_PART=new_delta_kern.part
61NEW_DELTA_ROOT_PART=new_delta_root.part
62NEW_FULL_KERN_PART=new_full_kern.part
63NEW_FULL_ROOT_PART=new_full_root.part
64CROS_PARTS="kernel root"
65
66
67log() {
68  echo "$@" >&2
69}
70
71die() {
72  log "$@"
73  exit 1
74}
75
76usage_and_exit() {
77  cat >&2 <<EOF
78Usage: ${0##*/} old_full_payload delta_payload new_full_payload
79EOF
80  exit
81}
82
83check_payload() {
84  payload_file=$1
85  payload_type=$2
86
87  time ${paycheck} -t ${payload_type} ${payload_file}
88}
89
90apply_full_payload() {
91  payload_file=$1
92  out_dst_kern_part="$2/$3"
93  out_dst_root_part="$2/$4"
94
95  time ${paycheck} ${payload_file} \
96    --part_names ${CROS_PARTS} \
97    --out_dst_part_paths ${out_dst_kern_part} ${out_dst_root_part}
98}
99
100apply_delta_payload() {
101  payload_file=$1
102  out_dst_kern_part="$2/$3"
103  out_dst_root_part="$2/$4"
104  dst_kern_part="$2/$5"
105  dst_root_part="$2/$6"
106  src_kern_part="$2/$7"
107  src_root_part="$2/$8"
108
109  time ${paycheck} ${payload_file} \
110    --part_names ${CROS_PARTS} \
111    --out_dst_part_paths ${out_dst_kern_part} ${out_dst_root_part} \
112    --dst_part_paths ${dst_kern_part} ${dst_root_part} \
113    --src_part_paths ${src_kern_part} ${src_root_part}
114}
115
116main() {
117  # Read command-line arguments.
118  if [ $# == 1 ] && [ "$1" == "-h" ]; then
119    usage_and_exit
120  elif [ $# != 3 ]; then
121    die "Error: unexpected number of arguments"
122  fi
123  old_full_payload="$1"
124  delta_payload="$2"
125  new_full_payload="$3"
126
127  # Find paycheck.py
128  paycheck=${0%/*}/paycheck.py
129  if [ -z "${paycheck}" ] || [ ! -x ${paycheck} ]; then
130    die "cannot find ${paycheck} or file is not executable"
131  fi
132
133  # Check the payloads statically.
134  log "Checking payloads..."
135  check_payload "${old_full_payload}" full
136  check_payload "${new_full_payload}" full
137  check_payload "${delta_payload}" delta
138  log "Done"
139
140  # Apply full/delta payloads and verify results are identical.
141  tmpdir="$(mktemp -d --tmpdir test_paycheck.XXXXXXXX)"
142  log "Initiating application of payloads at $tmpdir"
143
144  log "Applying old full payload..."
145  apply_full_payload "${old_full_payload}" "${tmpdir}" "${OLD_KERN_PART}" \
146    "${OLD_ROOT_PART}"
147  log "Done"
148
149  log "Applying new full payload..."
150  apply_full_payload "${new_full_payload}" "${tmpdir}" "${NEW_FULL_KERN_PART}" \
151    "${NEW_FULL_ROOT_PART}"
152  log "Done"
153
154  log "Applying delta payload to old partitions..."
155  apply_delta_payload "${delta_payload}" "${tmpdir}" "${NEW_DELTA_KERN_PART}" \
156    "${NEW_DELTA_ROOT_PART}" "${NEW_FULL_KERN_PART}" \
157    "${NEW_FULL_ROOT_PART}" "${OLD_KERN_PART}" "${OLD_ROOT_PART}"
158  log "Done"
159
160  log "Comparing results of delta and new full updates..."
161  diff "${tmpdir}/${NEW_FULL_KERN_PART}" "${tmpdir}/${NEW_DELTA_KERN_PART}"
162  diff "${tmpdir}/${NEW_FULL_ROOT_PART}" "${tmpdir}/${NEW_DELTA_ROOT_PART}"
163  log "Done"
164
165  log "Cleaning up"
166  rm -fr "${tmpdir}"
167}
168
169main "$@"
170