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