blob: a42866a336d673faa76ffaf27622ef224d4390c2 [file] [log] [blame]
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Abort on error.
set -e
# Load common constants and variables.
. "$(dirname "$0")/"
usage() {
echo "Usage $PROG image [config]"
# Usage: lsbequals path-to-lsb-file key expected-value
# Returns 0 if they match, 1 otherwise.
# Also outputs a warning message if they don't match.
lsbequals() {
local lsbfile="$1"
local key="$2"
local expectval="$3"
local realval=$(lsbval "$lsbfile" $key)
if [ "$realval" != "$expectval" ]; then
error "${key} mismatch. Expected '${expectval}'," \
"image contains '${realval}'"
return 1
return 0
# Usage: check_keyval_in_list lsbfile lsbkey [list of values]
# Extracts the lsb-release value for the specified key, and confirms it
# matches one of the whitelisted values specified in value_array.
# Implementation note:
# You can't really pass bash arrays to functions. Best you can do is either
# serialize to string/pass/deserialize (e.g. using whitspace/IFS hacks), or,
# let the array contents be received as multiple arguments to the target
# function. We take the latter approach here, hence the shift's to get the
# first 2 arguments out, before we process the rest of the varargs.
check_keyval_in_list() {
local lsbfile="$1"
local lsbkey="$1"
local lsbval=$(lsbval "$lsbfile" "$lsbkey")
while [ $# -gt 0 ]; do
if [ "$lsbval" == "$1" ]; then
return 0
# If we get here, it wasn't found
error "${lsbkey}: Value '${lsbval}' was not recognized"
return 1
# Usage: lsb_syntaxcheck path-to-lsb-file
# Enforces a number of basic sanity checks on the overall format and contents
# of the lsb-release file:
# - Every line is "key=value".
# - No space after key, no space before value.
# - key is all A-Z or _, but not starting with _.
# - value is made up of printable characters, or is empty.
# - The whole file is a reasonable size (4kb).
lsb_syntaxcheck() {
local lsbfile="$1"
# Checks for key being A-Z_, 1 or more characters, not starting with _.
# Also checks for = with no spaces on either side.
# Checks that the value contains printables (and not starting with space).
# Alternatively, the value is permitted to be empty (0 chars) too.
# Allow comments to start with #.
badlines=$(grep -Ev \
-e '^[A-Z][A-Z_]*=([[:graph:]][[:print:]]*)?$' \
-e '^[[:space:]]*#' "${lsbfile}")
if [ -n "$badlines" ]; then
error "${lsbfile}: Some lines seem non-well-formed:"
error "${badlines}"
# Overall file size check:
size=$(ls -sk "$lsbfile" | cut -d ' ' -f 1)
if [ $size -gt 4 ]; then
error "${lsbfile}: This file exceeds 4kb"
return $syntaxbad
main() {
# We want to catch all the discrepancies, not just the first one.
# So, any time we find one, we set testfail=1 and continue.
# When finished we will use testfail to determine our exit value.
local testfail=0
if [ $# -ne 1 ] && [ $# -ne 2 ]; then
exit 1
local image="$1"
# Default config location: same directory as this script.
local configfile="$(dirname "$0")/default_lsb_release.config"
# Or, maybe a config was provided on the command line.
if [ $# -eq 2 ]; then
# Either way, load test-expectations data from config.
info "Loading config from ${configfile}"
. "$configfile" || return 1
local loopdev rootfs
if [[ -d "${image}" ]]; then
# We're given a mounted rootfs.
# Mount the disk image.
loopdev=$(loopback_partscan "${image}")
mount_loop_image_partition_ro "${loopdev}" 3 "${rootfs}"
local lsb="$rootfs/$LSB_FILE"
# Basic syntax check first.
lsb_syntaxcheck "$lsb" || testfail=1
lsbequals $lsb CHROMEOS_AUSERVER "$expected_auserver" || testfail=1
lsbequals $lsb CHROMEOS_RELEASE_NAME "$expected_release_name" || testfail=1
check_keyval_in_list $lsb CHROMEOS_RELEASE_TRACK \
"${expected_release_tracks[@]}" || testfail=1
local board=$(get_board_from_lsb_release "${rootfs}")
if check_keyval_in_list $lsb CHROMEOS_RELEASE_BOARD \
"${expected_boards[@]}"; then
local boardvar=$(get_boardvar_from_lsb_release "${rootfs}")
channel=$(lsbval $lsb CHROMEOS_RELEASE_TRACK)
# For a canary or dogfood channel, appid maybe a different default value.
if [[ "${channel}" == 'canary-channel' ||
"${channel}" == 'dogfood-channel' ]]; then
eval "expected_appid=\"\$expected_appid_${channel%\-channel}\""
eval "expected_appid=\"\$expected_appid_$boardvar\""
lsbequals $lsb CHROMEOS_RELEASE_APPID "$expected_appid" || testfail=1
else # unrecognized board
error "Unknown board: ${board}"
exit $testfail
main "$@"