lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <1350979382-19983-2-git-send-email-steffen.schwigon@amd.com>
Date:	Tue, 23 Oct 2012 10:03:01 +0200
From:	<steffen.schwigon@....com>
To:	<linux-kernel@...r.kernel.org>
CC:	<ss5@...ormalist.net>, <srostedt@...hat.com>,
	<Dariusz.Filipski@...arch.com>,
	<yoshitake.kobayashi@...hiba.co.jp>, <sassmann@...hat.com>,
	<andre.przywara@....com>, <frank.arnold@....com>,
	<conny.seidel@....com>, <csd@...adcom.com>,
	Steffen Schwigon <steffen.schwigon@....com>
Subject: [PATCH 1/2] bash-test-utils: support writing functional tests

From: Steffen Schwigon <steffen.schwigon@....com>

It provides utility functions and facilities to write tests in
baremetal and Xen/KVM contexts (host and guest support) and was
polished to work with i686, x86_64, and ARM under lots of major
Linux distributions (Debian, Ubuntu, RHEL, SLES, Slackware,
Fedora, openSUSE).

It can be run as normal bash script or indirectly via the "prove"
command, a standard Linux tool to run test scripts.

Synopsis:

  $ cd /usr/src/linux

  $ cat t/my-feature-test.t
  #! /bin/bash
  . tools/testing/tap/bash-test-utils
  test_feature_foo
  ok $? "feature foo"
  done_testing

  $ prove -v t/my-feature-test.t

Signed-off-by: Steffen Schwigon <steffen.schwigon@....com>
Signed-off-by: Andre Przywara <andre.przywara@....com>
Signed-off-by: Frank Arnold <frank.arnold@....com>
Signed-off-by: Conny Seidel <conny.seidel@....com>
Signed-off-by: Christian Daudt <csd@...adcom.com>
---
 tools/testing/tap/bash-test-utils     | 1508 +++++++++++++++++++++++++++++++++
 tools/testing/tap/bash-test-utils.txt |  320 +++++++
 2 files changed, 1828 insertions(+)
 create mode 100755 tools/testing/tap/bash-test-utils
 create mode 100644 tools/testing/tap/bash-test-utils.txt

