#!/bin/bash
#
# Copyright (C) 2013 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# A test script for paycheck.py and the update_payload.py library.
#
# This script requires three payload files, along with a metadata signature for
# each, and a public key for verifying signatures. Payload include:
#
# - A full payload for release X (old_full_payload)
#
# - A full payload for release Y (new_full_payload), where Y > X
#
# - A delta payload from X to Y (delta_payload)
#
# The test performs the following:
#
# - It verifies each payload against its metadata signature, also asserting the
#   payload type. Another artifact is a human-readable payload report, which
#   is output to stdout to be inspected by the user.
#
# - It applies old_full_payload to yield old kernel (old_kern.part) and rootfs
#   (old_root.part) partitions.
#
# - It applies delta_payload to old_{kern,root}.part to yield new kernel
#   (new_delta_kern.part) and rootfs (new_delta_root.part) partitions.
#
# - It applies new_full_payload to yield reference new kernel
#   (new_full_kern.part) and rootfs (new_full_root.part) partitions.
#
# - It compares new_{delta,full}_kern.part and new_{delta,full}_root.part to
#   ensure that they are binary identical.
#
# If all steps have completed successfully we know with high certainty that
# paycheck.py (and hence update_payload.py) correctly parses both full and delta
# payloads, and applies them to yield the expected result. Finally, each
# paycheck.py execution is timed.


# Stop on errors, unset variables.
set -e
set -u

# Temporary image files.
OLD_KERN_PART=old_kern.part
OLD_ROOT_PART=old_root.part
NEW_DELTA_KERN_PART=new_delta_kern.part
NEW_DELTA_ROOT_PART=new_delta_root.part
NEW_FULL_KERN_PART=new_full_kern.part
NEW_FULL_ROOT_PART=new_full_root.part


log() {
  echo "$@" >&2
}

die() {
  log "$@"
  exit 1
}

usage_and_exit() {
  cat >&2 <<EOF
Usage: ${0##*/} old_full_payload delta_payload new_full_payload
EOF
  exit
}

check_payload() {
  payload_file=$1
  payload_type=$2

  time ${paycheck} -t ${payload_type} ${payload_file}
}

apply_full_payload() {
  payload_file=$1
  dst_kern_part="$2/$3"
  dst_root_part="$2/$4"

  time ${paycheck} ${payload_file} \
    --dst_kern ${dst_kern_part} --dst_root ${dst_root_part}
}

apply_delta_payload() {
  payload_file=$1
  dst_kern_part="$2/$3"
  dst_root_part="$2/$4"
  src_kern_part="$2/$5"
  src_root_part="$2/$6"

  time ${paycheck} ${payload_file} \
    --dst_kern ${dst_kern_part} --dst_root ${dst_root_part} \
    --src_kern ${src_kern_part} --src_root ${src_root_part}
}

main() {
  # Read command-line arguments.
  if [ $# == 1 ] && [ "$1" == "-h" ]; then
    usage_and_exit
  elif [ $# != 3 ]; then
    die "Error: unexpected number of arguments"
  fi
  old_full_payload="$1"
  delta_payload="$2"
  new_full_payload="$3"

  # Find paycheck.py
  paycheck=${0%/*}/paycheck.py
  if [ -z "${paycheck}" ] || [ ! -x ${paycheck} ]; then
    die "cannot find ${paycheck} or file is not executable"
  fi

  # Check the payloads statically.
  log "Checking payloads..."
  check_payload "${old_full_payload}" full
  check_payload "${new_full_payload}" full
  check_payload "${delta_payload}" delta
  log "Done"

  # Apply full/delta payloads and verify results are identical.
  tmpdir="$(mktemp -d --tmpdir test_paycheck.XXXXXXXX)"
  log "Initiating application of payloads at $tmpdir"

  log "Applying old full payload..."
  apply_full_payload "${old_full_payload}" "${tmpdir}" "${OLD_KERN_PART}" \
    "${OLD_ROOT_PART}"
  log "Done"

  log "Applying delta payload to old partitions..."
  apply_delta_payload "${delta_payload}" "${tmpdir}" "${NEW_DELTA_KERN_PART}" \
    "${NEW_DELTA_ROOT_PART}" "${OLD_KERN_PART}" "${OLD_ROOT_PART}"
  log "Done"

  log "Applying new full payload..."
  apply_full_payload "${new_full_payload}" "${tmpdir}" "${NEW_FULL_KERN_PART}" \
    "${NEW_FULL_ROOT_PART}"
  log "Done"

  log "Comparing results of delta and new full updates..."
  diff "${tmpdir}/${NEW_FULL_KERN_PART}" "${tmpdir}/${NEW_DELTA_KERN_PART}"
  diff "${tmpdir}/${NEW_FULL_ROOT_PART}" "${tmpdir}/${NEW_DELTA_ROOT_PART}"
  log "Done"

  log "Cleaning up"
  rm -fr "${tmpdir}"
}

main "$@"
