333 lines
12 KiB
Bash
Executable File
333 lines
12 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
STORAGE_BINARY=${STORAGE_BINARY:-$(dirname ${BASH_SOURCE})/../containers-storage}
|
|
TESTSDIR=${TESTSDIR:-$(dirname ${BASH_SOURCE})}
|
|
STORAGE_DRIVER=${STORAGE_DRIVER:-vfs}
|
|
STORAGE_TRANSIENT=${STORAGE_TRANSIENT:-0}
|
|
STORAGE_OPTION=${STORAGE_OPTION:-}
|
|
PATH=$(dirname ${BASH_SOURCE})/..:${PATH}
|
|
OS=$(uname -s)
|
|
if [ "$STORAGE_TRANSIENT" -eq 1 ]; then
|
|
CONTAINERS_LOCK_ROOT=runroot
|
|
STORAGE_TRANSIENT_OPT=--transient-store
|
|
else
|
|
CONTAINERS_LOCK_ROOT=root
|
|
STORAGE_TRANSIENT_OPT=""
|
|
fi
|
|
|
|
# Create a unique root directory and a runroot directory.
|
|
function setup() {
|
|
suffix=$(dd if=/dev/urandom bs=12 count=1 status=none | base64 | tr +/ABCDEFGHIJKLMNOPQRSTUVWXYZ _.abcdefghijklmnopqrstuvwxyz)
|
|
TESTDIR=${BATS_TMPDIR}/tmp.${suffix}
|
|
rm -fr ${TESTDIR}
|
|
mkdir -p ${TESTDIR}/{root,runroot}
|
|
# disable idmapped mounts in the overlay driver, since that
|
|
# is the expectation in the idmaps.bats tests.
|
|
export _CONTAINERS_OVERLAY_DISABLE_IDMAP=yes
|
|
}
|
|
|
|
# Delete the unique root directory and a runroot directory.
|
|
function teardown() {
|
|
run storage wipe
|
|
if [[ $status -ne 0 ]] ; then
|
|
echo "$output"
|
|
fi
|
|
run storage shutdown
|
|
if [[ $status -ne 0 ]] ; then
|
|
echo "$output"
|
|
fi
|
|
rm -fr ${TESTDIR}
|
|
}
|
|
|
|
# Create a file "$1" with random contents of length $2, or 256.
|
|
function createrandom() {
|
|
output=${1:-${BATS_TMPDIR}/randomfile}
|
|
dd if=/dev/urandom bs=1 count=${2:-256} of=${output} status=none
|
|
# Set the mtime to the epoch so it won't be different once it
|
|
# is deduplicated with OSTree
|
|
#
|
|
# Note: The Linux touch utility can express time as an
|
|
# explicit offset, allowing '@0' as a clear way of expressing
|
|
# epoch. Unfortunately, the touch utility from BSD derived
|
|
# platforms including FreeBSD and darwin is more restrictive
|
|
# so we use ISO 8601 format as lowest common denominator.
|
|
touch -d 1970-01-01T00:00:00Z ${output}
|
|
}
|
|
|
|
# Run the CLI with the specified options.
|
|
function storage() {
|
|
${STORAGE_BINARY} --debug --graph ${TESTDIR}/root --run ${TESTDIR}/runroot ${STORAGE_TRANSIENT_OPT} --storage-driver ${STORAGE_DRIVER} ${STORAGE_OPTION:+--storage-opt=${STORAGE_OPTION}} "$@"
|
|
}
|
|
|
|
# Run the CLI with the specified options, and sort its output lines.
|
|
function storagewithsorting() {
|
|
storage "$@" | LC_ALL=C sort
|
|
}
|
|
|
|
# Run the CLI with the specified options, and sort its output lines using the second field.
|
|
function storagewithsorting2() {
|
|
storage "$@" | LC_ALL=C sort -k2
|
|
}
|
|
|
|
# Create a few layers with files and directories added and removed at each
|
|
# layer. Their IDs are set to $lowerlayer, $midlayer, and $upperlayer.
|
|
populate() {
|
|
# Create a base layer.
|
|
run storage --debug=false create-layer
|
|
echo $output
|
|
[ "$status" -eq 0 ]
|
|
[ "$output" != "" ]
|
|
lowerlayer="$output"
|
|
# Mount the layer.
|
|
run storage --debug=false mount $lowerlayer
|
|
[ "$status" -eq 0 ]
|
|
[ "$output" != "" ]
|
|
local lowermount="$output"
|
|
# Create three files, and nine directories: three empty, three with subdirectories, three with files.
|
|
createrandom "$lowermount"/layer1file1
|
|
createrandom "$lowermount"/layer1file2
|
|
createrandom "$lowermount"/layer1file3
|
|
mkdir "$lowermount"/layerdir1
|
|
mkdir "$lowermount"/layerdir2
|
|
mkdir "$lowermount"/layerdir3
|
|
mkdir "$lowermount"/layerdir4
|
|
mkdir "$lowermount"/layerdir4/layer1subdir
|
|
mkdir "$lowermount"/layerdir5
|
|
mkdir "$lowermount"/layerdir5/layer1subdir
|
|
mkdir "$lowermount"/layerdir6
|
|
mkdir "$lowermount"/layerdir6/layer1subdir
|
|
mkdir "$lowermount"/layerdir7
|
|
createrandom "$lowermount"/layerdir7/layer1file4
|
|
mkdir "$lowermount"/layerdir8
|
|
createrandom "$lowermount"/layerdir8/layer1file5
|
|
mkdir "$lowermount"/layerdir9
|
|
createrandom "$lowermount"/layerdir9/layer1file6
|
|
# Unmount the layer.
|
|
storage unmount $lowerlayer
|
|
|
|
# Create a second layer based on the first.
|
|
run storage --debug=false create-layer "$lowerlayer"
|
|
[ "$status" -eq 0 ]
|
|
[ "$output" != "" ]
|
|
midlayer="$output"
|
|
# Mount the second layer.
|
|
run storage --debug=false mount $midlayer
|
|
[ "$status" -eq 0 ]
|
|
[ "$output" != "" ]
|
|
local midmount="$output"
|
|
# Check that the files and directories from the first layer are present.
|
|
test -s "$midmount"/layer1file1
|
|
test -s "$midmount"/layer1file2
|
|
test -s "$midmount"/layer1file3
|
|
test -d "$midmount"/layerdir1
|
|
test -d "$midmount"/layerdir2
|
|
test -d "$midmount"/layerdir3
|
|
test -d "$midmount"/layerdir4
|
|
test -d "$midmount"/layerdir4/layer1subdir
|
|
test -d "$midmount"/layerdir5
|
|
test -d "$midmount"/layerdir5/layer1subdir
|
|
test -d "$midmount"/layerdir6
|
|
test -d "$midmount"/layerdir6/layer1subdir
|
|
test -d "$midmount"/layerdir7
|
|
test -s "$midmount"/layerdir7/layer1file4
|
|
test -d "$midmount"/layerdir8
|
|
test -s "$midmount"/layerdir8/layer1file5
|
|
test -d "$midmount"/layerdir9
|
|
test -s "$midmount"/layerdir9/layer1file6
|
|
# Now remove some of those files and directories.
|
|
rm "$midmount"/layer1file1
|
|
rm "$midmount"/layer1file2
|
|
rmdir "$midmount"/layerdir1
|
|
rmdir "$midmount"/layerdir2
|
|
rmdir "$midmount"/layerdir4/layer1subdir
|
|
rmdir "$midmount"/layerdir4
|
|
rmdir "$midmount"/layerdir5/layer1subdir
|
|
rmdir "$midmount"/layerdir5
|
|
rm "$midmount"/layerdir7/layer1file4
|
|
rmdir "$midmount"/layerdir7
|
|
rm "$midmount"/layerdir8/layer1file5
|
|
rmdir "$midmount"/layerdir8
|
|
# Add a couple of new files and directories.
|
|
createrandom "$midmount"/layer2file1
|
|
mkdir "$midmount"/layerdir10
|
|
mkdir "$midmount"/layerdir11
|
|
mkdir "$midmount"/layerdir11/layer2subdir
|
|
mkdir "$midmount"/layerdir12
|
|
createrandom "$midmount"/layerdir12/layer2file2
|
|
# Unmount the layer.
|
|
storage unmount $midlayer
|
|
|
|
# Create a third layer based on the second.
|
|
run storage --debug=false create-layer "$midlayer"
|
|
[ "$status" -eq 0 ]
|
|
[ "$output" != "" ]
|
|
upperlayer="$output"
|
|
# Mount the third layer.
|
|
run storage --debug=false mount $upperlayer
|
|
[ "$status" -eq 0 ]
|
|
[ "$output" != "" ]
|
|
local uppermount="$output"
|
|
# Check that contents of the second layer are present.
|
|
test -s "$uppermount"/layer1file3
|
|
test -d "$uppermount"/layerdir3
|
|
test -d "$uppermount"/layerdir6
|
|
test -d "$uppermount"/layerdir6/layer1subdir
|
|
test -d "$uppermount"/layerdir9
|
|
test -s "$uppermount"/layerdir9/layer1file6
|
|
test -s "$uppermount"/layer2file1
|
|
test -d "$uppermount"/layerdir10
|
|
test -d "$uppermount"/layerdir11
|
|
test -d "$uppermount"/layerdir11/layer2subdir
|
|
test -d "$uppermount"/layerdir12
|
|
test -s "$uppermount"/layerdir12/layer2file2
|
|
# Re-add some contents for this layer that were removed earlier.
|
|
createrandom "$uppermount"/layerfile1
|
|
mkdir "$uppermount"/layerdir1
|
|
mkdir "$uppermount"/layerdir4
|
|
mkdir "$uppermount"/layerdir4/layer1subdir
|
|
mkdir "$uppermount"/layerdir7
|
|
# Add some new contents, too.
|
|
mkdir "$uppermount"/layerdir3/layer3subdir
|
|
mkdir "$uppermount"/layerdir3/layer3subdir/layer3subsubdir
|
|
createrandom "$uppermount"/layerdir7/layer1file4
|
|
# Unmount the layer.
|
|
storage unmount $upperlayer
|
|
}
|
|
|
|
# Check that the changes list for layers created by populate() correspond to
|
|
# what naive diff methods would generate.
|
|
checkchanges() {
|
|
# The first layer should all be additions.
|
|
storage changes $lowerlayer
|
|
run storagewithsorting2 --debug=false changes $lowerlayer
|
|
[ "$status" -eq 0 ]
|
|
echo Changes for layer 1:
|
|
echo "$output"
|
|
[ "${#lines[*]}" -eq 18 ]
|
|
[ "${lines[0]}" = 'Add "/layer1file1"' ]
|
|
[ "${lines[1]}" = 'Add "/layer1file2"' ]
|
|
[ "${lines[2]}" = 'Add "/layer1file3"' ]
|
|
[ "${lines[3]}" = 'Add "/layerdir1"' ]
|
|
[ "${lines[4]}" = 'Add "/layerdir2"' ]
|
|
[ "${lines[5]}" = 'Add "/layerdir3"' ]
|
|
[ "${lines[6]}" = 'Add "/layerdir4"' ]
|
|
[ "${lines[7]}" = 'Add "/layerdir4/layer1subdir"' ]
|
|
[ "${lines[8]}" = 'Add "/layerdir5"' ]
|
|
[ "${lines[9]}" = 'Add "/layerdir5/layer1subdir"' ]
|
|
[ "${lines[10]}" = 'Add "/layerdir6"' ]
|
|
[ "${lines[11]}" = 'Add "/layerdir6/layer1subdir"' ]
|
|
[ "${lines[12]}" = 'Add "/layerdir7"' ]
|
|
[ "${lines[13]}" = 'Add "/layerdir7/layer1file4"' ]
|
|
[ "${lines[14]}" = 'Add "/layerdir8"' ]
|
|
[ "${lines[15]}" = 'Add "/layerdir8/layer1file5"' ]
|
|
[ "${lines[16]}" = 'Add "/layerdir9"' ]
|
|
[ "${lines[17]}" = 'Add "/layerdir9/layer1file6"' ]
|
|
# Check the second layer.
|
|
storage changes $midlayer
|
|
run storagewithsorting2 --debug=false changes $midlayer
|
|
[ "$status" -eq 0 ]
|
|
echo Changes for layer 2:
|
|
echo "$output"
|
|
[ "${#lines[*]}" -eq 14 ]
|
|
[ "${lines[0]}" = 'Delete "/layer1file1"' ]
|
|
[ "${lines[1]}" = 'Delete "/layer1file2"' ]
|
|
[ "${lines[2]}" = 'Add "/layer2file1"' ]
|
|
[ "${lines[3]}" = 'Delete "/layerdir1"' ]
|
|
[ "${lines[4]}" = 'Add "/layerdir10"' ]
|
|
[ "${lines[5]}" = 'Add "/layerdir11"' ]
|
|
[ "${lines[6]}" = 'Add "/layerdir11/layer2subdir"' ]
|
|
[ "${lines[7]}" = 'Add "/layerdir12"' ]
|
|
[ "${lines[8]}" = 'Add "/layerdir12/layer2file2"' ]
|
|
[ "${lines[9]}" = 'Delete "/layerdir2"' ]
|
|
[ "${lines[10]}" = 'Delete "/layerdir4"' ]
|
|
[ "${lines[11]}" = 'Delete "/layerdir5"' ]
|
|
[ "${lines[12]}" = 'Delete "/layerdir7"' ]
|
|
[ "${lines[13]}" = 'Delete "/layerdir8"' ]
|
|
# Check the third layer.
|
|
storage changes $upperlayer
|
|
run storagewithsorting2 --debug=false changes $upperlayer
|
|
[ "$status" -eq 0 ]
|
|
echo Changes for layer 3:
|
|
echo "$output"
|
|
[ "${#lines[*]}" -eq 9 ]
|
|
[ "${lines[0]}" = 'Add "/layerdir1"' ]
|
|
[ "${lines[1]}" = 'Modify "/layerdir3"' ]
|
|
[ "${lines[2]}" = 'Add "/layerdir3/layer3subdir"' ]
|
|
[ "${lines[3]}" = 'Add "/layerdir3/layer3subdir/layer3subsubdir"' ]
|
|
[ "${lines[4]}" = 'Add "/layerdir4"' ]
|
|
[ "${lines[5]}" = 'Add "/layerdir4/layer1subdir"' ]
|
|
[ "${lines[6]}" = 'Add "/layerdir7"' ]
|
|
[ "${lines[7]}" = 'Add "/layerdir7/layer1file4"' ]
|
|
[ "${lines[8]}" = 'Add "/layerfile1"' ]
|
|
}
|
|
|
|
# Check that the diff contents for layers created by populate() correspond to
|
|
# what naive diff methods would generate.
|
|
checkdiffs() {
|
|
# The first layer should all be additions.
|
|
storage diff -u -f $TESTDIR/lower.tar $lowerlayer
|
|
tar tf $TESTDIR/lower.tar > $TESTDIR/lower.txt
|
|
run env LC_ALL=C sort $TESTDIR/lower.txt
|
|
[ "$status" -eq 0 ]
|
|
echo Diff contents for layer 1:
|
|
echo "$output"
|
|
[ "${#lines[*]}" -eq 18 ]
|
|
[ "${lines[0]}" = 'layer1file1' ]
|
|
[ "${lines[1]}" = 'layer1file2' ]
|
|
[ "${lines[2]}" = 'layer1file3' ]
|
|
[ "${lines[3]}" = 'layerdir1/' ]
|
|
[ "${lines[4]}" = 'layerdir2/' ]
|
|
[ "${lines[5]}" = 'layerdir3/' ]
|
|
[ "${lines[6]}" = 'layerdir4/' ]
|
|
[ "${lines[7]}" = 'layerdir4/layer1subdir/' ]
|
|
[ "${lines[8]}" = 'layerdir5/' ]
|
|
[ "${lines[9]}" = 'layerdir5/layer1subdir/' ]
|
|
[ "${lines[10]}" = 'layerdir6/' ]
|
|
[ "${lines[11]}" = 'layerdir6/layer1subdir/' ]
|
|
[ "${lines[12]}" = 'layerdir7/' ]
|
|
[ "${lines[13]}" = 'layerdir7/layer1file4' ]
|
|
[ "${lines[14]}" = 'layerdir8/' ]
|
|
[ "${lines[15]}" = 'layerdir8/layer1file5' ]
|
|
[ "${lines[16]}" = 'layerdir9/' ]
|
|
[ "${lines[17]}" = 'layerdir9/layer1file6' ]
|
|
# Check the second layer.
|
|
storage diff -c -f $TESTDIR/middle.tar $midlayer
|
|
tar tzf $TESTDIR/middle.tar > $TESTDIR/middle.txt
|
|
run env LC_ALL=C sort $TESTDIR/middle.txt
|
|
[ "$status" -eq 0 ]
|
|
echo Diff contents for layer 2:
|
|
echo "$output"
|
|
[ "${#lines[*]}" -eq 14 ]
|
|
[ "${lines[0]}" = '.wh.layer1file1' ]
|
|
[ "${lines[1]}" = '.wh.layer1file2' ]
|
|
[ "${lines[2]}" = '.wh.layerdir1' ]
|
|
[ "${lines[3]}" = '.wh.layerdir2' ]
|
|
[ "${lines[4]}" = '.wh.layerdir4' ]
|
|
[ "${lines[5]}" = '.wh.layerdir5' ]
|
|
[ "${lines[6]}" = '.wh.layerdir7' ]
|
|
[ "${lines[7]}" = '.wh.layerdir8' ]
|
|
[ "${lines[8]}" = 'layer2file1' ]
|
|
[ "${lines[9]}" = 'layerdir10/' ]
|
|
[ "${lines[10]}" = 'layerdir11/' ]
|
|
[ "${lines[11]}" = 'layerdir11/layer2subdir/' ]
|
|
[ "${lines[12]}" = 'layerdir12/' ]
|
|
[ "${lines[13]}" = 'layerdir12/layer2file2' ]
|
|
# Check the third layer.
|
|
storage diff -u -f $TESTDIR/upper.tar $upperlayer
|
|
tar tf $TESTDIR/upper.tar > $TESTDIR/upper.txt
|
|
run env LC_ALL=C sort $TESTDIR/upper.txt
|
|
[ "$status" -eq 0 ]
|
|
echo Diff contents for layer 3:
|
|
echo "$output"
|
|
[ "${#lines[*]}" -eq 9 ]
|
|
[ "${lines[0]}" = 'layerdir1/' ]
|
|
[ "${lines[1]}" = 'layerdir3/' ]
|
|
[ "${lines[2]}" = 'layerdir3/layer3subdir/' ]
|
|
[ "${lines[3]}" = 'layerdir3/layer3subdir/layer3subsubdir/' ]
|
|
[ "${lines[4]}" = 'layerdir4/' ]
|
|
[ "${lines[5]}" = 'layerdir4/layer1subdir/' ]
|
|
[ "${lines[6]}" = 'layerdir7/' ]
|
|
[ "${lines[7]}" = 'layerdir7/layer1file4' ]
|
|
[ "${lines[8]}" = 'layerfile1' ]
|
|
}
|