diff --git a/tools/testing/tap/bash-test-utils b/tools/testing/tap/bash-test-utils
new file mode 100755
index 0000000..68661dd
--- /dev/null
+++ b/tools/testing/tap/bash-test-utils
@@ -0,0 +1,1508 @@
+#! /bin/bash
+
+# bash-test-utils -- an include file to support writing test scripts.
+#
+# --------------------------------------------------------------------
+#
+# It provides utility functions and facilities to write tests in
+# baremetal and Xen/KVM contexts (host and guest support) and was
+# polished to work with i686, x86_64, and ARM under lots of major
+# Linux distributions (Debian, Ubuntu, RHEL, SLES, Slackware,
+# Fedora, openSUSE).
+#
+# It can be run as normal bash script or indirectly via the "prove"
+# command, a standard Linux tool to run test scripts.
+#
+# Synopsis:
+#
+#   $ cd /usr/src/linux
+#
+#   $ cat > t/my-feature-test.t
+#   #! /bin/bash
+#   . tools/testing/tap/bash-test-utils
+#   test_feature_foo
+#   ok $? "feature foo worked"
+#   done_testing
+#
+#   $ prove -v t/my-feature-test.t
+#
+# --------------------------------------------------------------------
+#
+# Copyright (c) 2009-2012, Advanced Micro Devices, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+
+
+# ==================== Utility functions =============================
+
+# constants
+_SUCCESS=0
+_FAILURE=1
+
+# gets vendor "AMD" or "Intel" from /proc/cpuinfo
+get_vendor () {
+    vendor=$(echo $(grep vendor_id /proc/cpuinfo |head -1|cut -d: -f2|sed -e "s/Genuine\|Authentic//"))
+    echo $vendor
+}
+
+# checks for vendor "Intel" in /proc/cpuinfo
+vendor_intel () {
+    grep -Eq 'vendor_id.*:.*Intel' /proc/cpuinfo
+}
+
+# checks for vendor "AMD" in /proc/cpuinfo
+vendor_amd () {
+    grep -Eq 'vendor_id.*:.*AMD' /proc/cpuinfo
+}
+
+# stops testscript if not matching required cpu vendor
+require_vendor_intel () {
+    if vendor_intel
+    then
+        if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok 0 "require_vendor_intel" ; fi
+        return $_SUCCESS
+    else
+        explanation="${1:-vendor does not match Intel}"
+        autoreport_skip_all "$explanation"
+    fi
+}
+
+# stops testscript if not matching required cpu vendor
+require_vendor_amd () {
+    if vendor_amd
+    then
+        if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok 0 "require_vendor_amd" ; fi
+        return $_SUCCESS
+    else
+        explanation="${1:-vendor does not match AMD}"
+        autoreport_skip_all "$explanation"
+    fi
+}
+
+# Checks for ARM cpu
+arm_cpu () {
+    grep -Eqi 'Processor.*:.*ARM' /proc/cpuinfo
+}
+
+# outputs cpu stepping from /proc/cpuinfo
+get_cpu_stepping () {
+    echo $(echo $(grep "^stepping" /proc/cpuinfo |head -1|cut -d: -f2))
+}
+# outputs cpu model from /proc/cpuinfo
+get_cpu_model () {
+    echo $(echo $(grep "^model[^ ]" /proc/cpuinfo |head -1|cut -d: -f2))
+}
+
+# outputs cpu model from /proc/cpuinfo
+get_cpu_model_hex () {
+    echo "0x"$(get_hex_from_int $(get_cpu_model))
+}
+
+# checks cpu model from /proc/cpuinfo against a minimum model
+cpu_model_min () {
+    min=${1:-0}
+    mod=$(get_cpu_model)
+    [ $(($mod)) -ge $(($min)) ]
+}
+
+# checks cpu model from /proc/cpuinfo against a maximum model
+cpu_model_max () {
+    max=${1:-0x999}
+    mod=$(get_cpu_model)
+    [ $(($mod)) -le $(($max)) ]
+}
+
+# outputs cpu family from /proc/cpuinfo
+# since all testsuites using hex values, return value in hex format
+get_cpu_family () {
+    echo $(echo $(grep "^cpu family" /proc/cpuinfo |head -1|cut -d: -f2))
+}
+
+get_cpu_family_hex () {
+    echo "0x"$(get_hex_from_int $(get_cpu_family))
+}
+
+# checks cpu family from /proc/cpuinfo against a minimum family
+cpu_family_min () {
+    min=${1:-0}
+    fam=$(get_cpu_family)
+    [ $(($fam)) -ge $(($min)) ]
+}
+
+# checks cpu family from /proc/cpuinfo against a maximum family
+cpu_family_max () {
+    max=${1:-0x999}
+    fam=$(get_cpu_family)
+    [ $(($fam)) -le $(($max)) ]
+}
+
+is_amd_family_range () {
+    min="${1:-0}"
+    max="${2:-$min}"
+    if vendor_amd && cpu_family_min "$min" && cpu_family_max "$max" ; then
+        return $_SUCCESS
+    else
+        return $_FAILURE
+    fi
+}
+
+# stops testscript if not matching required cpu family from
+# /proc/cpuinfo of a minimum/maximum range
+require_amd_family_range () {
+    min="${1:-0}"
+    max="${2:-$min}"
+    if is_amd_family_range "$min" "$max" ; then
+        if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok 0 "require_amd_family_range $min $max" ; fi
+        return $_SUCCESS
+    else
+        vendor=$(get_vendor);
+        fam=$(printf "0x%x" $(get_cpu_family));
+        explanation="${3:-Family $vendor/$fam does not match AMD/$min..$max}"
+        autoreport_skip_all "$explanation"
+    fi
+}
+
+# Checks all nodes for NB devices with one of the supplied PCI device ids
+# Note: Call it separately for different PCI device functions
+has_amd_nb_function_id () {
+    devids=${@:-"0xffffffff"}
+
+    for devid in $devids; do
+        devid=$(printf '0x%x' $devid)
+        nbdevs="/sys/bus/pci/devices/0000:00:1[89abcdef].*"
+
+        [ $(ls $nbdevs 2>/dev/null | wc -l) -gt 0 ] || continue
+
+        f0devs="/sys/bus/pci/devices/0000:00:1[89abcdef].0/vendor"
+        northbridges=$(ls $f0devs 2>/dev/null | wc -l)
+
+        devices=0
+        for nbdev in $nbdevs; do
+            vendor=$(cat $nbdev/vendor 2>/dev/null)
+            if [ "$vendor" != "0x1022" ]; then
+                return $_FAILURE
+            fi
+
+            device=$(cat $nbdev/device 2>/dev/null)
+            if [ "$device" = "$devid" ]; then
+                let devices++
+            fi
+        done
+
+        if [ $devices -gt 0 -a $devices -eq $northbridges ]; then
+            return $_SUCCESS
+        fi
+    done
+
+    return $_FAILURE
+}
+
+# Stops if no NB devices with one of supplied PCI device ids exist on all nodes
+# Note: Call it separately for different PCI device functions
+require_amd_nb_function_id () {
+    devids=${@:-"0xffffffff"}
+    if has_amd_nb_function_id "$devids"; then
+        if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_amd_nb_function_id" ; fi
+    else
+        autoreport_skip_all "No supported AMD northbridge function devices"
+    fi
+}
+
+get_number_cpus () {
+    (getconf _NPROCESSORS_ONLN || grep -ci "^bogomips" /proc/cpuinfo || echo -1) 2>/dev/null
+}
+
+# check sysfs whether cpu has L3 cache
+has_l3cache () {
+    if [ -d /sys/devices/system/cpu/cpu0/cache/index3 ] ; then
+        return $_SUCCESS
+    else
+        return $_FAILURE
+    fi
+}
+
+# stops testscript if cpu does not have L3 cache
+require_l3cache () {
+    explanation="${1:-No L3 cache}"
+    if has_l3cache ; then
+        if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_l3cache" ; fi
+        return $_SUCCESS
+    else
+        autoreport_skip_all "$explanation"
+    fi
+}
+
+# check x86_64
+is_x86_64 () {
+    if uname -m | grep -q x86_64 ; then
+        return $_SUCCESS
+    else
+        return $_FAILURE
+    fi
+}
+
+# stops testscript if is not x86_64
+require_x86_64 () {
+    explanation="${1:-No x86_64}"
+    if is_x86_64 ; then
+        if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_x86_64" ; fi
+        return $_SUCCESS
+    else
+        autoreport_skip_all "$explanation"
+    fi
+}
+
+# scan all PCI devices for one with XenSource's PCI-ID
+has_xen_pci_device() {
+    # try lspci (not in PATH if not root)
+    _ta_xen_LSPCI=$(which lspci 2> /dev/null) || _ta_xen_LSPCI=/sbin/lspci
+    if [ -x "$_ta_xen_LSPCI" ]
+    then
+        $_ta_xen_LSPCI -n | grep -q " 5853:"
+        return $?
+    else
+        # directly query sysfs and check for XenSource's PCI-ID
+        if [ -r /sys/bus/pci/devices/0000:00:00.0/vendor ] ; then
+            cat /sys/bus/pci/devices/*/vendor | grep -q 0x5853
+            return $?
+        else
+            return $_FAILURE
+        fi
+    fi
+}
+
+# checks the PCI hostbridge's vendor and optionally device ID
+# usage: check_hostbridge 0x1022 (for checking for AMD northbridge)
+#        check_hostbridge 0x8086 0x1237 (for QEMU host bridge)
+check_hostbridge() (
+    LSPCI=$(which lspci 2> /dev/null) || LSPCI=/sbin/lspci
+    if [ -x "$LSPCI" ]
+    then
+        lspciout=$($LSPCI -s 0:0.0 -n | cut -d: -f3- | tr -d \ )
+        vendor="0x$(echo $lspciout | cut -d: -f1)"
+        device="0x$(echo $lspciout | cut -d: -f2)"
+    else
+        vendor=$(cat /sys/bus/pci/devices/0000:00:00.0/vendor)
+        device=$(cat /sys/bus/pci/devices/0000:00:00.0/device)
+    fi
+    [ "$vendor" = "$1" ] || return $_FAILURE
+    [ -z "$2" ] && return $_SUCCESS
+    [ "$device" = "$2" ]
+    return $?
+)
+
+# checks whether the Xen hypervisor is running
+# this returns 0 if we are a Dom0 or PV DomU or HVM DomU
+is_running_under_xen_hv () {
+    if [ -r /sys/hypervisor/type ] ; then
+        [ $(cat /sys/hypervisor/type) = "xen" ]
+        return $?
+    fi
+
+    [ -r /proc/xen/capabilities ] && return $_SUCCESS
+
+    # Linux denies registering XenFS if not running under Xen
+    if has_kernel_config CONFIG_XENFS ; then
+        grep -q xenfs /proc/filesystems
+        return $?
+    fi
+
+    # TODO: do older kernels support this? At least RHEL5 does
+    has_cpufeature hypervisor || return $_FAILURE
+
+    _ta_e820prov=$(dmesg | sed -e 's/^\[.*\] *//' | grep -A1 "^BIOS-provided physical RAM map:" | tail -1 | cut -d: -f1)
+    [ -n "$_ta_820prov" ] && [ "$_ta_e820prov" = "Xen" ] && return $_SUCCESS
+
+    dmesg | grep -q "Booting paravirtualized kernel on Xen" && return $_SUCCESS
+
+    return $_FAILURE
+}
+
+# check if we are in a Xen host
+# it is a bit tricky to differentiate Dom0 and (PV-)DomU
+is_running_in_xen_dom0 () {
+
+    # this is a definite way to check for Dom0, but not always available, since
+    # XENFS could not be mounted
+    if [ -r /proc/xen/capabilities ] ; then
+        grep -q control_d /proc/xen/capabilities
+        return $?
+    fi
+
+    # this should sort out most of the other possibilities
+    is_running_under_xen_hv || return $_FAILURE
+
+    # we need to sort out only Dom0 vs. DomU from now on
+
+    # an ATI or AMD northbridge means Dom0
+    if check_hostbridge 0x1002 || check_hostbridge 0x1022 ; then
+        return $_SUCCESS
+    fi
+
+    # a QEMU northbridge cannot be Dom0
+    check_hostbridge 0x8086 0x1237 && return $_FAILURE
+
+    # out of clues, but we are probably not Dom0 at this point anymore
+    return $_FAILURE
+}
+
+# check if we are in a KVM host
+is_running_in_kvm_host () {
+    [ -e /dev/kvm ]
+}
+
+# check if we have KVM guests running
+has_kvm_guests () {
+    counter=$(lsmod |grep '^kvm_'|awk '{print $3}')
+    if [ $counter -gt 0 ] ; then
+        return $_SUCCESS
+    else
+        return $_FAILURE
+    fi
+}
+
+get_xen_tool() {
+    which xl 2> /dev/null || which xm 2> /dev/null
+}
+
+get_number_xen_guests() {
+    XL=$(get_xen_tool) || return $_FAILURE
+    res=$($XL list | wc -l)
+    if [ -n "$res" -a "$res" -ge 2 ] ; then
+        echo "$((res-2))"
+        return $_SUCCESS
+    else
+        echo "0"
+        return $_FAILURE
+    fi
+}
+
+# check if we are in a Xen guest
+# Note:
+#   In Xen the dom0 reports the same 'hypervisor' flag and CPUID entry
+#   as in domU therefore the CPUID check is not enough, but dmidecode
+#   and lspci show different devices inside a domU.
+is_running_in_xen_guest () {
+
+    is_running_under_xen_hv || return $_FAILURE
+
+    has_xen_pci_device && return $_SUCCESS
+
+    check_hostbridge 0x8086 0x1237 && return $_SUCCESS
+
+    # try dmidecode
+    if dmidecode > /dev/null 2>&1 ; then
+        _dmi_chassis=$(dmidecode -s chassis-manufacturer)
+        # dmidecode does not output anything in PV Xen
+        if [ -n "$_dmi_chassis" ] ; then
+            echo "$_dmi_chassis" | grep -q Xen
+            return $?
+        fi
+    fi
+
+    # last resort: check for Xen Dom0
+    is_running_in_xen_dom0 && return $_FAILURE
+
+    # there are no PCI device by default in PV guests
+    _nr_pci_devices=$(ls /sys/bus/pci/devices | wc -l)
+    [ "$_nr_pci_devices" -eq 0 ] && return $_SUCCESS
+
+    # no more clues at this point, assume we are some kind of DomU
+    return $_SUCCESS
+}
+
+# check if we are in a KVM guest
+# Note:
+#   In KVM the hypervisor CPUID check is relieable and we can first
+#   narrow it against being not a Xen guest. After that the devices
+#   are less significant in KVM so here we then check for the CPUID.
+is_running_in_kvm_guest () {
+
+    is_running_in_xen_guest && return $_FAILURE
+    has_cpufeature hypervisor || return $_FAILURE
+
+    # try to load the cpuid module if not already done
+    [ -c /dev/cpu/0/cpuid ] || modprobe cpuid > /dev/null 2>&1
+
+    if [ -c /dev/cpu/0/cpuid ] ; then
+        virtvendor=$(dd if=/dev/cpu/0/cpuid bs=16 skip=67108864 count=1 2> /dev/null)
+        [ "$virtvendor" = "KVMKVMKVM" ]
+        return $?
+    fi
+    return 1
+}
+
+# check if we are in a virtualized guest (Xen or KVM)
+is_running_in_virtualized_guest () {
+    is_running_in_xen_guest || is_running_in_kvm_guest
+    return $?
+}
+
+# stops testscript if we aren't a Xen guest
+require_running_in_xen_guest () {
+    explanation="${1:-Needs to run in Xen guest}"
+    if is_running_in_xen_guest ; then
+        if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_running_in_xen_guest" ; fi
+        return $_SUCCESS
+    else
+        autoreport_skip_all "$explanation"
+    fi
+}
+
+# stops testscript if we aren't a Xen dom0
+require_running_in_xen_dom0 () {
+    explanation="${1:-Needs to run in Xen dom0}"
+    if is_running_in_xen_dom0 ; then
+        if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_running_in_xen_dom0" ; fi
+        return $_SUCCESS
+    else
+        autoreport_skip_all "$explanation"
+    fi
+}
+
+# stops testscript if we aren't a KVM guest
+require_running_in_kvm_guest () {
+    explanation="${1:-Needs to run in KVM guest}"
+    if is_running_in_kvm_guest ; then
+        if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_running_in_kvm_guest" ; fi
+        return $_SUCCESS
+    else
+        autoreport_skip_all "$explanation"
+    fi
+}
+
+# stops testscript if we aren't a KVM host
+require_running_in_kvm_host () {
+    explanation="${1:-Needs to run in KVM host}"
+    if is_running_in_kvm_host ; then
+        if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_running_in_kvm_host" ; fi
+        return $_SUCCESS
+    else
+        autoreport_skip_all "$explanation"
+    fi
+}
+
+# stops testscript if we aren't a virtualized guest
+require_running_in_virtualized_guest () {
+    explanation="${1:-Needs to run in virtualized guest}"
+    if is_running_in_virtualized_guest ; then
+        if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_running_in_virtualized_guest" ; fi
+        return $_SUCCESS
+    else
+        autoreport_skip_all "$explanation"
+    fi
+}
+
+# checks for a feature flag in /proc/cpuinfo
+has_cpufeature () {
+    _ta_feature="${1:-UNKNOWNFEATURE}"
+    if cat /proc/cpuinfo | grep -E '^flags\W*:' | head -1 | sed -e 's/^flags\W*://' | grep -q "\<${_ta_feature}\>" 2>&1 ; then
+        return $_SUCCESS
+    else
+        return $_FAILURE
+    fi
+}
+
+# stops testscript if a feature flag is not found in /proc/cpuinfo
+require_cpufeature () {
+    _ta2_feature="${1:-UNKNOWNFEATURE}"
+    explanation="${2:-Missing cpufeature $_ta2_feature}"
+    if has_cpufeature "$_ta2_feature" ; then
+        if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_cpufeature $_ta2_feature" ; fi
+        return $_SUCCESS
+    else
+        autoreport_skip_all "$explanation"
+    fi
+}
+
+# checks for a config in /proc/config.gz or /boot/config/$(uname -r)
+has_kernel_config () {
+    _ta3_feature="${1:-UNKNOWNFEATURE}"
+    CONFIG=$(get_first_file "/proc/config.gz" "/boot/config-$(uname -r)")
+    if [ -z "$CONFIG" ] ; then
+        return $_FAILURE
+    fi
+    if echo $CONFIG | grep -q '\.gz' ; then
+        gzip -cd "$CONFIG" | grep -q "^${_ta3_feature}=."
+    else
+        grep -q "^${_ta3_feature}=." "$CONFIG"
+    fi
+}
+
+# stops testscript if a feature flag is not found in /proc/cpuinfo
+require_kernel_config () {
+    _ta4_feature="${1:-UNKNOWNFEATURE}"
+    explanation="${2:-Missing kernel config $_ta4_feature}"
+    if has_kernel_config "$_ta4_feature" ; then
+        if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_kernel_config $_ta4_feature" ; fi
+        return $_SUCCESS
+    else
+        autoreport_skip_all "$explanation"
+    fi
+}
+
+# Enable CPU frequency scaling and set sane defaults
+# - Makes sure the appropriate cpufreq driver is loaded
+# - Enables ondemand governor on all cores
+# - Sets the boost state, on=1 (default), off=0
+enable_cpufreq () {
+    booststate="$1"
+    [ "$booststate" != "0" ] && booststate=1
+
+    # Load cpufreq driver module
+    for module in acpi-cpufreq powernow-k8; do
+        [ -d /sys/devices/system/cpu/cpu0/cpufreq ] && break
+        modprobe $module 2>/dev/null
+    done
+    if [ ! -d /sys/devices/system/cpu/cpu0/cpufreq ]; then
+        echo "failed to load cpufreq driver"
+        return $_FAILURE
+    fi
+
+    # Load ondemand governor module and set ondemand governor
+    if ! grep -q ondemand /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors; then
+        modprobe cpufreq-ondemand 2>/dev/null
+    fi
+    for cpu in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do
+        echo ondemand > $cpu 2>/dev/null
+        if [ "$(cat $cpu)" != "ondemand" ]; then
+            echo "failed to set ondemand governor"
+            return $_FAILURE
+        fi
+    done
+
+    # Set requested boost state
+    if ! has_cpufeature cpb; then
+        return $_SUCCESS
+    elif [ -f /sys/devices/system/cpu/cpufreq/boost ]; then
+        interfaces="/sys/devices/system/cpu/cpufreq/boost"
+    elif [ $(ls /sys/devices/system/cpu/cpu*/cpufreq/cpb 2>/dev/null | wc -l) -gt 0 ]; then
+        interfaces="/sys/devices/system/cpu/cpu*/cpufreq/cpb"
+    elif grep -q " show_cpb\| show_global_boost" /proc/kallsyms; then
+        echo "failed to find sysfs boost state interface"
+        return $_FAILURE
+    elif [ $booststate -eq 0 ]; then
+        echo "cpufreq driver doesn't provide sysfs boost state interface"
+        return $_FAILURE
+    else
+        return $_SUCCESS
+    fi
+    for interface in $interfaces; do
+       echo $booststate > $interface 2>/dev/null
+       if [ "$(cat $interface)" != "$booststate" ]; then
+            echo "failed to set requested boost state"
+            return $_FAILURE
+       fi
+    done
+
+    return $_SUCCESS
+}
+
+require_cpufreq_enabled () {
+    explanation="${1:-CPUFreq not available}"
+    reason=$(enable_cpufreq 1)
+    if [ $? -eq $_SUCCESS ] ; then
+        if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_cpufreq_enabled" ; fi
+        return $_SUCCESS
+    else
+        autoreport_skip_all "$explanation ($reason)"
+    fi
+}
+
+require_cpb_disabled () {
+    explanation="${1:-Failed to disable Core Boosting}"
+    reason=$(enable_cpufreq 0)
+    if [ $? -eq $_SUCCESS ] ; then
+        if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_cpufreq_enabled" ; fi
+        return $_SUCCESS
+    else
+        autoreport_skip_all "$explanation ($reason)"
+    fi
+}
+
+request_cpufreq_enabled () {
+    todo="# TODO $(enable_cpufreq 1)" && todo=""
+    ok $? "request_cpufreq_enabled $todo"
+    [ -n "$todo" ] && return $_FAILURE
+    return $_SUCCESS
+}
+
+request_cpb_disabled () {
+    todo="# TODO $(enable_cpufreq 0)" && todo=""
+    ok $? "request_cpb_disabled $todo"
+    [ -n "$todo" ] && return $_FAILURE
+    return $_SUCCESS
+}
+
+# disables core performance boosting for reproducable and well scaling
+# benchmarks. Tries hard to learn the actual state and to really disable
+# it. Diagnostic messages will be print to stdout, the return value
+# describes the success: 0=CPB is disabled, 1=CPB is (probably) still enabled.
+# possible usage (failed disabling is non-fatal, but report it):
+#   todostem="# TODO "
+#   expl=$(disable_cpb) && todostem=""
+#   ok $? "disable CPB $todostem$expl"
+# or a fatal version ending the script:
+#   expl=$(disable_cpb)
+#   require_ok $? "disable CPB"
+# or: just try to disable it, but don't care if we fail
+#   disable_cpb > /dev/null
+disable_cpb() {
+    # check whether the CPB sysfs knob is there
+    if [ ! -r /sys/devices/system/cpu/cpu0/cpufreq/cpb ] ; then
+        is_running_in_virtualized_guest && _cpbhint=" (running virtualized)"
+        # if the CPU does not support boosting, we dont care
+        if ! has_cpufeature cpb ; then
+            echo "# CPU has no CPB support$_cpbhint"
+            return 0
+        fi
+        # is the powernow_k8 driver loaded?
+        if ! grep -q " powernowk8_init" /proc/kallsyms; then
+            # if not, try to load it
+            if ! _modprobe_res=$(modprobe powernow_k8 2>&1) ; then
+                echo "# modprobe powernow_k8: $_modprobe_res"
+                return 1
+            fi
+        fi
+        # does this version of powernow_k8 support CPB?
+        if ! grep -q " show_cpb" /proc/kallsyms ; then
+            echo "# powernow_k8 loaded, but no CPB support"
+            return 1
+        fi
+    fi
+    # now check for the sysfs knob again (we may have loaded the driver)
+    if [ ! -r /sys/devices/system/cpu/cpu0/cpufreq/cpb ] ; then
+        echo "# no sysfs knob for disabling CPB, probably still active"
+        return 1
+    fi
+
+    # if the knob is there and it reads 0, everything is fine
+    if [ $(cat /sys/devices/system/cpu/cpu0/cpufreq/cpb) = "0" ] ; then
+        echo "# CPB already disabled"
+        return 0
+    fi
+    # try to disable CPB on all cores and count the number of failures
+    failures=0
+    for cpb in /sys/devices/system/cpu/cpu*/cpufreq/cpb; do
+        echo 0 2> /dev/null > $cpb || let failures++
+    done
+    # no failures means everything is fine
+    if [ "$failures" = 0 ] ; then
+        echo "# CPB successfully disabled"
+        return 0
+    fi
+    # don't give up so quickly, try to explore dmesg for the right message
+    if $(dmesg | grep -q "Core Boosting .*abled") ; then
+        # there was at least one messages, check the last one
+        if dmesg | grep -q "Core Boosting .*abled" | tail -1 | grep -q "Core Boosting disabled" ; then
+            # the last message says its disabled, believe this
+            echo "# CPB disabling failed, but probably disabled before"
+            return 0
+        else
+            # the last message says its enabled, we failed eventually
+            echo "# CPB disabling failed (no permissions), CPB active"
+            return 1
+        fi
+    fi
+    # we have no real clue at this point, but assume the worst
+    echo "# CPB disabling failed, probably still active"
+    return 1
+}
+
+# checks whether the cpbdisable file exists in sysfs
+has_cpbdisable () {
+    # This file's existence is not the best check.
+    # It also exists on non-cpb systems.
+    if [ -e /sys/devices/system/cpu/cpu0/cpufreq/cpb ] ; then
+        return $_SUCCESS
+    else
+        return $_FAILURE
+    fi
+}
+
+# stops testscript if the cpbdisable file does not exist in sysfs
+require_cpbdisable () {
+    explanation="${1:-No CPB disable}"
+    if has_cpbdisable ; then
+        if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_cpbdisable" ; fi
+        return $_SUCCESS
+    else
+        autoreport_skip_all "$explanation"
+    fi
+}
+
+# checks whether the module is ther
+has_module () {
+    module="${1:-UNKNOWNMODULE}"
+    if lsmod | grep -q "^$module\b" ; then
+        return $_SUCCESS
+    else
+        return $_FAILURE
+    fi
+}
+
+# stops testscript if the cpbdisable file does not exist in sysfs
+require_module () {
+    module="${1:-UNKNOWNMODULE}"
+    explanation="${2:-No module $module disable}"
+    if has_module "$module"; then
+        if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_module" ; fi
+        return $_SUCCESS
+    else
+        autoreport_skip_all "$explanation"
+    fi
+}
+
+# checks whether the program is available
+has_program () {
+    program="${1:-UNKNOWNPROGRAM}"
+    if which "$program" > /dev/null 2>&1 ; then
+        return $_SUCCESS
+    else
+        return $_FAILURE
+    fi
+}
+
+# stops testscript if program not available
+require_program () {
+    program="${1:-UNKNOWNPROGRAM}"
+    explanation="${2:-Missing program $program}"
+    if has_program "$program" ; then
+        return $_SUCCESS
+    else
+        autoreport_skip_all "$explanation"
+    fi
+}
+
+# checks whether the file is available
+has_file () {
+    file="${1:-UNKNOWNFILE}"
+    explanation="${2:-Missing file $file}"
+    if [ -e "$file" ] ; then
+        return $_SUCCESS
+    else
+        return $_FAILURE
+    fi
+}
+
+# stops testscript if file not available
+require_file () {
+    file="${1:-UNKNOWNFILE}"
+    explanation="${2:-Missing file $file}"
+    if has_file "$file" ; then
+        if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_file $file" ; fi
+        return $_SUCCESS
+    else
+        autoreport_skip_all "$explanation"
+    fi
+}
+
+# checks whether the script's criticality is in allowed range
+has_crit_level () {
+    _ta_crit_level="${1:-5}"
+    _ta_crit_level_allowed="${CRITICALITY:-0}"
+    if [ $_ta_crit_level -le $_ta_crit_level_allowed ] ; then
+        return $_SUCCESS;
+    else
+        return $_FAILURE
+    fi
+}
+
+# stops testscript if script's criticality is not in allowed range
+require_crit_level () {
+    _ta_crit_level="${1:-5}"
+    _ta_crit_level_allowed="${CRITICALITY:-0}"
+    explanation="${2:-Too high criticality level: $_ta_crit_level (CRITICALITY=$_ta_crit_level_allowed)}"
+
+    if has_crit_level $_ta_crit_level ; then
+        if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "criticality level $_ta_crit_level (CRITICALITY=$_ta_crit_level_allowed)" ; fi
+        return $_SUCCESS
+    else
+        autoreport_skip_all "$explanation"
+    fi
+}
+
+require_root () {
+    explanation="${1:-Need to run as root}"
+    ID=$(id|cut -d" " -f1|cut -d= -f2|cut -d\( -f1)
+    if [ "x$ID" == "x0" ] ; then
+        if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_root" ; fi
+        return $_SUCCESS
+    else
+        autoreport_skip_all "$explanation"
+    fi
+}
+
+get_first_file () {
+    for i in $(seq 1 $#) ; do
+        file=${!i}
+        if [ -r "$file" ] ; then
+            echo "$file"
+            return
+        fi
+    done
+}
+
+# checks whether MSRs could be read from userspace
+# will try to load the appropriate kernel module if not already done
+# will return an error if the file is not readable (not root)
+has_msr_access() (
+    cpu=${1:-0}
+    if [ ! -e /dev/cpu/$cpu/msr ] ; then
+        has_program modprobe || return 1
+        modprobe msr || return 1
+    fi
+    [ -r /dev/cpu/$cpu/msr ]
+)
+
+# reads a MSR via the /dev/cpu/<n>/msr device
+# expects the MSR number (in hex) as the first parameter and optionally the
+# CPU number from which to read as the second argument (defaults to 0)
+# outputs a 16 char hex value (lower case letters) to stdout
+# returns 0 on success, 1 for an invalid MSR and 2 for permission issues
+read_msr() (
+    cpu=${2:-0}
+    if has_program rdmsr ; then
+        rdmsr -x -0 -p $cpu "$1" 2> /dev/null
+        return $?
+    fi
+    [ -r /dev/cpu/$cpu/msr ] || return 2
+
+    perl -e 'my $msr;sysseek(STDIN,hex($ARGV[0]),0);sysread(STDIN,$msr,8) or exit(1);my @words=unpack("LL",$msr);printf("%08x%08x\n",$words[1],$words[0]);' $1 < /dev/cpu/$cpu/msr
+)
+
+# writes a MSR via the /dev/cpu/<n>/msr device
+# expects the MSR number (in hex) as the first parameter, the value (in hex)
+# is the second one. Optionally the CPU number to use for the write can be
+# given as the third argument (defaults to 0)
+# returns 0 on success, 1 for an invalid MSR and 2 for permission issues
+write_msr() (
+    [ $# -lt 2 ] && return 3
+    cpu=${3:-0}
+    if has_program wrmsr ; then
+        wrmsr -p $cpu "$1" "$2" 2> /dev/null
+        return $?
+    fi
+    [ -w /dev/cpu/$cpu/msr ] || return 2
+    low=$(printf "0x%x" $(($2 & (2**32 - 1))))
+    high=$(printf "0x%x" $((($2 >> 32) & (2**32 - 1))))
+    perl -e 'my $value=pack("LL",hex($ARGV[1]),hex($ARGV[2]));sysseek(STDOUT,hex($ARGV[0]),0);syswrite(STDOUT,$value,8) or exit(1);' $1 $low $high > /dev/cpu/$cpu/msr
+)
+
+# Reads an entire cpuid register
+# Usage: get_cpuid_register <leafnr_in_hex> e[abcd]x
+# Example: get_cpuid_register 0x80000001 ecx
+# Outputs the decimal register value to stdout
+# Returns 0 for success, 1 for invalid cpuid leaf, 2 for permission
+get_cpuid_register() {
+    [ $# -lt 2 ] && return 3
+    cpu=${3:-0}
+
+    # try to load the cpuid module if not already done
+    [ -c /dev/cpu/$cpu/cpuid ] || modprobe cpuid > /dev/null 2>&1
+    [ -r /dev/cpu/$cpu/cpuid ] || return 2
+
+    perl -e 'my $leaf;sysseek(STDIN, hex($ARGV[0]),0);sysread(STDIN,$leaf,16) or exit(1);my @regs=unpack("LLLL",$leaf);printf("%u\n",$regs[ord(substr($ARGV[1],1,1))-ord("a")]);' $1 $2 < /dev/cpu/$cpu/cpuid
+}
+
+# Reads a cpuid register and filters a certain bit
+# Usage: get_cpuid_bit <leafnr_in_hex> e[abcd]x <bitnr>
+# Example: get_cpuid_bit 0x80000001 ecx 2
+# Outputs either 0 or 1 to stdout
+# Returns 0 for success, 1 for invalid cpuid leaf, 2 for permission
+get_cpuid_bit() {
+    [ $# -lt 3 ] && return 3
+    cpu=${4:-0}
+    reg=$(get_cpuid_register $1 $2 $4) || return $?
+
+    echo $(($reg >> $3 & 1))
+}
+
+# Get a space separated list of CPUs from a sysfs cpumap file
+# Example:
+#   get_cpus_from_cpumap /sys/devices/system/node/node0/cpumap
+#   0 1 2 3
+# Notes:
+#   Result may be an empty string
+#   Result may be -1 in case of parsing errors
+get_cpus_from_cpumap () {
+    cpumap="${1}"
+    cpus=""
+    wordcnt=$(cat $cpumap | sed -e 's/,/ /g' | wc -w)
+
+    if [ $wordcnt -eq 0 ]; then
+        echo -1
+        return
+    fi
+
+    for i in $(seq $wordcnt -1 1); do
+        offset=$(($wordcnt - $i))
+        word=$((0x$(cat $cpumap | cut -d , -f $i)))
+        if [ $? -ne 0 ]; then cpus=-1; break; fi
+        for j in $(seq 0 31); do
+            if [ $(($word >> $j & 1 )) -eq 1 ]; then
+                cpus="$cpus $((32 * $offset + $j))"
+            fi
+        done
+    done
+
+    echo $cpus
+}
+
+# Get a space separated list of CPUs from a sysfs cpulist file
+# Example:
+#   get_cpus_from_cpulist /sys/devices/system/cpu/online
+#   0 1 2 3
+# Notes:
+#   Result may be an empty string
+#   Result may be -1 in case of parsing errors
+get_cpus_from_cpulist () {
+    cpulist="${1}"
+    cpus=""
+    ranges=$(cat $cpulist | sed -e 's/,/ /g')
+
+    if [ -z "$ranges" ]; then
+        echo -1
+        return
+    fi
+
+    for range in $ranges; do
+        if echo $range | grep -q '^[0-9]\+-[0-9]\+$'; then
+            min=$(echo $range | sed 's/-[0-9]\+$//')
+            max=$(echo $range | sed 's/^[0-9]\+-//')
+            if [ $min -ge $max ]; then cpus=-1; break; fi
+            for cpu in $(seq $min $max); do cpus="$cpus $cpu"; done
+        elif echo $range | grep -q '^[0-9]\+$'; then
+            cpus="$cpus $range"
+        else
+            cpus=-1; break
+        fi
+    done
+
+    echo $cpus
+}
+
+autoreport_skip_all () {
+    explanation="${1:-'no explanation'}"
+    SKIPALL="1..0 # skip $explanation"
+    autoreport_start
+    exit 0
+}
+
+# ==================== TAP utils ====================
+
+get_tap_counter () {
+     echo ${#TAP[@]}
+}
+
+get_tapdata_counter () {
+     echo ${#TAPDATA[@]}
+}
+
+append_tap () {
+    tapline="${1:-'not ok - unknown TAP line in utility function append_tap'}"
+    TAP=( "${TAP[@]}" "$tapline" )
+}
+
+append_tapdata () {
+    tapline="${1:-'not ok - unknown TAP line in utility function append_tapdata'}"
+    TAPDATA=( "${TAPDATA[@]}" "$tapline" )
+}
+
+append_comment () {
+    tapline="# ${@:-''}"
+    TAP=( "${TAP[@]}" "$tapline" )
+    COMMENTCOUNTER=$((COMMENTCOUNTER + 1))
+}
+
+diag () {
+    append_comment "${@}"
+}
+
+is () {
+    A="${1:-}"
+    B="${2:-}"
+    msg="${3:-unknown}"
+
+    if [ "x$A" != "x$B" ] ; then
+        append_tap "not ok - $msg"
+        append_comment "Failed test '$msg'"
+        append_comment "got: '$A'"
+        append_comment "expected: '$B'"
+    else
+        append_tap "ok - $msg"
+    fi
+}
+
+isnt () {
+    A="${1:-}"
+    B="${2:-}"
+    msg="${3:-unknown}"
+
+    if [ "x$A" = "x$B" ] ; then
+        append_tap "not ok - $msg"
+        append_comment "Failed test '$msg'"
+        append_comment "got: '$A'"
+        append_comment "expected: anything else"
+    else
+        append_tap "ok - $msg"
+    fi
+}
+
+require_ok () {
+    success="${1:-0}"
+    msg="${2:-unknown}"
+    if [ "$success" != "0" ] ; then
+        NOT="not "
+    else
+        NOT=""
+    fi
+    append_tap "${NOT}ok - $msg"
+
+    if [ "$success" = "0" ] ; then
+        return
+    fi
+
+    # similar to SKIPALL but report what we have so far
+    if [[ -n $EXIT_ON_SKIPALL ]]; then
+        exit 254
+    else
+        autoreport_start
+        exit 0
+    fi
+}
+
+ok () {
+    success="${1:-0}"
+    msg="${2:-unknown}"
+    if [ "$success" != "0" ] ; then
+        NOT="not "
+    else
+        NOT=""
+    fi
+    append_tap "${NOT}ok - $msg"
+    return $success
+}
+
+negate_ok () {
+    success="${1:-0}"
+    msg="${2:-unknown}"
+    if [ "$success" == "0" ] ; then
+        NOT="not "
+    else
+        NOT=""
+    fi
+    append_tap "${NOT}ok - $msg"
+    return $success
+}
+
+get_hex_from_int() { # returns lower case
+    printf "%x\n" "$1"
+}
+
+lower_case () {
+    string="${1:-}"
+    echo $(echo "$string" | tr '[A-Z]' '[a-z]')
+}
+
+get_random_number () {
+    range_max="${1:-32768}"
+    number=$RANDOM
+    let "number %= $range_max"
+    echo "$number"
+}
+
+get_kernel_release_1 () {
+    uname -r | cut -d. -f1
+}
+
+get_kernel_release_2 () {
+    uname -r | cut -d. -f2
+}
+
+get_kernel_release_3 () {
+    uname -r | cut -d. -f3 | sed -s 's/^\([0-9]*\).*$/\1/'
+}
+
+get_kernel_release () {
+    echo $(uname -r | cut -d. -f1-2).$(get_kernel_release_3)
+}
+
+normalize_version_number () {
+    A="${1:-0}"
+    # triplets x.y.z are converted to x + y/thousands + z/millions
+    # easier, but requires awk:
+    # awk -F. '{printf ("%d.%03d%03d\n",$1,$2,$3);}'
+    # we have to do a trick do avoid octal interpretation due to leading
+    # zeros, we use $((10#<number>)), which overrides with a base of 10
+    if echo $A | grep -q '\.' ; then
+        printf "%d.%03d%03d\n" $((10#$(echo "$A" | cut -d. -f1))) $((10#$(echo "$A" | cut -d. -f2))) $((10#$(echo "$A" | cut -d. -f3)))
+    else
+        echo "$A.000000"
+    fi
+}
+
+version_number_compare () {
+    A="${1:-0}"
+    COMPARATOR="${2:-'-eq'}"
+    B="${3:-0}"
+
+    An=$(normalize_version_number $A | tr -d .)
+    Bn=$(normalize_version_number $B | tr -d .)
+
+	test "$An" $COMPARATOR "$Bn"
+}
+
+version_number_gt () {
+    A="${1:-0}"
+    B="${2:-0}"
+    return $(version_number_compare "$A" -gt "$B")
+}
+
+version_number_ge () {
+    A="${1:-0}"
+    B="${2:-0}"
+    return $(version_number_compare "$A" -ge "$B")
+}
+
+version_number_lt () {
+    A="${1:-0}"
+    B="${2:-0}"
+    return $(version_number_compare "$A" -lt "$B")
+}
+
+version_number_le () {
+    A="${1:-0}"
+    B="${2:-0}"
+    return $(version_number_compare "$A" -le "$B")
+}
+
+has_kernel_release_min () {
+    _ta_autoreport_v="${1:-0}"
+    version_number_compare $(get_kernel_release) -gt $_ta_autoreport_v
+}
+
+require_kernel_release_min () {
+    release_req="${1:-}"
+    explanation="${2:-Linux Kernel must be newer than ${release_req}}"
+    if has_kernel_release_min "$release_req"; then
+        if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_kernel_release_min $release_req" ; fi
+        return $_SUCCESS
+    else
+        autoreport_skip_all "$explanation"
+    fi
+}
+
+prepare_information() {
+
+    # ===== control variables defaults ==================
+
+    # by default require_* functions generate TAP ok lines
+    REQUIRES_GENERATE_TAP=${REQUIRES_GENERATE_TAP:-1}
+
+    # ===== kernel details ==================
+
+    kernelrelease=$(uname -r)
+
+    # ===== suite name ==================
+
+    myname=$(echo $(basename -- $0 | sed -e 's/\.\w*$//i'))
+
+    SUITE=${myname:-bash-test-utils}
+    VERSION=1.000
+
+    # ===== other meta info ==================
+
+    suite_name=${SUITENAME:-$(echo $SUITE)}
+    suite_version=${SUITEVERSION:-$VERSION}
+    hostname=${HOSTNAME:-$(hostname)}
+    hostname=$(echo $hostname | cut -d. -f1)
+
+    if [ -e /etc/issue.net ]
+    then
+	osname=${OSNAME:-$(cat /etc/issue.net | head -1)}
+    else
+	osname=${OSNAME:-$(uname -o)}
+    fi
+
+    changeset=${CHANGESET:-$(cat /proc/version | head -1)}
+    kernelflags=$(cat /proc/cmdline)
+    uname=$(uname -a)
+    ram=$(free -m | grep -i mem: | awk '{print $2}'MB)
+    starttime_test_program=${starttime_test_program:-$(date --rfc-2822)} # first occurrence
+    starttime_test_program_epoch=${starttime_test_program_epoch:-$(date +"%s")}
+    endtime_test_program=$(date --rfc-2822) # last occurrence
+    endtime_test_program_epoch=$(date +"%s")
+    bogomips=$(echo $(cat /proc/cpuinfo | grep -i bogomips | head -1 | cut -d: -f2))
+    cpuinfo=$(
+        if arm_cpu
+        then
+            cpu=$(grep 'Processor' < /proc/cpuinfo | cut -d: -f2- |head -1 | cut -d" " -f2);
+        else
+            cpu=$(grep 'model name' < /proc/cpuinfo | cut -d: -f2- | head -1 | sed -e "s/^ *//");
+        fi
+        echo "$(get_number_cpus) cores [$cpu]";
+    )
+    # TODO: bogomips from /proc/cpuinfo
+
+    if [ -e "/boot/config-$kernelrelease" ]
+    then
+	BOOTCONFIG="/boot/config-$kernelrelease"
+    else
+	BOOTCONFIG=
+    fi
+    PROCCONFIG="/proc/config.gz"
+
+} # prepare_information()
+
+ltu_suite_meta() {
+    if [[ -n $VERBOSE ]]; then
+        echo "# Test-section: $suite_name";
+        echo "# Test-suite-version: $suite_version";
+    fi
+    echo "# Test-suite-name: $suite_name";
+    echo "# Test-machine-name: $hostname";
+}
+
+ltu_base_os_description () {
+    if [ -r /etc/lsb-release ] ; then
+        . /etc/lsb-release
+        BASE_OS_DESCRIPTION="$DISTRIB_DESCRIPTION"
+    else
+        RELEASE_FILES="/etc/slackware-version /etc/gentoo-release /etc/SuSE-release /etc/issue /etc/issue.net /etc/motd"
+        for i in $RELEASE_FILES ; do if [ -r $i ] ; then RELEASE_FILE=$i ; break ; fi; done
+        BASE_OS_DESCRIPTION=$(cat $RELEASE_FILE | perl -ne 'print if /\w/' | head -1)
+    fi
+    echo $BASE_OS_DESCRIPTION
+}
+
+# we could as well use uname -r here, but lets explicitly ask Xen
+# first what it thinks the Dom0 kernel version is
+ltu_xen_dom0_kernel () {
+    XL=$(get_xen_tool)
+    if [ "$?" -eq 0 ] ; then
+        $XL info 2> /dev/null | grep '^release.*:' | cut -d: -f2 || uname -r
+    else
+        uname -r
+    fi
+}
+
+ltu_xen_changeset () {
+    if [ -r /sys/hypervisor/properties/changeset ] ; then
+        cat /sys/hypervisor/properties/changeset | sed -e 's/^.* \([^ ]*\)/\1/'
+    else
+        XL=$(get_xen_tool) || return $_FAILURE
+        echo $($XL info|grep '^xen_changeset.*:'|sed -e 's/^.* \([^ ]*\)/\1/')
+    fi
+}
+
+ltu_xen_version () {
+    if [ -r /sys/hypervisor/version/major ] ; then
+        _VPATH="/sys/hypervisor/version"
+        echo "$(cat $_VPATH/major).$(cat $_VPATH/minor)$(cat $_VPATH/extra)"
+    else
+        XL=$(get_xen_tool) || return $_FAILURE
+        XEN_VERSION_MAJOR=$(echo $($XL info|grep '^xen_major.*:'|cut -d: -f2))
+        XEN_VERSION_MINOR=$(echo $($XL info|grep '^xen_minor.*:'|cut -d: -f2))
+        XEN_VERSION_EXTRA=$(echo $($XL info|grep '^xen_extra.*:'|cut -d: -f2))
+        XEN_VERSION=""
+        if [ -n "$XEN_VERSION_MAJOR" ] ; then
+            XEN_VERSION="$XEN_VERSION_MAJOR.$XEN_VERSION_MINOR$XEN_VERSION_EXTRA"
+        fi
+        echo $XEN_VERSION
+    fi
+}
+
+ltu_xen_meta () {
+    echo "# Test-xen-dom0-kernel: $(ltu_xen_dom0_kernel)"
+    echo "# Test-xen-version: $(ltu_xen_version)"
+    echo "# Test-xen-changeset: $(ltu_xen_changeset)"
+    echo "# Test-xen-base-os-description: $(ltu_base_os_description)"
+}
+
+ltu_kvm_meta () {
+    echo "# Test-kvm-version: $(uname -r)"
+    echo "# Test-kvm-base-os-description: $(ltu_base_os_description)"
+}
+
+ltu_section_meta() {
+    if [ ! "x1" = "x$DONTREPEATMETA" ] ; then
+        echo "# Test-uname: $uname"
+        echo "# Test-osname: $osname"
+        echo "# Test-kernel: $kernelrelease"
+        echo "# Test-changeset: $changeset"
+        echo "# Test-flags: $kernelflags"
+        echo "# Test-cpuinfo: $cpuinfo"
+        echo "# Test-ram: $ram"
+        echo "# Test-starttime-test-program: $starttime_test_program"
+        echo "# Test-endtime-test-program: $endtime_test_program"
+        if is_running_in_xen_dom0 ; then
+            ltu_xen_meta
+        fi
+        if is_running_in_kvm_host ; then
+            ltu_kvm_meta
+        fi
+    fi
+
+    if [ -n "$SECTION" ] ; then
+        echo "# Test-section:              $SECTION"
+    fi
+}
+
+ltu_help () {
+    echo "bash-test-utils"
+    echo ""
+    echo "This is the 'bash-test-utils' bash utility -- a bash include file"
+    echo "to turn your bash script into a test suite that can optionally be"
+    echo "used with the 'prove' command, a standard tool to run test scripts."
+    echo ""
+    echo "Use in your script:"
+    echo "  . ./bash-test-utils"
+    echo "  # ... your testing here, eg.:"
+    echo "  grep -q foobar /proc/cpuinfo"
+    echo '  ok $? "found foobar in cpuinfo"'
+    echo "  done_testing"
+    echo ""
+    echo "Run:"
+    echo "  prove    ./examples/utils-example-01.t"
+    echo "  prove -v ./examples/utils-example-01.t  # verbose"
+    echo "  prove    ./examples/                    # whole subdir"
+    echo ""
+}
+
+ltu_version () {
+	echo "$VERSION"
+}
+
+# ===== param evaluation ==============================
+
+prepare_start () {
+    prepare_information
+    # other context sensitive initialization (eg. default, destructive, ...)
+}
+
+prepare_plan() {
+    # count of our own tests
+    COUNT=${#TAP[@]}
+    PLAN=$(($MYPLAN + $COUNT - $COMMENTCOUNTER))
+}
+
+# ===== main =========================================
+
+autoreport_main() {
+
+    COMMENTCOUNTER=${COMMENTCOUNTER:-0}
+
+    if [ -n "$SKIPALL" ] ; then
+        echo "$SKIPALL"
+        ltu_suite_meta
+        if [[ -n $VERBOSE ]]; then
+            ltu_section_meta
+        fi
+        return
+    fi
+
+    # ==================== prepare plan
+
+    # count of tests until "END of own tests"
+    MYPLAN=2
+    prepare_plan
+    echo "TAP Version 13"
+    echo "1..$PLAN"
+
+    # ==================== meta info ====================
+    ltu_suite_meta
+    if [[ -n $VERBOSE ]]; then
+        ltu_section_meta
+    fi
+
+    # =============== own headers (later entries win) ===============
+    HEADERSCOUNT=${#HEADERS[@]}
+    for l in $(seq 0 $(($HEADERSCOUNT - 1))) ; do
+        echo ${HEADERS[l]}
+    done
+
+    # ,==================== BEGIN of own tests ====================
+    # |
+    #
+    echo "ok - autoreport"
+    #
+    # |
+    # `==================== END of own tests ====================
+
+    # ==================== remaining TAP ====================
+    for l in $(seq 0 $(($COUNT - 1))) ; do
+        echo ${TAP[l]}
+    done
+
+    # ==================== additional TAP/YAML data ====================
+    echo "ok - tapdata"
+    echo "  ---"
+    echo "  tapdata: 1"
+    if [ -n "$starttime_test_program_epoch" ] && [ -n "$endtime_test_program_epoch" ] ; then
+        echo "  starttime: $starttime_test_program_epoch"
+        echo "  endtime: $endtime_test_program_epoch"
+        echo "  runtime: $((endtime_test_program_epoch-starttime_test_program_epoch))"
+    fi
+    TAPDATACOUNT=${#TAPDATA[@]}
+    if [ "$TAPDATACOUNT" -gt 0 ] ; then
+        for l in $(seq 0 $(($TAPDATACOUNT - 1))) ; do
+            echo "  ${TAPDATA[l]}"
+        done
+    fi
+    echo "  ..."
+
+    # ==================== remaining output ====================
+    OUTPUTCOUNT=${#OUTPUT[@]}
+    for l in $(seq 0 $(($OUTPUTCOUNT - 1))) ; do
+        echo ${OUTPUT[l]}
+    done
+
+    # ==================== files ====================
+    for f in $(seq 0 $(($FILECOUNT - 1))) ; do
+        echo "# File upload: '${FILES[f]}'"
+    done
+
+    if set | grep -q '^main_after_hook \(\)' ; then
+        main_after_hook
+    fi
+}
+
+# ===== main =========================================
+
+autoreport_start () {
+
+    prepare_start "${@}"
+    autoreport_main
+}
+
+done_testing () {
+    autoreport_start "${@}"
+}
+
+# =====================================================
+
+function recover_kill {
+    ok 1 'GOT KILLED EXTERNALLY'
+    done_testing
+    exit
+}
+
+trap "recover_kill" SIGTERM SIGHUP SIGINT SIGKILL
+
+# =====================================================
+
+[ "$1" == "--help" ]         && ltu_help    && exit $_SUCCESS
+[ "$1" == "--version" ]      && ltu_version && exit $_SUCCESS
+
+# =====================================================
+
+prepare_information
diff --git a/tools/testing/tap/bash-test-utils.txt b/tools/testing/tap/bash-test-utils.txt
new file mode 100644
index 0000000..b0596db
--- /dev/null
+++ b/tools/testing/tap/bash-test-utils.txt
@@ -0,0 +1,320 @@
+bash-test-utils -- support writing functional tests
+
+ABOUT
+=====
+
+It provides utility functions and facilities to write tests in
+baremetal and Xen/KVM contexts (host and guest support) and was
+polished to work with i686, x86_64, and ARM under lots of major Linux
+distributions (Debian, Ubuntu, RHEL, SLES, Slackware, Fedora,
+openSUSE).
+
+It can be run as normal bash script or indirectly via the "prove"
+command, a standard Linux tool to run test scripts.
+
+
+SYNOPSIS
+========
+
+A test script
+-------------
+
+  #! /bin/bash
+  . ./bash-test-utils
+  # your_feature_test here
+  done_testing
+
+This imports utility functions to be used by your script, then you
+write your tests, and at the end it calls the actual printing of test
+results.
+
+
+Run it via 'prove' (a standard test utility)
+--------------------------------------------
+
+  $ prove ./trivial-example-1.sh
+  ./trivial-example-1.sh .. ok
+  All tests successful.
+  Files=1, Tests=5, 20 wallclock secs
+  Result: PASS
+
+The tool "prove" is a standard tool available in every Linux
+distribution. It runs the script and prints success statistics. See
+"man prove" for more options.
+
+
+UTILITY FUNCTIONS
+=================
+
+Import utility functions at the beginning of the script via
+
+  . tools/testing/tap/bash-test-utils
+
+Then you have several functions available.
+
+Expressing test results
+-----------------------
+
+* ok ARG1 "some description"
+
+  Evaluates the first argument with Shell boolean semantics (0 is
+  true) and appends a corresponding TAP line. See also "require_ok"
+  below.
+
+* negate_ok ARG1 "some description"
+
+  Evaluates the first argument with Shell inverse boolean semantics (0
+  is false) and appends a corresponding TAP line.
+
+* append_tap "ok - some description"
+
+  Appends a complete TAP line where you have taken care for the
+  "ok"/"not ok" at the beginning.
+
+* append_comment "foo bar baz"
+
+  Appends a complete comment line starting with "#". It appears
+  directly after the last added TAP line so it can be used for
+  diagnostics.
+
+* append_tapdata "key: value"
+
+  Appends a key:value line at the final tapdata YAML block. The key
+  must start with letter and consist of only alphanum an underscore.
+
+
+require_* functions
+-------------------
+
+  All require_* functions check for something and gracefully exit the
+  script if the requirement is not fulfilled. Use this to allow the
+  script to run everywhere without polluting results with false
+  negatives.
+
+* require_ok ARG1 "some description"
+
+  Evaluates the first argument with Shell boolean semantics (0 is
+  true) and appends a corresponding TAP line. If it reports "not ok"
+  the script gracefully exits.
+
+* require_amd_family_range [ MIN [ MAX ] ]
+
+  Ensures vendor is AMD and cpu family from /proc/cpuinfo is in a
+  minimum/maximum range. If you don't specify MIN it defaults to 0. If
+  you don't specify MAX it defaults to MIN.
+
+* require_cpufeature "foo"
+
+  Verifies that the string "foo" occurs in /proc/cpuinfo flags section.
+
+* require_kernel_config "CONFIG_FOO"
+
+  Verify that regex "^CONFIG_FOO=." occurs in /proc/config.gz or
+  /boot/config/$ (uname -r).
+
+* require_program "foo"
+
+  Verify that the program "foo" is available. Use it to declare
+  external programs you call, like "awk", "bc", "perl", etc.
+
+* require_l3cache
+
+  Verify that L3 cache is available (checked in
+  /sys/devices/system/cpu/cpu0/ cache/index3).
+
+* require_root
+
+  Verify that the user executing the script is root (UID 0).
+
+* require_crit_level N
+
+  Verify that the criticality level N of the script is allowed to be
+  run, which is controlled by environment variable CRITICALITY. See
+  "has_crit_level" for meaning of criticality levels.
+
+* require_cpb_disabled
+
+  Enables cpufreq and disables boosting. In case of errors the calling
+  test is skipped.
+
+* require_cpufreq_enabled
+
+  Enables cpufreq and also core boosting. In case of errors the
+  calling test is skipped.
+
+* require_kernel_release_min
+
+  Verify that the current LK release is at least the required version
+  number.
+
+* require_running_in_xen_guest
+
+  Verify if we are in a Xen guest.
+
+* require_running_in_kvm_guest
+
+  Verify if we are in a KVM guest.
+
+* require_running_in_virtualized_guest
+
+  Verify if we are in a virtualized guest (Xen or KVM).
+
+
+request_* functions
+-------------------
+
+All request_* functions try to enable something and if that fails mark it as
+#TODO but continue the test. It's kind of an "uncritical require_*".
+
+* request_cpb_disabled
+
+  Enables cpufreq and disables boosting. The result will be reported
+  and returned. Errors are marked as TODO.
+
+* request_cpufreq_enabled
+
+  Enables cpufreq and also core boosting. The result will be reported
+  and returned. Errors are marked as TODO.
+
+
+Misc auxiliary functions
+------------------------
+
+These are really just utilities to help you but they don't influence the
+behaviour like the require_* functions do.
+
+* has_l3cache
+
+  Returns 0 (shell TRUE) if L3 cache is available (checked in
+  /sys/devices/ system/cpu/cpu0/cache/index3).
+
+* has_cpufeature "foo"
+
+  Returns 0 (shell TRUE) if string "foo" occurs in /proc/cpuinfo flags
+  section.
+
+* has_kernel_release_min
+
+  Returns 0 (shell TRUE) if the current LK release is at least the
+  required version number.
+
+* has_kernel_config "CONFIG_FOO"
+
+  Returns 0 (shell TRUE) if regex "^CONFIG_FOO=." occurs in
+  /proc/config.gz or / boot/config/$(uname -r).
+
+* has_program "foo"
+
+  Return 0 (shell TRUE) if the program "foo" is available.
+
+* has_crit_level N
+
+  Checks whether the criticality level N of the script is allowed to
+  be run, which is controlled by environment variable CRITICALITY. The
+  criticality levels are defined as this:
+
+   * 0: not critical
+   * 1: read sysfs/debugfs/proc files
+   * 2: read HW (MSRs/Northbridge)
+   * 3: write sysfs/debugfs/proc files
+   * 4: write HW (MSRs/Northbridge) or potentially crash the machine
+
+* get_vendor
+
+  Prints vendor "AMD" or "Intel" from /proc/cpuinfo.
+
+* vendor_intel
+
+  Returns 0 (shell TRUE) if vendor is Intel.
+
+* vendor_amd
+
+  Returns 0 (shell TRUE) if vendor is AMD.
+
+* get_random_number [ MAX ]
+
+  Prints a random integer between 0 and MAX (default 32768).
+
+* get_cpu_family
+
+  Print cpu family from /proc/cpuinfo.
+
+* get_cpu_family_hex
+
+  Print cpu family from /proc/cpuinfo in hex syntax (0x...).
+
+* cpu_family_min [ MINFAMILY ]
+
+  Returns 0 (shell TRUE) if cpu family from /proc/cpuinfo is greater
+  or equal to MINFAMILY. Defaults to 0.
+
+* cpu_family_max [ MAXFAMILY ]
+
+  Returns 0 (shell TRUE) if cpu family from /proc/cpuinfo is less or
+  equal to MAXFAMILY. Defaults to 999.
+
+* get_first_file [ LIST OF FILENAMES ]
+
+  Goes through all specified filenames and prints the first one that
+  exists and is readable.
+
+* is_element_in_list WORD "SPACE SEPARATED LIST OF WORDS"
+
+  Returns 0 (shell TRUE) if WORD appears in "SPACE SEPARATED LIST OF
+  WORDS". Remember the usual shell quoting rules.
+
+* get_kernel_release
+
+  Prints the kernel version number from uname -r.
+
+* is_running_in_xen_guest
+
+  Check if we are in a Xen guest.
+
+* is_running_in_kvm_guest
+
+  Check if we are in a KVM guest.
+
+* is_running_in_virtualized_guest
+
+  Check if we are in a virtualized guest (Xen or KVM).
+
+
+INFLUENCING BEHAVIOUR
+=====================
+
+Environment Variables
+---------------------
+
+These variables are expected to be set inside the script to declare
+meta information or influence behaviour:
+
+* TAP[*]                - Array of TAP lines
+* TAPDATA[*]            - Array of YAML lines that contain data in TAP
+* OUTPUT[*]             - Array of additional output lines
+* SUITENAME             - alternative suite name instead of $0
+* SUITEVERSION          - alternative suite version
+* KEYWORDS              - space separated keywords to influence suite
+                          name
+* OSNAME                - alternative OS description
+* CHANGESET             - alternative changeset
+* HOSTNAME              - alternative hostname
+* TICKETURL             - relevant URL in used ticket system
+                          (Bugzilla)
+* WIKIURL               - relevant URL in used wiki
+* PLANNINGID            - relevant task planning id
+                          (MS Project, TaskJuggler, etc.)
+* REQUIRES_GENERATE_TAP - if "1" then require_* functions generate
+                          additional "ok" line on success
+
+
+External environment variables
+------------------------------
+
+These variables are expected to be set from outside of the script to
+influence behaviour:
+
+* EXIT_ON_SKIPALL - if "1" then on skip_all we immediately exit
+                    with exitcode 254.
+* CRITICALITY     - Sets the allowed maximal criticality level.
+                    Scripts with higher level call skip_all().
-- 
1.7.10.4


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