diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/README | 51 | ||||
-rwxr-xr-x | tests/common.sh | 41 | ||||
-rwxr-xr-x | tests/gen_test.sh | 91 | ||||
-rwxr-xr-x | tests/run_tests.sh | 68 | ||||
-rw-r--r-- | tests/src/Android.mk | 19 | ||||
-rw-r--r-- | tests/src/ufdt_overlay_test_app.c | 69 | ||||
-rw-r--r-- | tests/testdata/apply_fragment.add_dts | 2 | ||||
-rw-r--r-- | tests/testdata/apply_fragment.base_dts | 6 | ||||
-rw-r--r-- | tests/testdata/dtc_local_fixup.add_dts | 5 | ||||
-rw-r--r-- | tests/testdata/dtc_local_fixup.base_dts | 8 | ||||
-rw-r--r-- | tests/testdata/libufdt_local_fixup.add_dts | 5 | ||||
-rw-r--r-- | tests/testdata/libufdt_local_fixup.add_ov_dts | 11 | ||||
-rw-r--r-- | tests/testdata/libufdt_local_fixup.base_dts | 8 | ||||
-rw-r--r-- | tests/testdata/local_fixup_with_offset.add_dts | 8 | ||||
-rw-r--r-- | tests/testdata/local_fixup_with_offset.base_dts | 6 | ||||
-rw-r--r-- | tests/testdata/no_local_fixup.add_dts | 3 | ||||
-rw-r--r-- | tests/testdata/no_local_fixup.base_dts | 7 | ||||
-rw-r--r-- | tests/testdata/overlay_2_layers.add_dts | 7 | ||||
-rw-r--r-- | tests/testdata/overlay_2_layers.base_dts | 11 |
19 files changed, 426 insertions, 0 deletions
diff --git a/tests/README b/tests/README new file mode 100644 index 0000000..645470d --- /dev/null +++ b/tests/README @@ -0,0 +1,51 @@ +This folder contains scripts and test data to test libufdt. + +# Test scripts + +* run_tests.sh: The main entry to run test cases. Using different + test cases under testdata/*. +* gen_test.sh: The script to run a single test case. +* common.sh: A common lib containing several useful functions. + +# Test data + +testdata/${my_test_case}.base_dts + - Base device tree source. + - Sample format: + ``` + /dts-v1/; + / { + a: a{}; + }; + ``` + +testdata/${my_test_case}.add_dts + - Additional device tree source. + - Sample format: + ``` + &a{ name = "a"; }; + ``` + +testdata/${my_test_case}.add_ov_dts (optional) + - Additional device tree fragment source. + - Sample format: + ``` + /dts-v1/ /plugin/; + / { + fragment@0{ + target = <&a>; + __overlay__ { + name = "a"; + }; + }; + }; + ``` + +# Steps to run the test + +Suppose you are at the root directory of your Android source. + +1. `source build/envsetup.sh` +2. `lunch` +3. `mmma system/libufdt` +4. `system/libufdt/tests/run_tests.sh` diff --git a/tests/common.sh b/tests/common.sh new file mode 100755 index 0000000..4c8ce78 --- /dev/null +++ b/tests/common.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +alert() { + echo "$*" >&2 +} + +die() { + echo "ERROR: $@" + exit 1 +} + +command_exists () { + type "$1" &> /dev/null; +} + +dtb_to_dts () { + dtc -O dts -s $1 + if [ $? -ne 0 ]; then + die "dtb_to_dts $1 failed!" + fi +} + +dts_to_dtb () { + dtc -O dtb -s -@ $1 + if [ $? -ne 0 ]; then + die "dts_to_dtb $1 failed!" + fi +} + +remove_local_fixups() { + sed '/__local_fixups__/ {s/^\s*__local_fixups__\s*//; :again;N; s/{[^{}]*};//; /^$/ !b again; d}' $1 +} + +remove_overlay_stuff() { + # remove __symbols__, phandle, "linux,phandle" and __local_fixups__ + sed "/__symbols__/,/[}];/d" $1 | sed "/\(^[ \t]*phandle\)/d" | sed "/\(^[ \t]*linux,phandle\)/d" | sed '/^\s*$/d' | remove_local_fixups +} + +dt_diff () { + diff -u <(dtb_to_dts "$1" | remove_overlay_stuff) <(dtb_to_dts "$2" | remove_overlay_stuff) +} diff --git a/tests/gen_test.sh b/tests/gen_test.sh new file mode 100755 index 0000000..5f30b71 --- /dev/null +++ b/tests/gen_test.sh @@ -0,0 +1,91 @@ +#!/bin/bash + +# We want to generate two device tree blob (.dtb) files by combining +# the "base" and "add" device tree source (.dts) files in two +# different ways. +# +# 1) /include/ the "add" at the end of the "base" file and +# compile with dtc to make the "gold standard" .dtb +# +# 2) Compile them separately (modifying the "add" file to +# be an overlay file) with dtc, then join them with the +# ov_test program +# +# To do this, we need to generate a lot of files from the .base_dts +# and .add_dts files: +# .base_inc_dts - Has the /include/ "${FILENAME}.add_dts" at the end. +# .base_inc_dtb - The dtc-generated "gold standard" +# .add_ov_dts - Has the /plugin/ at the start +# .base_dtb - Compiled version of just the base +# .add_ov_dtbo - Compiled version of the overlay +# .base_ov_dtb - overlay-test-joined version of the dtb +# +# Then, compare .base_inc_dtb and .base_ov_dtb with dtdiff +# (or maybe diff?) and return 0 iff they are identical. + +# Include some functions from common.sh. +SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" +source ${SCRIPT_DIR}/common.sh + +# Constants +IN_DATA_DIR="testdata" +OUT_DATA_DIR="test-out" + +# Global variables +FILENAME=$1 + +on_exit() { + rm -rf "${OUT_DATA_DIR}" +} + +# Generate test cases to OUT_DATA_DIR +prepare_tests() { + cp "${IN_DATA_DIR}/${FILENAME}.base_dts" "${OUT_DATA_DIR}/${FILENAME}.base_dts" + cp "${IN_DATA_DIR}/${FILENAME}.add_dts" "${OUT_DATA_DIR}/${FILENAME}.add_dts" + + # Add the "include" to make .base_inc_dts + cp "${IN_DATA_DIR}/${FILENAME}.base_dts" "${OUT_DATA_DIR}/${FILENAME}.base_inc_dts" + echo "/include/ \"${FILENAME}.add_dts\"" >> "${OUT_DATA_DIR}/${FILENAME}.base_inc_dts" + + # Generate .base_inc_dtb + dtc -@ -O dtb -s -b 0 -o "${OUT_DATA_DIR}/${FILENAME}.base_inc.dtb" \ + "${OUT_DATA_DIR}/${FILENAME}.base_inc_dts" + + # Add /dts-v1/ /plugin/; in front of .add_dts file. In order to trigger dtc's + # fragment generation mechanism. + if [ -a "${IN_DATA_DIR}/${FILENAME}.add_ov_dts" ]; then + cp "${IN_DATA_DIR}/${FILENAME}.add_ov_dts" "${OUT_DATA_DIR}/${FILENAME}.add_ov_dts" + else + sed "1i/dts-v1/ /plugin/;" "${IN_DATA_DIR}/${FILENAME}.add_dts" > \ + "${OUT_DATA_DIR}/${FILENAME}.add_ov_dts" + fi +} + +# Compile test cases into dtb, and do the diff things. +compile_and_diff() { + # Compile the base to make .base_dtb + dtc -O dtb -b 0 -@ -o "${OUT_DATA_DIR}/${FILENAME}.base_dtb" \ + "${OUT_DATA_DIR}/${FILENAME}.base_dts" + + # Compile the overlay to make .add_ov_dtbo + dtc -O dtb -b 0 -@ -o "${OUT_DATA_DIR}/${FILENAME}.add_ov_dtbo" \ + "${OUT_DATA_DIR}/${FILENAME}.add_ov_dts" + + # Run ov_test to combine .base_dtb and .add_ov_dtbo + # into .base_ov_dtb + ufdt_apply_overlay "${OUT_DATA_DIR}/${FILENAME}.base_dtb" \ + "${OUT_DATA_DIR}/${FILENAME}.add_ov_dtbo" \ + "${OUT_DATA_DIR}/${FILENAME}.base_ov.dtb" + + # Run the diff + dt_diff ${OUT_DATA_DIR}/${FILENAME}.base_inc.dtb ${OUT_DATA_DIR}/${FILENAME}.base_ov.dtb +} + +# The script will exit directly if any command fails. +set -e +trap on_exit EXIT + +mkdir -p "${OUT_DATA_DIR}" >& /dev/null + +prepare_tests +compile_and_diff diff --git a/tests/run_tests.sh b/tests/run_tests.sh new file mode 100755 index 0000000..845f190 --- /dev/null +++ b/tests/run_tests.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +# Include some functions from common.sh. +SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" +source ${SCRIPT_DIR}/common.sh + +# Usage: run_test_case <filename> <description> +# Args: +# filename: The file name for ./gen_test.sh to generate and run the +# test case. Several files under ./testdata subfolder are required: +# - ./testdata/${filename}.base_dts +# - ./testdata/${filename}.add_dts +# - ./testdata/${filename}.add_ov_dts (optional) +# For more details, check ./gen_test.sh. +# description: a description message to be displayed in the terminal +run_test_case() { + local filename="$1" + local description="$2" + + alert "${description}" + ./gen_test.sh "${filename}" >&2 || + die "Test case: ${filename} failed!!" +} + +main() { + alert "========== Running Tests of libufdt ==========" + + if [ -z "${ANDROID_BUILD_TOP}" ]; then + die "Run envsetup.sh / lunch yet?" + fi + + if ! command_exists dtc || + ! command_exists ufdt_apply_overlay; then + die "Run mmma $(dirname ${SCRIPT_DIR}) yet?" + fi + + ( + + # cd to ${SCRIPT_DIR} in a subshell because gen_test.sh uses relative + # paths for dependent files. + cd "${SCRIPT_DIR}" + + run_test_case \ + "no_local_fixup" \ + "Run test about fdt_apply_fragment with no local fixup" + run_test_case \ + "apply_fragment" \ + "Run test about fdt_apply_fragment with phandle update" + run_test_case \ + "libufdt_local_fixup" \ + "Run test about fdt_overlay_do_local_fixups" + run_test_case \ + "dtc_local_fixup" \ + "Run test about local fixup format consistent with current dtc" + run_test_case \ + "local_fixup_with_offset" \ + "Run test about dealing with local fixup with offset > 0" + run_test_case \ + "overlay_2_layers" \ + "Run test about dealing with overlay deep tree" + ) + + if [ $? -ne 0 ]; then + die "Some test cases failed, please check error message..." + fi +} + +main "$@" diff --git a/tests/src/Android.mk b/tests/src/Android.mk new file mode 100644 index 0000000..4239c81 --- /dev/null +++ b/tests/src/Android.mk @@ -0,0 +1,19 @@ +# Copyright 2016 The Android Open Source Project + +LOCAL_PATH:= $(call my-dir) + +################################################### + +include $(CLEAR_VARS) + +LOCAL_MODULE := ufdt_apply_overlay +LOCAL_SRC_FILES := ufdt_overlay_test_app.c +LOCAL_STATIC_LIBRARIES := \ + libufdt \ + libfdt \ + libufdt_sysdeps +LOCAL_REQUIRED_MODULES := dtc + +include $(BUILD_HOST_EXECUTABLE) + +################################################### diff --git a/tests/src/ufdt_overlay_test_app.c b/tests/src/ufdt_overlay_test_app.c new file mode 100644 index 0000000..ce30936 --- /dev/null +++ b/tests/src/ufdt_overlay_test_app.c @@ -0,0 +1,69 @@ +#include "ufdt_overlay.h" + +#include <stdio.h> +#include <stdlib.h> +#include <time.h> + +#include "libufdt_sysdeps.h" + + +char *load_file(char *fname, size_t *pLen); + +char *load_file(char *fname, size_t *pLen) { + FILE *f; + f = fopen(fname, "r"); + if (!f) { + printf("Couldn't open file '%s'\n", fname); + exit(1); + } + fseek(f, 0, SEEK_END); + *pLen = ftell(f); + fseek(f, 0, SEEK_SET); + char *buf = dto_malloc(*pLen); + if (fread(buf, *pLen, 1, f) != 1) { + printf("Bad fread"); + exit(1); + } + return buf; +} + +int main(int argc, char **argv) { + char *base_buf, *overlay_buf; + FILE *out_file; + struct fdt_header *blob; + if (argc < 4) { + printf("Usage: ov_test base_file overlay_file out_file\n"); + exit(1); + } + size_t blob_len, overlay_len; + base_buf = load_file(argv[1], &blob_len); + overlay_buf = load_file(argv[2], &overlay_len); + if (!overlay_buf) return 1; + blob = ufdt_install_blob(base_buf, blob_len); + + if (!blob) { + printf("ufdt_install_blob returned null\n"); + exit(1); + } + clock_t start, end; + double cpu_time_used; + start = clock(); + struct fdt_header *new_blob = + ufdt_apply_overlay(blob, blob_len, overlay_buf, overlay_len); + end = clock(); + cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC; + + printf("ufdt_apply_overlay took %.9f second\n", cpu_time_used); + + // Do not dto_free(blob) - it's the same as base_buf. + + out_file = fopen(argv[3], "wb"); + if (fwrite(new_blob, 1, fdt_totalsize(new_blob), out_file) < 1) { + printf("fwrite failed\n"); + exit(1); + } + free(new_blob); + free(base_buf); + free(overlay_buf); + return 0; +} diff --git a/tests/testdata/apply_fragment.add_dts b/tests/testdata/apply_fragment.add_dts new file mode 100644 index 0000000..7666089 --- /dev/null +++ b/tests/testdata/apply_fragment.add_dts @@ -0,0 +1,2 @@ +&a { d: d{}; }; +&b { e{}; }; diff --git a/tests/testdata/apply_fragment.base_dts b/tests/testdata/apply_fragment.base_dts new file mode 100644 index 0000000..c116a9b --- /dev/null +++ b/tests/testdata/apply_fragment.base_dts @@ -0,0 +1,6 @@ +/dts-v1/; +/ { + a: a {}; + b: b {}; + c: c {}; +}; diff --git a/tests/testdata/dtc_local_fixup.add_dts b/tests/testdata/dtc_local_fixup.add_dts new file mode 100644 index 0000000..b158cd7 --- /dev/null +++ b/tests/testdata/dtc_local_fixup.add_dts @@ -0,0 +1,5 @@ +&a { + c: c{ + d{ interrupt_parent = <&c>; }; + }; +}; diff --git a/tests/testdata/dtc_local_fixup.base_dts b/tests/testdata/dtc_local_fixup.base_dts new file mode 100644 index 0000000..f5a1086 --- /dev/null +++ b/tests/testdata/dtc_local_fixup.base_dts @@ -0,0 +1,8 @@ +/dts-v1/; +/ { +a: a { + interrupt_parent = <&a>; + }; +}; + + diff --git a/tests/testdata/libufdt_local_fixup.add_dts b/tests/testdata/libufdt_local_fixup.add_dts new file mode 100644 index 0000000..b158cd7 --- /dev/null +++ b/tests/testdata/libufdt_local_fixup.add_dts @@ -0,0 +1,5 @@ +&a { + c: c{ + d{ interrupt_parent = <&c>; }; + }; +}; diff --git a/tests/testdata/libufdt_local_fixup.add_ov_dts b/tests/testdata/libufdt_local_fixup.add_ov_dts new file mode 100644 index 0000000..2734141 --- /dev/null +++ b/tests/testdata/libufdt_local_fixup.add_ov_dts @@ -0,0 +1,11 @@ +/dts-v1/ /plugin/; +/ { + fragment@0 { + target = <&a>; + __overlay__ { + c: c{ + d{ interrupt_parent = <&c>; }; + }; + }; + }; +}; diff --git a/tests/testdata/libufdt_local_fixup.base_dts b/tests/testdata/libufdt_local_fixup.base_dts new file mode 100644 index 0000000..556e3dc --- /dev/null +++ b/tests/testdata/libufdt_local_fixup.base_dts @@ -0,0 +1,8 @@ +/dts-v1/; +/ { + a: a { + interrupt_parent = <&a>; + }; +}; + + diff --git a/tests/testdata/local_fixup_with_offset.add_dts b/tests/testdata/local_fixup_with_offset.add_dts new file mode 100644 index 0000000..f45757e --- /dev/null +++ b/tests/testdata/local_fixup_with_offset.add_dts @@ -0,0 +1,8 @@ +&a { + c: c{ + d{ interrupt_parent = <0 1 &c 2 3>; }; + }; + e: e{ + f{ interrupt_parent = <&c 5 &e>; }; + }; +}; diff --git a/tests/testdata/local_fixup_with_offset.base_dts b/tests/testdata/local_fixup_with_offset.base_dts new file mode 100644 index 0000000..f90145d --- /dev/null +++ b/tests/testdata/local_fixup_with_offset.base_dts @@ -0,0 +1,6 @@ +/dts-v1/; +/ { +a: a { + interrupt_parent = <&a>; + }; +}; diff --git a/tests/testdata/no_local_fixup.add_dts b/tests/testdata/no_local_fixup.add_dts new file mode 100644 index 0000000..2cdf6a4 --- /dev/null +++ b/tests/testdata/no_local_fixup.add_dts @@ -0,0 +1,3 @@ +&a { c = "new-c"; + d: d = "d"; +}; diff --git a/tests/testdata/no_local_fixup.base_dts b/tests/testdata/no_local_fixup.base_dts new file mode 100644 index 0000000..01bad36 --- /dev/null +++ b/tests/testdata/no_local_fixup.base_dts @@ -0,0 +1,7 @@ +/dts-v1/; +/ { + a: a { + b = "b"; + c = "c"; + }; + }; diff --git a/tests/testdata/overlay_2_layers.add_dts b/tests/testdata/overlay_2_layers.add_dts new file mode 100644 index 0000000..952a462 --- /dev/null +++ b/tests/testdata/overlay_2_layers.add_dts @@ -0,0 +1,7 @@ +&a { + g = "g"; + d { + f = "f"; + }; +}; + diff --git a/tests/testdata/overlay_2_layers.base_dts b/tests/testdata/overlay_2_layers.base_dts new file mode 100644 index 0000000..1d7b578 --- /dev/null +++ b/tests/testdata/overlay_2_layers.base_dts @@ -0,0 +1,11 @@ +/dts-v1/; +/ { + a: a { + b = "b"; + c = "c"; + d { + e = "e"; + }; + }; +}; + |