github.com/opensuse/umoci@v0.4.2/test/helpers.bash (about)

     1  #!/bin/bash
     2  # umoci: Umoci Modifies Open Containers' Images
     3  # Copyright (C) 2016, 2017, 2018 SUSE LLC.
     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  # Root directory of integration tests.
    18  INTEGRATION_ROOT=$(dirname "$(readlink -f "$BASH_SOURCE")")
    19  UMOCI="${UMOCI:-${INTEGRATION_ROOT}/../umoci}"
    20  GOMTREE="/usr/bin/gomtree" # For some reason $(whence ...) and $(where ...) are broken.
    21  
    22  # The source OCI image path, which we will make a copy of for each test.
    23  SOURCE_IMAGE="${SOURCE_IMAGE:-/image}"
    24  SOURCE_TAG="${SOURCE_TAG:-latest}"
    25  
    26  # Where we're going to copy the images and bundle to.
    27  IMAGE="${BATS_TMPDIR}/image"
    28  TAG="${SOURCE_TAG}"
    29  
    30  # We need to store the coverage outputs somewhere.
    31  COVERAGE_DIR="${COVERAGE_DIR:-}"
    32  
    33  # Are we rootless?
    34  ROOTLESS="$(id -u)"
    35  
    36  # Allows a test to specify what things it requires. If the environment can't
    37  # support it, the test is skipped with a message.
    38  function requires() {
    39  	for var in "$@"; do
    40  		case $var in
    41  			root)
    42  				if [ "$ROOTLESS" -ne 0 ]; then
    43  					skip "test requires ${var}"
    44  				fi
    45  				;;
    46  			*)
    47  				fail "BUG: Invalid requires ${var}."
    48  				;;
    49  		esac
    50  	done
    51  }
    52  
    53  function image-verify() {
    54  	oci-image-tool validate --type "imageLayout" "$@"
    55  	return $?
    56  }
    57  
    58  function bundle-verify() {
    59  	args=()
    60  
    61  	for arg in "$@"; do
    62  		args+=( --path="$arg" )
    63  	done
    64  
    65  	oci-runtime-tool validate "${args[@]}"
    66  	return $?
    67  }
    68  
    69  function umoci() {
    70  	local args=()
    71  	if [[ "$COVER" == 1 ]]; then
    72  		if [ "$COVERAGE_DIR" ]; then
    73  			args+=("-test.coverprofile=$(mktemp -p "$COVERAGE_DIR" umoci.cov.XXXXXX)")
    74  		fi
    75  		args+=("__DEVEL--i-heard-you-like-tests")
    76  	fi
    77  
    78  	if [[ "$1" == "raw" ]]; then
    79  		args+=("$1")
    80  		shift 1
    81  	fi
    82  
    83  	# Set the first argument (the subcommand).
    84  	args+=("$1")
    85  
    86  	# We're rootless if we're asked to unpack something.
    87  	if [[ "$ROOTLESS" != 0 && "$1" == "unpack" ]]; then
    88  		args+=("--rootless")
    89  	fi
    90  
    91  	shift
    92  	args+=("$@")
    93  	sane_run "$UMOCI" "${args[@]}"
    94  
    95  	if [[ "$COVER" == 1 ]]; then
    96  		# Because this is running as a -test.cover test, we need to remove the last
    97  		# two lines.
    98  		if [ "$status" -eq 0 ]; then
    99  			export output="$(echo "$output" | head -n-2)"
   100  			unset 'lines[${#lines[@]}-1]'
   101  			unset 'lines[${#lines[@]}-1]'
   102  		fi
   103  	fi
   104  }
   105  
   106  function gomtree() {
   107  	local args=("$@")
   108  
   109  	# We're rootless. Note that this is _not_ available in the upstream
   110  	# version of go-mtree and is unlikely to be accepted there (see
   111  	# https://github.com/vbatts/go-mtree/pull/96).
   112  	# It's maintained instead as an openSUSE extension:
   113  	# https://build.opensuse.org/package/view_file/Virtualization:containers/go-mtree/0001-gomtree-add-rootless-flag.patch?expand=1
   114  	if [[ "$ROOTLESS" != 0 ]]; then
   115  		args+=("-rootless")
   116  	fi
   117  
   118  	sane_run "$GOMTREE" -K sha256digest "${args[@]}"
   119  }
   120  
   121  function sane_run() {
   122  	local cmd="$1"
   123  	shift
   124  
   125  	run "$cmd" "$@"
   126  
   127  	# Some debug information to make life easier.
   128  	echo "$(basename "$cmd") $@ (status=$status)" >&2
   129  	echo "$output" >&2
   130  }
   131  
   132  function setup_image() {
   133  	cp -r "${SOURCE_IMAGE}" "${IMAGE}"
   134  	df >/dev/stderr
   135  	du -h -d 2 "$BATS_TMPDIR" >/dev/stderr
   136  	image-verify "${IMAGE}"
   137  }
   138  
   139  function teardown_image() {
   140  	rm -rf "${IMAGE}"
   141  }
   142  
   143  # Stores the set of tmpdirs that still have to be cleaned up. Calling
   144  # teardown_tmpdirs will set this to an empty array (and all the tmpdirs
   145  # contained within are removed).
   146  export TESTDIR_LIST="$(mktemp --tmpdir="$BATS_TMPDIR" umoci-integration-tmpdirs.XXXXXX)"
   147  
   148  # setup_tmpdir creates a new temporary directory and returns its name.  Note
   149  # that if "$ROOTLESS" is true, then removing this tmpdir might be harder than
   150  # expected -- so tests should not really attempt to clean up tmpdirs.
   151  function setup_tmpdir() {
   152  	mktemp -d --tmpdir="$BATS_TMPDIR" umoci-integration-tmpdir.XXXXXXXX | tee -a "$TESTDIR_LIST"
   153  }
   154  
   155  # teardown_tmpdirs removes all tmpdirs created with setup_tmpdir.
   156  function teardown_tmpdirs() {
   157  	# Do nothing if TESTDIR_LIST doesn't exist.
   158  	[ -e "$TESTDIR_LIST" ] || return
   159  
   160  	# Remove all of the tmpdirs.
   161  	while read tmpdir; do
   162  		[ -e "$tmpdir" ] || continue
   163  		chmod -R 0777 "$tmpdir"
   164  		rm -rf "$tmpdir"
   165  	done < "$TESTDIR_LIST"
   166  
   167  	# Clear tmpdir list.
   168  	rm -f "$TESTDIR_LIST"
   169  }
   170  
   171  # Generate a new $BUNDLE and $ROOTFS combination.
   172  function new_bundle_rootfs() {
   173  	declare -g BUNDLE="$(setup_tmpdir)"
   174  	declare -g ROOTFS="$BUNDLE/rootfs"
   175  }
   176  
   177  # _getfattr is a sane wrapper around getfattr(1) which only extracts the value
   178  # of the requested xattr (and removes any of the other crap that it spits out).
   179  # The usage is "sane_getfattr <xattr name> <path>" and outputs the hex
   180  # representation in a single line. Exit status is non-zero if the xattr isn't
   181  # set.
   182  function _getfattr() {
   183  	# We only support single-file inputs.
   184  	[ "$#" -eq 2 ] || return 1
   185  
   186  	local xattr="$1"
   187  	local path="$2"
   188  
   189  	# Run getfattr.
   190  	(
   191  		set -o pipefail
   192  		getfattr -e hex -n "$xattr" "$path" 2>/dev/null \
   193  			| grep "^$xattr=" | sed "s|^$xattr=||g"
   194  	)
   195  	return $?
   196  }