diff options
Diffstat (limited to 'fuse/test-fuse.sh')
-rwxr-xr-x | fuse/test-fuse.sh | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/fuse/test-fuse.sh b/fuse/test-fuse.sh new file mode 100755 index 00000000..fffd851f --- /dev/null +++ b/fuse/test-fuse.sh @@ -0,0 +1,218 @@ +#!/bin/bash - +# libguestfs +# Copyright (C) 2009 Red Hat Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# 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. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +unset CDPATH +set -e +#set -v + +if [ -z "$top_builddir" ]; then + echo "$0: error: environment variable \$top_builddir must be set" + exit 1 +fi + +nr_stages=$(grep "^stage " $0 | wc -l) + +# Allow top_builddir to be a relative path, but also make it absolute, +# and move to that directory for the initial phase of the script. +top_builddir=$(cd "$top_builddir" > /dev/null; pwd) + +# Set libguestfs up for running locally. +export LIBGUESTFS_PATH="$top_builddir/appliance" + +# Paths to the other programs and files. NB: Must be absolute paths. +guestfish="$top_builddir/fish/guestfish" +guestmount="$top_builddir/fuse/guestmount" +image="$top_builddir/fuse/test.img" +mp="$top_builddir/fuse/test-mp" + +if [ ! -x "$guestfish" -o ! -x "$guestmount" ]; then + echo "$0: error: guestfish or guestmount are not available" + exit 1 +fi + +# Ensure everything is cleaned up on exit. +rm -f "$image" +mkdir -p "$mp" +fusermount -u "$mp" >/dev/null 2>&1 ||: +function cleanup () +{ + status=$? + set +e + [ $status = 0 ] || echo "*** FAILED ***" + echo "Unmounting filesystem and cleaning up." + + # Move out of the mountpoint (otherwise our cwd will prevent the + # mountpoint from being unmounted). + cd "$top_builddir" + + # Who's using this? Should be no one, but see below. + if [ -x /sbin/fuser ]; then /sbin/fuser "$mp"; fi + + # If you run this and you have GNOME running at the same time, + # then randomly /usr/libexec/gvfs-gdu-volume-monitor will decide + # to do whatever it does in the mountpoint directory, preventing + # you from unmounting it! Hence the need for this loop. + count=10 + while ! fusermount -u "$mp" && [ $count -gt 0 ]; do + sleep 1 + ((count--)) + done + + rm -f "$image" + rm -rf "$mp" + exit $status +} +trap cleanup INT TERM QUIT EXIT + +s=1 +function stage () +{ + echo "test-fuse: $s/$nr_stages:" "$@" "..." + ((s++)) +} + +stage Create filesystem with some inital content +$guestfish <<EOF + sparse "$image" 10M + run + part-disk /dev/sda mbr + mkfs ext2 /dev/sda1 + mount /dev/sda1 / + write-file /hello.txt hello 0 + write-file /world.txt "hello world" 0 + touch /empty +EOF + +stage Mounting the filesystem +$guestmount -a "$image" -m /dev/sda1 "$mp" + +stage Changing into mounted directory +cd "$mp" + +stage Checking initial files exist +[ -n "$(echo *)" ] +[ "$(ls empty hello.txt world.txt)" = "empty +hello.txt +world.txt" ] + +stage Checking initial files contain expected content +[ "$(cat hello.txt)" = "hello" ] +[ "$(cat world.txt)" = "hello world" ] +cat empty ;# should print nothing +[ -z "$(cat empty)" ] + +stage Checking file modes of initial content +[ "$(stat -c %a empty)" = "644" ] +[ "$(stat -c %a hello.txt)" = "644" ] +[ "$(stat -c %a world.txt)" = "644" ] + +stage Checking sizes of initial content +[ "$(stat -c %s empty)" -eq 0 ] +[ "$(stat -c %s hello.txt)" -eq 5 ] +[ "$(stat -c %s world.txt)" -eq 11 ] + +stage Checking unlink +touch new +rm -f new ;# force because file is "owned" by root + +stage Checking symbolic link +ln -s hello.txt symlink +[ -L symlink ] + +stage Checking readlink +[ "$(readlink symlink)" = "hello.txt" ] + +stage Checking hard link +[ "$(stat -c %h hello.txt)" -eq 1 ] +ln hello.txt link +[ "$(stat -c %h link)" -eq 2 ] +[ "$(stat -c %h hello.txt)" -eq 2 ] +rm -f link +[ ! -e link ] + +# This fails because of caching. The problem is that the linked file +# ("hello.txt") is cached with a link count of 2. unlink("link") +# invalidates the cache for "link", but _not_ for "hello.txt" which +# still has the now-incorrect cached value. However there's not much +# we can do about this since searching for all linked inodes of a file +# is an O(n) operation. +#[ "$(stat -c %h hello.txt)" -eq 1 ] + +stage Checking mkdir +mkdir newdir +[ -d newdir ] + +stage Checking rmdir +rmdir newdir +[ ! -e newdir ] + +stage Checking rename +touch old +mv old new +[ -f new ] +[ ! -e old ] +rm -f new + +stage Checking chmod +touch new +chmod a+x new +[ -x new ] +chmod a-x new +[ ! -x new ] +chmod a-w new +[ ! -w new ] +chmod a+w new +[ -w new ] +chmod a-r new +[ ! -r new ] +chmod a+r new +[ -r new ] +rm -f new + +stage Checking truncate +truncate -s 10000 truncated +[ "$(stat -c %s truncated)" -eq 10000 ] +truncate -c -s 1000 truncated +[ "$(stat -c %s truncated)" -eq 1000 ] +truncate -c -s 10 truncated +[ "$(stat -c %s truncated)" -eq 10 ] +truncate -c -s 0 truncated +[ "$(stat -c %s truncated)" -eq 0 ] +rm -f truncated + +stage Checking utimens and timestamps +for ts in 12345 1234567 987654321; do + # NB: It's not possible to set the ctime with touch. + touch -a -d @$ts timestamp + [ "$(stat -c %X timestamp)" -eq $ts ] + touch -m -d @$ts timestamp + [ "$(stat -c %Y timestamp)" -eq $ts ] + touch -d @$ts timestamp + [ "$(stat -c %X timestamp)" -eq $ts ] + [ "$(stat -c %Y timestamp)" -eq $ts ] +done + +# These ones are not yet tested by the current script: +#stage XXX statfs/statvfs +#stage XXX xattr operations + +# These ones cannot easily be tested by the current script, eg because +# this script doesn't run as root: +#stage XXX fsync +#stage XXX chown +#stage XXX mknod |