diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 16:11:47 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 16:11:47 +0000 |
commit | 758f820bcc0f68aeebac1717e537ca13a320b909 (patch) | |
tree | 48111ece75cf4f98316848b37a7e26356e00669e /tests/du | |
parent | Initial commit. (diff) | |
download | coreutils-758f820bcc0f68aeebac1717e537ca13a320b909.tar.xz coreutils-758f820bcc0f68aeebac1717e537ca13a320b909.zip |
Adding upstream version 9.1.upstream/9.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/du')
29 files changed, 1949 insertions, 0 deletions
diff --git a/tests/du/2g.sh b/tests/du/2g.sh new file mode 100755 index 0000000..adee756 --- /dev/null +++ b/tests/du/2g.sh @@ -0,0 +1,71 @@ +#!/bin/sh +# Ensure that du can handle a 2GB file (i.e., a file of size 2^31 bytes) +# Before coreutils-5.93, on systems with a signed, 32-bit stat.st_blocks +# one of du's computations would overflow. + +# Copyright (C) 2005-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du + +# Creating a 2GB file counts as 'very expensive'. +very_expensive_ + +# Get number of free kilobytes on current partition, so we can +# skip this test if there is insufficient free space. +free_kb=$(df -k --output=avail . | tail -n1) +case "$free_kb" in + [0-9]*) ;; + *) skip_ "invalid size from df: $free_kb";; +esac + +# Require about 3GB free. +min_kb=3000000 +test $min_kb -lt $free_kb || +{ + skip_ \ + "too little free space on current partition: $free_kb (need $min_kb KB)" +} + +big=big + +if ! fallocate -l2G $big; then + rm -f $big + { + is_local_dir_ . || skip_ 'Not writing 2GB data to remote' + for i in $(seq 100); do + # Note: 2147483648 == 2^31. Print floor(2^31/100) per iteration. + printf %21474836s x || fail=1 + done + # After the final iteration, append the remaining 48 bytes. + printf %48s x || fail=1 + } > $big || fail=1 +fi + +# The allocation may be done asynchronously (BTRFS for example) +sync $big || framework_failure_ + +du -k $big > out1 || fail=1 +rm -f $big +sed 's/^2[0-9][0-9][0-9][0-9][0-9][0-9] '$big'$/~2M/' out1 > out + +cat <<\EOF > exp || framework_failure_ +~2M +EOF + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/du/8gb.sh b/tests/du/8gb.sh new file mode 100755 index 0000000..7d067e5 --- /dev/null +++ b/tests/du/8gb.sh @@ -0,0 +1,54 @@ +#!/bin/sh +# Ensure that du does not rely on narrow types like size_t for +# file sizes or sums. + +# Copyright (C) 2003-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du +require_sparse_support_ + +# timeout to avoid hang on GNU/Hurd from 2019 +timeout 10 dd bs=1 seek=8G of=big < /dev/null 2> /dev/null +if test $? != 0; then + skip_ 'cannot create a file large enough for this test; possibly +because file offsets are only 32 bits on this file system' +fi + +# FIXME: this should be a test of dd. +# On some systems (at least linux-2.4.18 + NFS to Solaris system) +# the 'dd' command above mistakenly creates a file of length '0', yet +# doesn't fail. The root of that failure is that the ftruncate call +# returns zero but doesn't do its job. Detect this failure. +set x $(ls -gG big) +size=$4 +if test "$size" = 0; then + skip_ "cannot create a file large enough for this test +possibly because this system's NFS support is buggy +Consider rerunning this test on a different file system." +fi + + +# This would print '0 big' with coreutils-4.5.8. +du -ab big > out || fail=1 + +cat <<\EOF > exp +8589934592 big +EOF + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/du/basic.sh b/tests/du/basic.sh new file mode 100755 index 0000000..a81e895 --- /dev/null +++ b/tests/du/basic.sh @@ -0,0 +1,89 @@ +#!/bin/sh +# Compare actual numbers from du, assuming block size matches mine. + +# Copyright (C) 2003-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du + +mkdir -p a/b d d/sub || framework_failure_ + +# Ensure that these files contain more than 64 bytes, so that we don't +# immediately disqualify file systems (e.g., NetApp) on which smaller +# files take up zero file system blocks. +printf '%*s' 257 make-sure-the-file-is-non-empty > a/b/F || framework_failure_ +printf %4096s x > d/1 +cp d/1 d/sub/2 + + +B=$(stat --format=%B a/b/F) + +du --block-size=$B -a a > out || fail=1 +echo === >> out +du --block-size=$B -a -S a >> out || fail=1 +echo === >> out +du --block-size=$B -s a >> out || fail=1 + +f=$(stat --format=%b a/b/F) +b=$(stat --format=%b a/b) +a=$(stat --format=%b a) +bf=$(expr $b + $f) +tot=$(expr $bf + $a) + +cat <<EOF | sed 's/ *#.*//' > exp +$f a/b/F +$bf a/b +$tot a +=== +$f a/b/F # size of file, a/b/F +$bf a/b # size of dir entry, a/b, + size of file, a/b/F +$a a # size of dir entry, a +=== +$tot a +EOF + +compare exp out || fail=1 + +# Perform this test only if "." is on a local file system. +# Otherwise, it would fail e.g., on an NFS-mounted Solaris ZFS file system. +if is_local_dir_ .; then + rm -f out exp + du --block-size=$B -a d | sort -r -k2,2 > out || fail=1 + echo === >> out + du --block-size=$B -S d | sort -r -k2,2 >> out || fail=1 + + t2=$(stat --format=%b d/sub/2) + ts=$(stat --format=%b d/sub) + t1=$(stat --format=%b d/1) + td=$(stat --format=%b d) + tot=$(expr $t1 + $t2 + $ts + $td) + d1=$(expr $td + $t1) + s2=$(expr $ts + $t2) + + cat <<EOF | sed 's/ *#.*//' > exp +$t2 d/sub/2 +$s2 d/sub +$t1 d/1 +$tot d +=== +$s2 d/sub +$d1 d # d + d/1; don't count the dir. entry for d/sub +EOF + + compare exp out || fail=1 +fi + +Exit $fail diff --git a/tests/du/bigtime.sh b/tests/du/bigtime.sh new file mode 100755 index 0000000..4f8cfa2 --- /dev/null +++ b/tests/du/bigtime.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# Exercise du on a file with a big timestamp. + +# Copyright (C) 2010-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du + +export LC_ALL=C +export TZ=UTC0 + +# 2**63 - 1 +bignum=9223372036854775807 + +touch -d @$bignum future 2>/dev/null && +future_time=$(ls -l future) && +case "$future_time" in +*" $bignum "*) + : ;; +*' Dec 4 300627798676 '*) + skip_ "file system and localtime both handle big timestamps" ;; +*) + skip_ "file system or localtime mishandles big timestamps:" \ + "$future_time" ;; +esac || skip_ "file system cannot represent big timestamps" + +printf "0\t$bignum\tfuture\n" > exp || framework_failure_ +printf "du: time '$bignum' is out of range\n" > err_ok || framework_failure_ + +du --time future >out 2>err || fail=1 + +# On some systems an empty file occupies 4 blocks. +# Map the number of blocks to 0. +sed 's/^[0-9][0-9]*/0/' out > k && mv k out + +compare exp out || fail=1 +compare err err_ok || fail=1 + +Exit $fail diff --git a/tests/du/bind-mount-dir-cycle-v2.sh b/tests/du/bind-mount-dir-cycle-v2.sh new file mode 100755 index 0000000..60ae8b7 --- /dev/null +++ b/tests/du/bind-mount-dir-cycle-v2.sh @@ -0,0 +1,38 @@ +#!/bin/sh +# Check that du can handle sub-bind-mounts cycles as well. + +# Copyright (C) 2014-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du +require_root_ + +cleanup_() { umount a/b/c; } + +mkdir -p a/b/c || framework_failure_ +mount --bind a a/b/c \ + || skip_ 'This test requires mount with a working --bind option.' + +echo a/b/c > exp || framework_failure_ +echo a/b >> exp || framework_failure_ + +du a/b > out 2> err || fail=1 +sed 's/^[0-9][0-9]* //' out > k && mv k out + +compare /dev/null err || fail=1 +compare exp out || fail=1 + +Exit $fail diff --git a/tests/du/bind-mount-dir-cycle.sh b/tests/du/bind-mount-dir-cycle.sh new file mode 100755 index 0000000..0995663 --- /dev/null +++ b/tests/du/bind-mount-dir-cycle.sh @@ -0,0 +1,37 @@ +#!/bin/sh +# Exercise du's new ability to handle bind-mount-induced dir cycles. + +# Copyright (C) 2012-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du +require_root_ + +cleanup_() { umount a/b; } + +mkdir -p a/b || framework_failure_ +mount --bind a a/b \ + || skip_ "This test requires mount with a working --bind option." + +echo a > exp || framework_failure_ + +du a > out 2> err || fail=1 +sed 's/^[0-9][0-9]* //' out > k && mv k out + +compare /dev/null err || fail=1 +compare exp out || fail=1 + +Exit $fail diff --git a/tests/du/deref-args.sh b/tests/du/deref-args.sh new file mode 100755 index 0000000..debc509 --- /dev/null +++ b/tests/du/deref-args.sh @@ -0,0 +1,48 @@ +#!/bin/sh +# Ensure that --dereference-args (-D) gives reasonable names. +# This test would fail for coreutils-5.0.91. + +# Copyright (C) 2003-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du + +mkdir -p dir/a || framework_failure_ +ln -s dir slink || framework_failure_ +printf %65536s x > 64k || framework_failure_ +ln -s 64k slink-to-64k || framework_failure_ + + +du -D slink | sed 's/^[0-9][0-9]* //' > out +# Ensure that the trailing slash is preserved and handled properly. +du -D slink/ | sed 's/^[0-9][0-9]* //' >> out + +# Ensure that -D makes du dereference even symlinks to non-directories. +# Be sure to use --apparent-size. Otherwise, we'd get varying block counts +# depending on file system type (e.g. 68 on ext3 vs. 64 on tmpfs and 72 +# on SELinux-enabled systems). +du --apparent-size --block-size=1K -D slink-to-64k >> out +cat <<\EOF > exp +slink/a +slink +slink/a +slink/ +64 slink-to-64k +EOF + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/du/deref.sh b/tests/du/deref.sh new file mode 100755 index 0000000..5a1085f --- /dev/null +++ b/tests/du/deref.sh @@ -0,0 +1,48 @@ +#!/bin/sh +# prior to coreutils-4.5.3, du -D didn't work in some cases +# Based on an example from Andreas Schwab and/or Michal Svec. +# Also, up to coreutils-8.5, du -L sometimes incorrectly +# counted the space of the followed symlinks. + +# Copyright (C) 2002-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du + +mkdir -p a/sub || framework_failure_ +ln -s a/sub slink || framework_failure_ +touch b || framework_failure_ +ln -s .. a/sub/dotdot || framework_failure_ +ln -s nowhere dangle || framework_failure_ + + +# This used to fail with the following diagnostic: +# du: 'b': No such file or directory +du -sD slink b > /dev/null 2>&1 || fail=1 + +# This used to fail to report the dangling symlink. +returns_ 1 du -L dangle > /dev/null 2>&1 || fail=1 + +# du -L used to mess up, either by counting the symlink's file system space +# itself (-L should follow symlinks, not count their space) +# or (briefly in July 2010) by omitting the entry for "a". +du_L_output=$(du -L a) || fail=1 +du_lL_output=$(du -lL a) || fail=1 +du_x_output=$(du --exclude=dotdot a) || fail=1 +test "X$du_L_output" = "X$du_x_output" || fail=1 +test "X$du_lL_output" = "X$du_x_output" || fail=1 + +Exit $fail diff --git a/tests/du/exclude.sh b/tests/du/exclude.sh new file mode 100755 index 0000000..eedf751 --- /dev/null +++ b/tests/du/exclude.sh @@ -0,0 +1,58 @@ +#!/bin/sh +# make sure du's --exclude option works + +# Copyright (C) 2003-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du + +mkdir -p a/b/c a/x/y a/u/v || framework_failure_ + + +du --exclude=x a | sed 's/^[0-9][0-9]* //' | sort > out || fail=1 +printf '===\n' >> out +printf 'b\n' > excl +du --exclude-from=excl a | sed 's/^[0-9][0-9]* //' | sort >> out || fail=1 +printf '===\n' >> out +# Make sure that we can exclude an entire hierarchy. +du --exclude=a a >> out || fail=1 +# Make sure that we can exclude based on more than one component. +# Before coreutils-5.3.0, this part would fail. +printf '===\n' >> out +du --exclude=a/u --exclude=a/b a \ + | sed 's/^[0-9][0-9]* //' | sort >> out || fail=1 +cat <<\EOF > exp +a +a/b +a/b/c +a/u +a/u/v +=== +a +a/u +a/u/v +a/x +a/x/y +=== +=== +a +a/x +a/x/y +EOF + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/du/fd-leak.sh b/tests/du/fd-leak.sh new file mode 100755 index 0000000..9697d00 --- /dev/null +++ b/tests/du/fd-leak.sh @@ -0,0 +1,43 @@ +#!/bin/sh +# check for file descriptor leak + +# Copyright (C) 2003-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du + +# Call this an expensive test. It's not that expensive, but command line +# limitations might induce failure on some losing systems. +expensive_ + +# Create 1296 (36^2) files. +# Their names and separating spaces take up 3887 bytes. +x='a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9' +f= +for i in $x; do + for j in $x; do + f="$f $i$j" + done +done + +# This may fail due to command line limitations. +touch $f || framework_failure_ + + +# With coreutils-5.0, this would fail due to a file descriptor leak. +du $f > out || fail=1 + +Exit $fail diff --git a/tests/du/files0-from-dir.sh b/tests/du/files0-from-dir.sh new file mode 100755 index 0000000..44287fe --- /dev/null +++ b/tests/du/files0-from-dir.sh @@ -0,0 +1,39 @@ +#!/bin/sh +# ensure that du and wc handle --files0-from=DIR + +# Copyright (C) 2011-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du wc + +mkdir dir + +# Skip this test if reading from a directory succeeds. +# In that case, using --files0-from=dir would yield garbage, +# interpreting the directory entry as a sequence of +# NUL-separated file names. +cat dir > /dev/null && skip_ "cat dir/ succeeds" + +for prog in du wc; do + $prog --files0-from=dir > /dev/null 2>err && fail=1 + printf "$prog: dir:\n" > exp || fail=1 + # The diagnostic string is usually "Is a directory" (ENOTDIR), + # but accept a different string or errno value. + sed "s/dir:.*/dir:/" err > k; mv k err + compare exp err || fail=1 +done + +Exit $fail diff --git a/tests/du/files0-from.pl b/tests/du/files0-from.pl new file mode 100755 index 0000000..bdc3420 --- /dev/null +++ b/tests/du/files0-from.pl @@ -0,0 +1,94 @@ +#!/usr/bin/perl +# Exercise du's --files0-from option. +# FIXME: keep this file in sync with tests/misc/wc-files0-from. + +# Copyright (C) 2004-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +use strict; + +(my $program_name = $0) =~ s|.*/||; + +my $prog = 'du'; + +# Turn off localization of executable's output. +@ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; + +my @Tests = + ( + # invalid extra command line argument + ['f-extra-arg', '--files0-from=- no-such', {IN=>"a"}, {EXIT=>1}, + {ERR => "$prog: extra operand 'no-such'\n" + . "file operands cannot be combined with --files0-from\n" + . "Try '$prog --help' for more information.\n"} + ], + + # missing input file + ['missing', '--files0-from=missing', {EXIT=>1}, + {ERR => "$prog: cannot open 'missing' for reading: " + . "No such file or directory\n"}], + + # input file name of '-' + ['minus-in-stdin', '--files0-from=-', '<', {IN=>{f=>'-'}}, {EXIT=>1}, + {ERR => "$prog: when reading file names from stdin, no file name of" + . " '-' allowed\n"}], + + # empty input, regular file + ['empty', '--files0-from=@AUX@', {AUX=>''}], + + # empty input, from non-regular file + ['empty-nonreg', '--files0-from=/dev/null'], + + # one NUL + ['nul-1', '--files0-from=-', '<', {IN=>"\0"}, {EXIT=>1}, + {ERR => "$prog: -:1: invalid zero-length file name\n"}], + + # two NULs + ['nul-2', '--files0-from=-', '<', {IN=>"\0\0"}, {EXIT=>1}, + {ERR => "$prog: -:1: invalid zero-length file name\n" + . "$prog: -:2: invalid zero-length file name\n"}], + + # one file name, no NUL + ['1', '--files0-from=-', '<', + {IN=>{f=>"g"}}, {AUX=>{g=>''}}, + {OUT=>"0\tg\n"}, {OUT_SUBST=>'s/^\d+/0/'} ], + + # one file name, with NUL + ['1a', '--files0-from=-', '<', + {IN=>{f=>"g\0"}}, {AUX=>{g=>''}}, + {OUT=>"0\tg\n"}, {OUT_SUBST=>'s/^\d+/0/'} ], + + # two identical file names, no final NUL + ['2', '--files0-from=-', '<', + {IN=>{f=>"g\0g"}}, {AUX=>{g=>''}}, + {OUT=>"0\tg\n"}, {OUT_SUBST=>'s/^\d+/0/'} ], + + # two identical file names, with final NUL + ['2a', '--files0-from=-', '<', + {IN=>{f=>"g\0g\0"}}, {AUX=>{g=>''}}, + {OUT=>"0\tg\n"}, {OUT_SUBST=>'s/^\d+/0/'} ], + + # Ensure that $prog processes FILEs following a zero-length name. + ['zero-len', '--files0-from=-', '<', + {IN=>{f=>"\0g\0"}}, {AUX=>{g=>''}}, + {OUT=>"0\tg\n"}, {OUT_SUBST=>'s/^\d+/0/'}, + {ERR => "$prog: -:1: invalid zero-length file name\n"}, {EXIT=>1} ], + ); + +my $save_temps = $ENV{DEBUG}; +my $verbose = $ENV{VERBOSE}; + +my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); +exit $fail; diff --git a/tests/du/hard-link.sh b/tests/du/hard-link.sh new file mode 100755 index 0000000..7cd03d3 --- /dev/null +++ b/tests/du/hard-link.sh @@ -0,0 +1,64 @@ +#!/bin/sh +# Ensure that hard-linked files are counted (and listed) only once. +# Likewise for excluded directories. +# Ensure that hard links _are_ listed twice when using --count-links. + +# Copyright (C) 2003-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du + +mkdir -p dir/sub +( cd dir && + { echo non-empty > f1 + ln f1 f2 + ln -s f1 f3 + echo non-empty > sub/F; } ) + +du -a -L --exclude=sub --count-links dir \ + | sed 's/^[0-9][0-9]* //' | sort -r > out || fail=1 + +# For these tests, transform f1 or f2 or f3 (whichever name is find +# first) to f_. That is necessary because, depending on the type of +# file system, du could encounter any of those linked files first, +# thus listing that one and not the others. +for args in '-L' 'dir' '-L dir' +do + echo === >> out + du -a --exclude=sub $args dir \ + | sed 's/^[0-9][0-9]* //' | sed 's/f[123]/f_/' >> out || fail=1 +done + +cat <<\EOF > exp +dir/f3 +dir/f2 +dir/f1 +dir +=== +dir/f_ +dir +=== +dir/f_ +dir/f_ +dir +=== +dir/f_ +dir +EOF + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/du/inacc-dest.sh b/tests/du/inacc-dest.sh new file mode 100755 index 0000000..b26fd1c --- /dev/null +++ b/tests/du/inacc-dest.sh @@ -0,0 +1,56 @@ +#!/bin/sh +# Prior to coreutils-6.5, an inaccessible destination dir (chmod a-x) +# would cause du to exit prematurely on systems with native openat support. + +# Copyright (C) 2006-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du +skip_if_root_ + +mkdir f && cd f && mkdir a b c d e && touch c/j && chmod a-x c \ + || framework_failure_ + +du > ../t 2>&1 && fail=1 + +# Accept either of the following outputs. +# You get the first from a system with openat _emulation_ (via /proc), +# the second from a system with native openat support. +# FIXME: there may well be a third output, for systems with neither +# /proc support, nor native openat support. + +sed 's/^[0-9][0-9]* //' ../t | sort -u > out +cat <<\EOF > exp || framework_failure_ +. +./a +./b +./c +./d +./e +du: cannot read directory './c': Permission denied +EOF + +# Map a diagnostic like this +# du: cannot access './c/j': Permission denied +# to this: +# du: cannot access './c': Permission denied +# And accept "cannot read directory" in place of "cannot access" +sed "s,/c/j': ,/c': ," out > t && mv t out +sed 's,cannot access,cannot read directory,' out > t && mv t out + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/du/inacc-dir.sh b/tests/du/inacc-dir.sh new file mode 100755 index 0000000..a5c823e --- /dev/null +++ b/tests/du/inacc-dir.sh @@ -0,0 +1,42 @@ +#!/bin/sh +# Ensure that du counts the size of an inaccessible directory. +# Copyright (C) 2007-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du +skip_if_root_ + +mkdir -p a/sub || framework_failure_ + + +du -s a > exp || fail=1 +chmod 0 a/sub || fail=1 +# Expect failure, ignore diagnostics. +du -s a > out 2> /dev/null && fail=1 + +compare exp out || fail=1 + +# Same as above, but don't use -s, so we print +# an entry for the unreadable "sub", too. +chmod 700 a/sub || fail=1 +du -k a > exp || fail=1 +chmod 0 a/sub || fail=1 +# Expect failure, ignore diagnostics. +du -k a > out 2> /dev/null && fail=1 + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/du/inaccessible-cwd.sh b/tests/du/inaccessible-cwd.sh new file mode 100755 index 0000000..464456d --- /dev/null +++ b/tests/du/inaccessible-cwd.sh @@ -0,0 +1,40 @@ +#!/bin/sh +# Ensure that even when run from an inaccessible directory, du can still +# operate on accessible directories elsewhere. + +# Copyright (C) 2003-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +# Before the switch to an fts-based implementation in coreutils 5.0.92, +# this test would fail. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du + +# Skip this test if your system has neither the openat-style functions +# nor /proc/self/fd support with which to emulate them. +require_openat_support_ + +skip_if_root_ + +cwd=$(pwd) +mkdir -p no-x a/b || framework_failure_ +cd no-x || framework_failure_ +chmod 0 . || framework_failure_ + + +du "$cwd/a" > /dev/null || fail=1 + +Exit $fail diff --git a/tests/du/inodes.sh b/tests/du/inodes.sh new file mode 100755 index 0000000..008bfe2 --- /dev/null +++ b/tests/du/inodes.sh @@ -0,0 +1,140 @@ +#!/bin/sh +# exercise du's --inodes option + +# Copyright (C) 2010-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du + +# An empty directory uses only 1 inode. +mkdir d || framework_failure_ +printf '1\td\n' > exp || framework_failure_ + +du --inodes d > out 2>err || fail=1 +compare exp out || fail=1 +compare /dev/null err || fail=1 + +# Add a regular file: 2 inodes used. +touch d/f || framework_failure_ +printf '2\td\n' > exp || framework_failure_ + +du --inodes d > out 2>err || fail=1 +compare exp out || fail=1 +compare /dev/null err || fail=1 + +# Add a hardlink to the file: still only 2 inodes used. +ln -v d/f d/h || framework_failure_ +du --inodes d > out 2>err || fail=1 +compare exp out || fail=1 +compare /dev/null err || fail=1 + +# Now count also hardlinks (-l,--count-links): 3 inodes. +printf '3\td\n' > exp || framework_failure_ +du --inodes -l d > out 2>err || fail=1 +compare exp out || fail=1 +compare /dev/null err || fail=1 + +# Create a directory and summarize: 3 inodes. +mkdir d/d || framework_failure_ +du --inodes -s d > out 2>err || fail=1 +compare exp out || fail=1 +compare /dev/null err || fail=1 + +# Count inodes separated: 1-2. +printf '1\td/d\n2\td\n' > exp || framework_failure_ +du --inodes -S d > out 2>err || fail=1 +compare exp out || fail=1 +compare /dev/null err || fail=1 + +# Count inodes cumulative (default): 1-3. +printf '1\td/d\n3\td\n' > exp || framework_failure_ +du --inodes d > out 2>err || fail=1 +compare exp out || fail=1 +compare /dev/null err || fail=1 + +# Count all items: 1-1-3. +# Sort output because the directory entry order is not defined. +# Also replace the hardlink with the original file name because +# the system may either return 'd/f' or 'd/h' first, and du(1) +# will ignore the other one. +printf '1\td/d\n1\td/f\n3\td\n' | sort > exp || framework_failure_ +du --inodes -a d > out.tmp 2>err || fail=1 +sed 's/h$/f/' out.tmp | sort >out || framework_failure_ +compare exp out || fail=1 +compare /dev/null err || fail=1 + +# Count all items and hardlinks again: 1-1-1-4 +# Sort output because the directory entry order is not defined. +printf '1\td/d\n1\td/h\n1\td/f\n4\td\n' | sort > exp || framework_failure_ +du --inodes -al d > out.tmp 2>err || fail=1 +sort <out.tmp >out || framework_failure_ +compare exp out || fail=1 +compare /dev/null err || fail=1 + +# Run with total (-c) line: 1-3-3 +printf '1\td/d\n3\td\n3\ttotal\n' > exp || framework_failure_ +du --inodes -c d > out 2>err || fail=1 +compare exp out || fail=1 +compare /dev/null err || fail=1 + +# Create another file in the subdirectory: 2-4 +touch d/d/f || framework_failure_ +printf '2\td/d\n4\td\n' > exp || framework_failure_ +du --inodes d > out 2>err || fail=1 +compare exp out || fail=1 +compare /dev/null err || fail=1 + +# Ensure human output (-h, --si) works. +rm -rf d || framework_failure_ +mkdir d || framework_failure_ +seq --format="d/file%g" 1023 | xargs touch || framework_failure_ +printf '1.0K\td\n' > exp || framework_failure_ +du --inodes -h d > out 2>err || fail=1 +compare exp out || fail=1 +compare /dev/null err || fail=1 + +printf '1.1k\td\n' > exp || framework_failure_ +du --inodes --si d > out 2>err || fail=1 +compare exp out || fail=1 +compare /dev/null err || fail=1 + +# Verify --inodes ignores -B. +printf '1024\td\n' > exp || framework_failure_ +du --inodes -B10 d > out 2>err || fail=1 +compare exp out || fail=1 +compare /dev/null err || fail=1 + +# Verify --inodes works with --threshold. +printf '1024\td\n' > exp || framework_failure_ +du --inodes --threshold=1000 d > out 2>err || fail=1 +compare exp out || fail=1 +compare /dev/null err || fail=1 + +du --inodes --threshold=-1000 d > out 2>err || fail=1 +compare /dev/null out || fail=1 +compare /dev/null err || fail=1 + +# Verify --inodes raises a warning for --apparent-size and -b. +du --inodes -b d > out 2>err || fail=1 +grep ' ineffective ' err >/dev/null || { fail=1; cat out err; } + +du --inodes --apparent-size d > out 2>err || fail=1 +grep ' ineffective ' err >/dev/null || { fail=1; cat out err; } + +# Ensure that --inodes is mentioned in the usage. +du --help > out || fail=1 +grep ' --inodes ' out >/dev/null || { fail=1; cat out; } +Exit $fail diff --git a/tests/du/long-from-unreadable.sh b/tests/du/long-from-unreadable.sh new file mode 100755 index 0000000..3a2e19b --- /dev/null +++ b/tests/du/long-from-unreadable.sh @@ -0,0 +1,74 @@ +#!/bin/sh +# Show fts fails on old-fashioned systems. + +# Copyright (C) 2006-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +# Show that fts (hence du, chmod, chgrp, chown) fails when all of the +# following are true: +# - '.' is not readable +# - operating on a hierarchy containing a relative name longer than PATH_MAX +# - run on a system where gnulib's openat emulation must resort to using +# save_cwd and restore_cwd (which fail if '.' is not readable). +# Thus, the following du invocation should succeed on newer Linux and +# Solaris systems, yet it must fail on systems lacking both openat and +# /proc support. However, before coreutils-6.0 this test would fail even +# on Linux+PROC_FS systems because its fts implementation would revert +# unnecessarily to using FTS_NOCHDIR mode in this corner case. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du + +require_perl_ + +# ecryptfs for example uses some of the file name space +# for encrypting filenames, so we must check dynamically. +name_max=$(stat -f -c %l .) +test "$name_max" -ge '200' || skip_ "NAME_MAX=$name_max is not sufficient" + +proc_file=/proc/self/fd +if test ! -d $proc_file; then + skip_ 'This test would fail, since your system lacks /proc support.' +fi + +dir=$(printf '%200s\n' ' '|tr ' ' x) + +# Construct a hierarchy containing a relative file with a name +# longer than PATH_MAX. +# for i in $(seq 52); do +# mkdir $dir || framework_failure_ +# cd $dir || framework_failure_ +# done +# cd $tmp || framework_failure_ + +# Sheesh. Bash 3.1.5 can't create this hierarchy. I get +# cd: error retrieving current directory: getcwd: +# cannot access parent directories: +# (all on one line). + +cwd=$(pwd) +# Use perl instead: +$PERL \ + -e 'my $d = '$dir'; foreach my $i (1..52)' \ + -e ' { mkdir ($d, 0700) && chdir $d or die "$!" }' \ + || framework_failure_ + +mkdir inaccessible || framework_failure_ +cd inaccessible || framework_failure_ +chmod 0 . || framework_failure_ + +du -s "$cwd/$dir" > /dev/null || fail=1 + +Exit $fail diff --git a/tests/du/long-sloop.sh b/tests/du/long-sloop.sh new file mode 100755 index 0000000..f93bca8 --- /dev/null +++ b/tests/du/long-sloop.sh @@ -0,0 +1,72 @@ +#!/bin/sh +# Use du to exercise a corner of fts's FTS_LOGICAL code. +# Show that du fails with ELOOP (Too many levels of symbolic links) +# when it encounters that condition. + +# Copyright (C) 2006-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du + +# Create lots of directories, each containing a single symlink +# pointing at the next directory in the list. + +# This number should be larger than the number of symlinks allowed in +# file name resolution, but not too large as a number of entries +# in a single directory. +n=400 + +dir_list=$(seq $n) +mkdir $dir_list || framework_failure_ +file=1 +i_minus_1=0 +for i in $dir_list $(expr $n + 1); do + case $i_minus_1 in + 0) ;; + *) + ln -s ../$i $i_minus_1/s || framework_failure_ + file=$file/s;; + esac + i_minus_1=$i +done +echo foo > $i || framework_failure_ + +# If a system can handle this many symlinks in a file name, +# just skip this test. + +# The following also serves to record in 'err' the string +# corresponding to strerror (ELOOP). This is necessary because while +# Linux/libc gives 'Too many levels of symbolic links', Solaris +# renders it as "Number of symbolic links encountered during path +# name traversal exceeds MAXSYMLINKS". + +cat $file > /dev/null 2> err && + skip_ 'Your system appears to be able to handle more than $n symlinks +in file name resolution' +too_many=$(sed 's/.*: //' err) + + +# With coreutils-5.93 there was no failure. +# With coreutils-5.94 we get the desired diagnostic: +# du: cannot access '1/s/s/s/.../s': Too many levels of symbolic links +du -L 1 > /dev/null 2> out1 && fail=1 +sed "s, .1/s/s/s/[/s]*',," out1 > out || framework_failure_ + +echo "du: cannot access: $too_many" > exp || framework_failure_ + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/du/max-depth.sh b/tests/du/max-depth.sh new file mode 100755 index 0000000..4699263 --- /dev/null +++ b/tests/du/max-depth.sh @@ -0,0 +1,39 @@ +#!/bin/sh +# exercise du's --max-depth=N option + +# Copyright (C) 2010-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du + +mkdir -p a/b/c/d/e || framework_failure_ +printf 'a/b/c\na/b\na\n' > exp || framework_failure_ + +du --max-depth=2 a > out 2>err || fail=1 + +# Remove the sizes. They vary between file systems. +cut -f2- out > k && mv k out +compare exp out || fail=1 +compare /dev/null err || fail=1 + +# Repeat, but use -d 1. +printf 'a/b\na\n' > exp || framework_failure_ +du -d 1 a > out 2>err || fail=1 +cut -f2- out > k && mv k out +compare exp out || fail=1 +compare /dev/null err || fail=1 + +Exit $fail diff --git a/tests/du/move-dir-while-traversing.sh b/tests/du/move-dir-while-traversing.sh new file mode 100755 index 0000000..a9708de --- /dev/null +++ b/tests/du/move-dir-while-traversing.sh @@ -0,0 +1,99 @@ +#!/bin/sh +# Trigger a failed assertion in coreutils-8.9 and earlier. + +# Copyright (C) 2011-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du +require_trap_signame_ + +# We use a python-inotify script, so... +python -m pyinotify -h > /dev/null \ + || skip_ 'python inotify package not installed' + +# Move a directory "up" while du is processing its sub-directories. +# While du is processing a hierarchy .../B/C/D/... this script +# detects when du opens D/, and then moves C/ "up" one level +# so that it is a sibling of B/. +# Given the inherent race condition, we have to add enough "weight" +# under D/ so that in most cases, the monitor performs the single +# rename syscall before du finishes processing the subtree under D/. + +cat <<'EOF' > inotify-watch-for-dir-access.py +#!/usr/bin/env python +import pyinotify as pn +import os,sys + +dir = sys.argv[1] +dest_parent = os.path.dirname(os.path.dirname(dir)) +dest = os.path.join(dest_parent, os.path.basename(dir)) + +class ProcessDir(pn.ProcessEvent): + + def process_IN_OPEN(self, event): + os.rename(dir, dest) + sys.exit(0) + + def process_default(self, event): + pass + +wm = pn.WatchManager() +notifier = pn.Notifier(wm) +wm.watch_transient_file(dir, pn.IN_OPEN, ProcessDir) +sys.stdout.write('started\n') +sys.stdout.flush() +notifier.loop() +EOF +chmod a+x inotify-watch-for-dir-access.py + +t=T/U +mkdir d2 || framework_failure_ +long=d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z +# One iteration of this loop creates a tree with which +# du sometimes completes its traversal before the above rename. +# Five iterations was not enough in 2 of 7 "make -j20 check" runs on a +# 6/12-core system. However, using "10", I saw no failure in 20 trials. +# Using 10 iterations was not enough, either. +# Using 50, I saw no failure in 200 trials. +for i in $(seq 50); do + mkdir -p $t/3/a/b/c/$i/$long || framework_failure_ +done + +# Terminate any background cp process +cleanup_() { kill $pid 2>/dev/null && wait $pid; } + +# Prohibit suspension, which could otherwise cause a timeout-induced FP failure. +trap '' TSTP + +timeout 6 ./inotify-watch-for-dir-access.py $t/3/a/b > start-msg & pid=$! + +# Wait for the watcher to start... +nonempty() { sleep $1; test -s start-msg; } +retry_delay_ nonempty .1 5 || fail=1 + +# The above watches for an IN_OPEN event on $t/3/a/b, +# and when it triggers, moves the parent, $t/3/a, up one level +# so it's directly under $t. + +# Before coreutils-8.10, du would abort. +returns_ 1 du -a $t d2 2> err || fail=1 + +# check for the new diagnostic +printf "du: fts_read failed: $t/3/a/b: No such file or directory\n" > exp \ + || fail=1 +compare exp err || fail=1 + +Exit $fail diff --git a/tests/du/no-deref.sh b/tests/du/no-deref.sh new file mode 100755 index 0000000..4bae934 --- /dev/null +++ b/tests/du/no-deref.sh @@ -0,0 +1,33 @@ +#!/bin/sh +# Ensure that by default, du doesn't dereference command-line symlinks. + +# Copyright (C) 2003-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du + +mkdir -p dir/a/b || framework_failure_ +ln -s dir slink || framework_failure_ + + +du slink | sed 's/^[0-9][0-9]* //' > out +cat <<\EOF > exp +slink +EOF + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/du/no-x.sh b/tests/du/no-x.sh new file mode 100755 index 0000000..79920a9 --- /dev/null +++ b/tests/du/no-x.sh @@ -0,0 +1,49 @@ +#!/bin/sh +# Make sure du gives the right diagnostic for a readable, +# but inaccessible directory. + +# Copyright (C) 2003-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du +skip_if_root_ + +mkdir -p d/no-x/y || framework_failure_ +chmod u=rw d/no-x || framework_failure_ + + +# This must exit nonzero. +du d >/dev/null 2>out && fail=1 + +prog=du +# NOTE: this code is the same for all tests/*/no-x tests. +# Depending on whether fts is using native fdopendir, we see one +# of the following diagnostics (note also the /y suffix in one case): +# prog: 'd/no-x': Permission denied +# prog: cannot access 'd/no-x/y': Permission denied +# prog: cannot read directory 'd/no-x': Permission denied +# Convert either of the latter two to the first one. +sed "s/^$prog: cannot access /$prog: /" out > t && mv t out +sed "s/^$prog: cannot read directory /$prog: /" out > t && mv t out +sed 's,d/no-x/y,d/no-x,' out > t && mv t out + +cat <<EOF > exp +$prog: 'd/no-x': Permission denied +EOF + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/du/one-file-system.sh b/tests/du/one-file-system.sh new file mode 100755 index 0000000..fff35ea --- /dev/null +++ b/tests/du/one-file-system.sh @@ -0,0 +1,57 @@ +#!/bin/sh +# Test for bugs in du's --one-file-system (-x) option. + +# Copyright (C) 2006-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du +cleanup_() { rm -rf "$other_partition_tmpdir"; } +. "$abs_srcdir/tests/other-fs-tmpdir" + +mkdir -p b/c y/z d "$other_partition_tmpdir/x" || framework_failure_ +ln -s "$other_partition_tmpdir/x" d || framework_failure_ + +# Due to a used-uninitialized variable, the "du -x" from coreutils-6.6 +# would not traverse into second and subsequent directories listed +# on the command line. +du -ax b y > t || fail=1 +sed 's/^[0-9][0-9]* //' t > out || framework_failure_ +cat <<\EOF > exp || framework_failure_ +b/c +b +y/z +y +EOF + +compare exp out || fail=1 + +# "du -xL" reported a zero count for a file in a different file system, +# instead of ignoring it. +du -xL d > u || fail=1 +sed 's/^[0-9][0-9]* //' u > out1 || framework_failure_ +echo d > exp1 || framework_failure_ +compare exp1 out1 || fail=1 + +# With coreutils-8.15, "du -xs FILE" would print no output. +touch f +for opt in -x -xs; do + du $opt f > u || fail=1 + sed 's/^[0-9][0-9]* //' u > out2 || framework_failure_ + echo f > exp2 || framework_failure_ + compare exp2 out2 || fail=1 +done + +Exit $fail diff --git a/tests/du/restore-wd.sh b/tests/du/restore-wd.sh new file mode 100755 index 0000000..c9c5069 --- /dev/null +++ b/tests/du/restore-wd.sh @@ -0,0 +1,31 @@ +#!/bin/sh +# due to a bug in glibc's ftw.c, in some cases, nftw w/FTW_CHDIR +# would not restore the working directory. + +# Copyright (C) 2003-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du + +mkdir a b || framework_failure_ + + +# With du from coreutils-4.5.5 and 4.5.6, this would fail with +# du: 'b': No such file or directory + +du a b > out || fail=1 + +Exit $fail diff --git a/tests/du/slash.sh b/tests/du/slash.sh new file mode 100755 index 0000000..6426d16 --- /dev/null +++ b/tests/du/slash.sh @@ -0,0 +1,33 @@ +#!/bin/sh +# 'du /' would omit the '/' on the last line. + +# Copyright (C) 2003-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du +require_readable_root_ + + +du --exclude='[^/]*' -x / > out-t || fail=1 +sed 's/^[0-9][0-9]* //' out-t > out +rm -f out-t +cat <<\EOF > exp +/ +EOF + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/du/threshold.sh b/tests/du/threshold.sh new file mode 100755 index 0000000..270b885 --- /dev/null +++ b/tests/du/threshold.sh @@ -0,0 +1,362 @@ +#!/bin/sh +# Exercise du's --threshold option. + +# Copyright (C) 2013-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du + +mkdir -p a/b a/c || framework_failure_ + +touch a/b/0 || framework_failure_ +printf '%1s' x > a/b/1 || framework_failure_ +printf '%2s' x > a/b/2 || framework_failure_ +printf '%3s' x > a/b/3 || framework_failure_ + +Ba=$(stat --format="%B * %b" a | xargs expr) +Bb=$(stat --format="%B * %b" a/b | xargs expr) +Bc=$(stat --format="%B * %b" a/c | xargs expr) +B0=$(stat --format="%B * %b" a/b/0 | xargs expr) +B1=$(stat --format="%B * %b" a/b/1 | xargs expr) +B2=$(stat --format="%B * %b" a/b/2 | xargs expr) +B3=$(stat --format="%B * %b" a/b/3 | xargs expr) + +Sa=$(stat --format=%s a ) +Sb=$(stat --format=%s a/b ) +Sc=$(stat --format=%s a/c ) +S0=$(stat --format=%s a/b/0) +S1=$(stat --format=%s a/b/1) +S2=$(stat --format=%s a/b/2) +S3=$(stat --format=%s a/b/3) + +Bb0123=$(expr $Bb + $B0 + $B1 + $B2 + $B3) +Sb0123=$(expr $Sb + $S0 + $S1 + $S2 + $S3) + +Bab0123=$(expr $Ba + $Bc + $Bb0123) +Sab0123=$(expr $Sa + $Sc + $Sb0123) + +# Sanity checks +test $Ba -gt 4 || skip_ "block size of a directory is smaller than 4 bytes" +test $Bc -gt 4 || skip_ "block size of an empty directory is smaller than 4 \ +bytes" +test $Sa -gt 4 || skip_ "apparent size of a directory is smaller than 4 bytes" +test $B1 -gt 4 || skip_ "block size of small file smaller than 4 bytes" +test $S3 -eq 3 || framework_failure_ +test $S2 -eq 2 || framework_failure_ +test $S1 -eq 1 || framework_failure_ +test $S0 -eq 0 || framework_failure_ +test $B0 -eq 0 || skip_ "block size of an empty file unequal Zero" +# block size of a/b/1 == a/b/2 +test $B1 -eq $B2 || framework_failure_ +# a is bigger than a/b. +test $Sab0123 -gt $Sb0123 || framework_failure_ +test $Bab0123 -gt $Bb0123 || framework_failure_ +# a/b is bigger than empty a/c. +test $Sb0123 -gt $Sc || framework_failure_ +test $Bb0123 -gt $Bc || framework_failure_ + +# Exercise a bad argument: unparsable number. +cat <<EOF > exp +du: invalid --threshold argument 'SIZE' +EOF +du --threshold=SIZE a > out 2>&1 && fail=1 +compare exp out || fail=1 + +cat <<EOF > exp +du: invalid -t argument 'SIZE' +EOF +du -t SIZE a > out 2>&1 && fail=1 +compare exp out || fail=1 + +# Exercise a bad argument: -0 is not valid. +cat <<EOF > exp +du: invalid --threshold argument '-0' +EOF +du --threshold=-0 a > out 2>&1 && fail=1 +compare exp out || fail=1 + +du -t -0 a > out 2>&1 && fail=1 +compare exp out || fail=1 + +du -t-0 a > out 2>&1 && fail=1 +compare exp out || fail=1 + +# Exercise a bad argument: empty argument. +cat <<EOF > exp +du: invalid --threshold argument '' +EOF +du --threshold= a > out 2>&1 && fail=1 +compare exp out || fail=1 + +# Exercise a bad argument: no argument. +du --threshold > out.tmp 2>&1 && fail=1 +sed 's/argument.*/argument/; s/option.*requires/option requires/' \ + < out.tmp > out || framework_failure_ +cat <<EOF > exp +du: option requires an argument +Try 'du --help' for more information. +EOF +compare exp out || fail=1 +rm -f out + +dutest () +{ + args="$1" + exp="$2" + + rm -f exp out + + # Expected output. + if [ "$exp" = "" ] ; then + touch exp + else + printf "%s\n" $exp > exp + fi + + rc=0 + du -B1 $args a > out1 2>&1 || { cat out1 ; rc=1 ; } + + # Remove the size column and sort the output. + cut -f2- out1 | sort > out || framework_failure_ + + compare exp out || { cat out1 ; rc=1 ; } + return $rc +} + +# Check numbers around the total size of the main directory 'a'. +# One byte greater than 'a'. +s=$(expr $Sab0123 + 1) # apparent size +dutest "--app -t $s" '' || fail=1 +dutest "--app -a -t $s" '' || fail=1 +dutest "--app -S -t $s" '' || fail=1 +dutest "--app -a -S -t $s" '' || fail=1 +dutest "--app -t -$s" 'a a/b a/c' || fail=1 +dutest "--app -a -t -$s" 'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 +dutest "--app -S -t -$s" 'a a/b a/c' || fail=1 +dutest "--app -a -S -t -$s" 'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 +s=$(expr $Bab0123 + 1) # block size +dutest " -t $s" '' || fail=1 +dutest " -a -t $s" '' || fail=1 +dutest " -S -t $s" '' || fail=1 +dutest " -a -S -t $s" '' || fail=1 +dutest " -t -$s" 'a a/b a/c' || fail=1 +dutest " -a -t -$s" 'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 +dutest " -S -t -$s" 'a a/b a/c' || fail=1 +dutest " -a -S -t -$s" 'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 + +# Exactly the size of 'a'. +s=$Sab0123 # apparent size +dutest "--app --th=$s" 'a' || fail=1 +dutest "--app -a --th=$s" 'a' || fail=1 +dutest "--app -S --th=$s" '' || fail=1 +dutest "--app -a -S --th=$s" '' || fail=1 +dutest "--app --th=-$s" 'a a/b a/c' || fail=1 +dutest "--app -a --th=-$s" 'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 +dutest "--app -S --th=-$s" 'a a/b a/c' || fail=1 +dutest "--app -a -S --th=-$s" 'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 +s=$Bab0123 # block size +dutest " --th=$s" 'a' || fail=1 +dutest " -a --th=$s" 'a' || fail=1 +dutest " -S --th=$s" '' || fail=1 +dutest " -a -S --th=$s" '' || fail=1 +dutest " --th=-$s" 'a a/b a/c' || fail=1 +dutest " -a --th=-$s" 'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 +dutest " -S --th=-$s" 'a a/b a/c' || fail=1 +dutest " -a -S --th=-$s" 'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 + +# One byte smaller than 'a'. +s=$(expr $Sab0123 - 1) # apparent size +dutest "--app --th=$s" 'a' || fail=1 +dutest "--app -a --th=$s" 'a' || fail=1 +dutest "--app -S --th=$s" '' || fail=1 +dutest "--app -a -S --th=$s" '' || fail=1 +dutest "--app --th=-$s" 'a/b a/c' || fail=1 +dutest "--app -a --th=-$s" 'a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 +dutest "--app -S --th=-$s" 'a a/b a/c' || fail=1 +dutest "--app -a -S --th=-$s" 'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 +s=$(expr $Bab0123 - 1) # block size +dutest " --th=$s" 'a' || fail=1 +dutest " -a --th=$s" 'a' || fail=1 +dutest " -S --th=$s" '' || fail=1 +dutest " -a -S --th=$s" '' || fail=1 +dutest " --th=-$s" 'a/b a/c' || fail=1 +dutest " -a --th=-$s" 'a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 +dutest " -S --th=-$s" 'a a/b a/c' || fail=1 +dutest " -a -S --th=-$s" 'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 + + +# Check numbers around the total size of the sub directory 'a/b'. +# One byte greater than 'a/b'. +s=$(expr $Sb0123 + 1) # apparent size +dutest "--app --th=$s" 'a' || fail=1 +dutest "--app -a --th=$s" 'a' || fail=1 +dutest "--app -S --th=$s" '' || fail=1 +dutest "--app -a -S --th=$s" '' || fail=1 +dutest "--app --th=-$s" 'a/b a/c' || fail=1 +dutest "--app -a --th=-$s" 'a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 +dutest "--app -S --th=-$s" 'a a/b a/c' || fail=1 +dutest "--app -a -S --th=-$s" 'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 +s=$(expr $Bb0123 + 1) # block size +dutest " --th=$s" 'a' || fail=1 +dutest " -a --th=$s" 'a' || fail=1 +dutest " -S --th=$s" '' || fail=1 +dutest " -a -S --th=$s" '' || fail=1 +dutest " --th=-$s" 'a/b a/c' || fail=1 +dutest " -a --th=-$s" 'a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 +dutest " -S --th=-$s" 'a a/b a/c' || fail=1 +dutest " -a -S --th=-$s" 'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 + +# Exactly the size of 'a/b'. +s=$Sb0123 # apparent size +dutest "--app --th=$s" 'a a/b' || fail=1 +dutest "--app -a --th=$s" 'a a/b' || fail=1 +dutest "--app -S --th=$s" 'a/b' || fail=1 +dutest "--app -a -S --th=$s" 'a/b' || fail=1 +dutest "--app --th=-$s" 'a/b a/c' || fail=1 +dutest "--app -a --th=-$s" 'a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 +dutest "--app -S --th=-$s" 'a a/b a/c' || fail=1 +dutest "--app -a -S --th=-$s" 'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 +s=$Bb0123 # block size +dutest " --th=$s" 'a a/b' || fail=1 +dutest " -a --th=$s" 'a a/b' || fail=1 +dutest " -S --th=$s" 'a/b' || fail=1 +dutest " -a -S --th=$s" 'a/b' || fail=1 +dutest " --th=-$s" 'a/b a/c' || fail=1 +dutest " -a --th=-$s" 'a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 +dutest " -S --th=-$s" 'a a/b a/c' || fail=1 +dutest " -a -S --th=-$s" 'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 + +# One byte smaller than 'a/b'. +s=$(expr $Sb0123 - 1) # apparent size +dutest "--app --th=$s" 'a a/b' || fail=1 +dutest "--app -a --th=$s" 'a a/b' || fail=1 +dutest "--app -S --th=$s" 'a/b' || fail=1 +dutest "--app -a -S --th=$s" 'a/b' || fail=1 +dutest "--app --th=-$s" 'a/c' || fail=1 +dutest "--app -a --th=-$s" 'a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 +dutest "--app -S --th=-$s" 'a a/c' || fail=1 +dutest "--app -a -S --th=-$s" 'a a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 +s=$(expr $Bb0123 - 1) # block size +dutest " --th=$s" 'a a/b' || fail=1 +dutest " -a --th=$s" 'a a/b' || fail=1 +dutest " -S --th=$s" 'a/b' || fail=1 +dutest " -a -S --th=$s" 'a/b' || fail=1 +dutest " --th=-$s" 'a/c' || fail=1 +dutest " -a --th=-$s" 'a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 +dutest " -S --th=-$s" 'a a/c' || fail=1 +dutest " -a -S --th=-$s" 'a a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 + + +# Check numbers around the total size of the files a/b/[0123]'. +echo One byte greater than 'a/b/3'. +s=$(expr $S3 + 1) # apparent size +dutest "--app --th=$s" 'a a/b a/c' || fail=1 +dutest "--app -a --th=$s" 'a a/b a/c' || fail=1 +dutest "--app -S --th=$s" 'a a/b a/c' || fail=1 +dutest "--app -a -S --th=$s" 'a a/b a/c' || fail=1 +dutest "--app --th=-$s" '' || fail=1 +dutest "--app -a --th=-$s" 'a/b/0 a/b/1 a/b/2 a/b/3' || fail=1 +dutest "--app -S --th=-$s" '' || fail=1 +dutest "--app -a -S --th=-$s" 'a/b/0 a/b/1 a/b/2 a/b/3' || fail=1 +s=$(expr $B3 + 1) # block size +dutest " --th=$s" 'a a/b' || fail=1 +dutest " -a --th=$s" 'a a/b' || fail=1 +dutest " -S --th=$s" 'a/b' || fail=1 +dutest " -a -S --th=$s" 'a/b' || fail=1 +dutest " --th=-$s" 'a/c' || fail=1 +dutest " -a --th=-$s" 'a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 +dutest " -S --th=-$s" 'a a/c' || fail=1 +dutest " -a -S --th=-$s" 'a a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 + +# Exactly the size of 'a/b/3'. +echo Exactly the size of 'a/b/3'. +s=$S3 # apparent size +dutest "--app --th=$s" 'a a/b a/c' || fail=1 +dutest "--app -a --th=$s" 'a a/b a/b/3 a/c' || fail=1 +dutest "--app -S --th=$s" 'a a/b a/c' || fail=1 +dutest "--app -a -S --th=$s" 'a a/b a/b/3 a/c' || fail=1 +dutest "--app --th=-$s" '' || fail=1 +dutest "--app -a --th=-$s" 'a/b/0 a/b/1 a/b/2 a/b/3' || fail=1 +dutest "--app -S --th=-$s" '' || fail=1 +dutest "--app -a -S --th=-$s" 'a/b/0 a/b/1 a/b/2 a/b/3' || fail=1 +s=$B3 # block size +dutest " --th=$s" 'a a/b a/c' || fail=1 +dutest " -a --th=$s" 'a a/b a/b/1 a/b/2 a/b/3 a/c' || fail=1 +dutest " -S --th=$s" 'a a/b a/c' || fail=1 +dutest " -a -S --th=$s" 'a a/b a/b/1 a/b/2 a/b/3 a/c' || fail=1 +dutest " --th=-$s" 'a/c' || fail=1 +dutest " -a --th=-$s" 'a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 +dutest " -S --th=-$s" 'a a/c' || fail=1 +dutest " -a -S --th=-$s" 'a a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 + +# Exactly the size of 'a/b/2'. +echo Exactly the size of 'a/b/2'. +s=$S2 # apparent size +dutest "--app --th=$s" 'a a/b a/c' || fail=1 +dutest "--app -a --th=$s" 'a a/b a/b/2 a/b/3 a/c' || fail=1 +dutest "--app -S --th=$s" 'a a/b a/c' || fail=1 +dutest "--app -a -S --th=$s" 'a a/b a/b/2 a/b/3 a/c' || fail=1 +dutest "--app --th=-$s" '' || fail=1 +dutest "--app -a --th=-$s" 'a/b/0 a/b/1 a/b/2' || fail=1 +dutest "--app -S --th=-$s" '' || fail=1 +dutest "--app -a -S --th=-$s" 'a/b/0 a/b/1 a/b/2' || fail=1 +s=$B2 # block size +dutest " --th=$s" 'a a/b a/c' || fail=1 +dutest " -a --th=$s" 'a a/b a/b/1 a/b/2 a/b/3 a/c' || fail=1 +dutest " -S --th=$s" 'a a/b a/c' || fail=1 +dutest " -a -S --th=$s" 'a a/b a/b/1 a/b/2 a/b/3 a/c' || fail=1 +dutest " --th=-$s" 'a/c' || fail=1 +dutest " -a --th=-$s" 'a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 +dutest " -S --th=-$s" 'a a/c' || fail=1 +dutest " -a -S --th=-$s" 'a a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 + +# Exactly the size of 'a/b/1'. +echo Exactly the size of 'a/b/1'. +s=$S1 # apparent size +dutest "--app --th=$s" 'a a/b a/c' || fail=1 +dutest "--app -a --th=$s" 'a a/b a/b/1 a/b/2 a/b/3 a/c' || fail=1 +dutest "--app -S --th=$s" 'a a/b a/c' || fail=1 +dutest "--app -a -S --th=$s" 'a a/b a/b/1 a/b/2 a/b/3 a/c' || fail=1 +dutest "--app --th=-$s" '' || fail=1 +dutest "--app -a --th=-$s" 'a/b/0 a/b/1' || fail=1 +dutest "--app -S --th=-$s" '' || fail=1 +dutest "--app -a -S --th=-$s" 'a/b/0 a/b/1' || fail=1 +s=$B1 # block size +dutest " --th=$s" 'a a/b a/c' || fail=1 +dutest " -a --th=$s" 'a a/b a/b/1 a/b/2 a/b/3 a/c' || fail=1 +dutest " -S --th=$s" 'a a/b a/c' || fail=1 +dutest " -a -S --th=$s" 'a a/b a/b/1 a/b/2 a/b/3 a/c' || fail=1 +dutest " --th=-$s" 'a/c' || fail=1 +dutest " -a --th=-$s" 'a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 +dutest " -S --th=-$s" 'a a/c' || fail=1 +dutest " -a -S --th=-$s" 'a a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 + +# Exactly the size of 'a/b/0'. +echo Exactly the size of 'a/b/0'. +s=$S0 # apparent size +dutest "--app --th=$s" 'a a/b a/c' || fail=1 +dutest "--app -a --th=$s" 'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 +dutest "--app -S --th=$s" 'a a/b a/c' || fail=1 +dutest "--app -a -S --th=$s" 'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 +# (maximum tests (-0) not possible). +s=$B0 # block size +dutest " --th=$s" 'a a/b a/c' || fail=1 +dutest " -a --th=$s" 'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 +dutest " -S --th=$s" 'a a/b a/c' || fail=1 +dutest " -a -S --th=$s" 'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1 +# (maximum tests (-0) not possible). + +Exit $fail diff --git a/tests/du/trailing-slash.sh b/tests/du/trailing-slash.sh new file mode 100755 index 0000000..01b5e61 --- /dev/null +++ b/tests/du/trailing-slash.sh @@ -0,0 +1,47 @@ +#!/bin/sh +# Ensure that du works properly for an argument that refers to a +# symbolic link, and that is specified with a trailing slash. + +# Copyright (C) 2002-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +# Before coreutils-4.5.3, it would remove a single trailing slash. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du + +mkdir -p dir/1/2 || framework_failure_ +ln -s dir slink || framework_failure_ + + +du slink/ | sed 's/^[0-9][0-9]* //' > out +echo === >> out + +# Ensure that with -L we get the same results (modulo the trailing slash +# on the third line) even without the trailing slash on the command line. +du -L slink | sed 's/^[0-9][0-9]* //' >> out +cat <<\EOF > exp +slink/1/2 +slink/1 +slink/ +=== +slink/1/2 +slink/1 +slink +EOF + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/du/two-args.sh b/tests/du/two-args.sh new file mode 100755 index 0000000..01b5e33 --- /dev/null +++ b/tests/du/two-args.sh @@ -0,0 +1,40 @@ +#!/bin/sh +# Make sure 'du d/1 d/2' works. +# That command failed with du from fileutils-4.0q. + +# Copyright (C) 2000-2022 Free Software Foundation, 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 3 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, see <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ du + +# Run this test from a sub-directory one level deeper than normal, +# so that the "du .." below doesn't traverse sibling directories +# that may be inaccessible due concurrently-running tests. +mkdir sub || framework_failure_ +cd sub || framework_failure_ + +t=t +mkdir -p $t/1 $t/2 || framework_failure_ + +test -d $t || fail=1 +du $t/1 $t/2 > /dev/null || fail=1 + +# Make sure 'du . $t' and 'du .. $t' work. +# These would fail prior to fileutils-4.0y. +du . $t > /dev/null || fail=1 +du .. $t > /dev/null || fail=1 + +Exit $fail |