1#!/bin/sh
2# Exercise du's --threshold option.
3
4# Copyright (C) 2013-2023 Free Software Foundation, Inc.
5
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15
16# You should have received a copy of the GNU General Public License
17# along with this program.  If not, see <https://www.gnu.org/licenses/>.
18
19. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
20print_ver_ du
21
22mkdir -p a/b a/c || framework_failure_
23
24touch            a/b/0 || framework_failure_
25printf '%1s' x > a/b/1 || framework_failure_
26printf '%2s' x > a/b/2 || framework_failure_
27printf '%3s' x > a/b/3 || framework_failure_
28
29Ba=$(stat --format="%B * %b" a     | xargs expr)
30Bb=$(stat --format="%B * %b" a/b   | xargs expr)
31Bc=$(stat --format="%B * %b" a/c   | xargs expr)
32B0=$(stat --format="%B * %b" a/b/0 | xargs expr)
33B1=$(stat --format="%B * %b" a/b/1 | xargs expr)
34B2=$(stat --format="%B * %b" a/b/2 | xargs expr)
35B3=$(stat --format="%B * %b" a/b/3 | xargs expr)
36
37Sa=0 # du always assumes st_size=0 for dirs
38Sb=0
39Sc=0
40S0=$(stat --format=%s a/b/0)
41S1=$(stat --format=%s a/b/1)
42S2=$(stat --format=%s a/b/2)
43S3=$(stat --format=%s a/b/3)
44
45Bb0123=$(expr $Bb + $B0 + $B1 + $B2 + $B3)
46Sb0123=$(expr $Sb + $S0 + $S1 + $S2 + $S3)
47
48Bab0123=$(expr $Ba + $Bc + $Bb0123)
49
50# Sanity checks
51test $Ba -gt 4 || skip_ "block size of a directory is smaller than 4 bytes"
52test $Bc -gt 4 || skip_ "block size of an empty directory is smaller than 4 \
53bytes"
54test $B1 -gt 4 || skip_ "block size of small file smaller than 4 bytes"
55test $S3 -eq 3 || framework_failure_
56test $S2 -eq 2 || framework_failure_
57test $S1 -eq 1 || framework_failure_
58test $S0 -eq 0 || framework_failure_
59test $B0 -eq 0 || skip_ "block size of an empty file unequal Zero"
60# block size of a/b/1 == a/b/2
61test $B1 -eq $B2 || framework_failure_
62# a is bigger than a/b.
63test $Bab0123 -gt $Bb0123 || framework_failure_
64# a/b is bigger than empty a/c.
65test $Sb0123 -gt $Sc || framework_failure_
66test $Bb0123 -gt $Bc || framework_failure_
67
68# Exercise a bad argument: unparsable number.
69cat <<EOF > exp
70du: invalid --threshold argument 'SIZE'
71EOF
72du --threshold=SIZE a > out 2>&1 && fail=1
73compare exp out || fail=1
74
75cat <<EOF > exp
76du: invalid -t argument 'SIZE'
77EOF
78du -t SIZE a > out 2>&1 && fail=1
79compare exp out || fail=1
80
81# Exercise a bad argument: -0 is not valid.
82cat <<EOF > exp
83du: invalid --threshold argument '-0'
84EOF
85du --threshold=-0 a > out 2>&1 && fail=1
86compare exp out || fail=1
87
88du -t -0 a > out 2>&1 && fail=1
89compare exp out || fail=1
90
91du -t-0 a > out 2>&1 && fail=1
92compare exp out || fail=1
93
94# Exercise a bad argument: empty argument.
95cat <<EOF > exp
96du: invalid --threshold argument ''
97EOF
98du --threshold= a > out 2>&1 && fail=1
99compare exp out || fail=1
100
101# Exercise a bad argument: no argument.
102du --threshold > out.tmp 2>&1 && fail=1
103sed 's/argument.*/argument/; s/option.*requires/option requires/' \
104  < out.tmp > out || framework_failure_
105cat <<EOF > exp
106du: option requires an argument
107Try 'du --help' for more information.
108EOF
109compare exp out || fail=1
110rm -f out
111
112dutest ()
113{
114  args="$1"
115  exp="$2"
116
117  rm -f exp out
118
119  # Expected output.
120  if [ "$exp" = "" ] ; then
121    touch exp
122  else
123    printf "%s\n" $exp > exp
124  fi
125
126  rc=0
127  du -B1 $args a > out1 2>&1 || { cat out1 ; rc=1 ; }
128
129  # Remove the size column and sort the output.
130  cut -f2- out1 | sort > out || framework_failure_
131
132  compare exp out || { cat out1 ; rc=1 ; }
133  return $rc
134}
135
136# Check numbers around the total size of the main directory 'a'.
137# One byte greater than 'a'.
138s=$(expr $Bab0123 + 1)  # block size
139dutest "            -t $s"  ''                                  || fail=1
140dutest "      -a    -t $s"  ''                                  || fail=1
141dutest "         -S -t $s"  ''                                  || fail=1
142dutest "      -a -S -t $s"  ''                                  || fail=1
143dutest "            -t -$s" 'a a/b a/c'                         || fail=1
144dutest "      -a    -t -$s" 'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1
145dutest "         -S -t -$s" 'a a/b a/c'                         || fail=1
146dutest "      -a -S -t -$s" 'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1
147
148# Exactly the size of 'a'.
149s=$Bab0123  # block size
150dutest "            --th=$s"  'a'                                 || fail=1
151dutest "      -a    --th=$s"  'a'                                 || fail=1
152dutest "         -S --th=$s"  ''                                  || fail=1
153dutest "      -a -S --th=$s"  ''                                  || fail=1
154dutest "            --th=-$s" 'a a/b a/c'                         || fail=1
155dutest "      -a    --th=-$s" 'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1
156dutest "         -S --th=-$s" 'a a/b a/c'                         || fail=1
157dutest "      -a -S --th=-$s" 'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1
158
159# One byte smaller than 'a'.
160s=$(expr $Bab0123 - 1)  # block size
161dutest "            --th=$s"  'a'                                 || fail=1
162dutest "      -a    --th=$s"  'a'                                 || fail=1
163dutest "         -S --th=$s"  ''                                  || fail=1
164dutest "      -a -S --th=$s"  ''                                  || fail=1
165dutest "            --th=-$s" 'a/b a/c'                           || fail=1
166dutest "      -a    --th=-$s" 'a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c'   || fail=1
167dutest "         -S --th=-$s" 'a a/b a/c'                         || fail=1
168dutest "      -a -S --th=-$s" 'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c' || fail=1
169
170
171# Check numbers around the total size of the sub directory 'a/b'.
172# One byte greater than 'a/b'.
173s=$(expr $Bb0123 + 1)  # block size
174dutest "            --th=$s"  'a'                                  || fail=1
175dutest "      -a    --th=$s"  'a'                                  || fail=1
176dutest "         -S --th=$s"  ''                                   || fail=1
177dutest "      -a -S --th=$s"  ''                                   || fail=1
178dutest "            --th=-$s" 'a/b a/c'                            || fail=1
179dutest "      -a    --th=-$s" 'a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c'    || fail=1
180dutest "         -S --th=-$s" 'a a/b a/c'                          || fail=1
181dutest "      -a -S --th=-$s" 'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c'  || fail=1
182
183# Exactly the size of 'a/b'.
184s=$Bb0123  # block size
185dutest "            --th=$s"  'a a/b'                              || fail=1
186dutest "      -a    --th=$s"  'a a/b'                              || fail=1
187dutest "         -S --th=$s"  'a/b'                                || fail=1
188dutest "      -a -S --th=$s"  'a/b'                                || fail=1
189dutest "            --th=-$s" 'a/b a/c'                            || fail=1
190dutest "      -a    --th=-$s" 'a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c'    || fail=1
191dutest "         -S --th=-$s" 'a a/b a/c'                          || fail=1
192dutest "      -a -S --th=-$s" 'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c'  || fail=1
193
194# One byte smaller than 'a/b'.
195s=$(expr $Bb0123 - 1)  # block size
196dutest "            --th=$s"  'a a/b'                              || fail=1
197dutest "      -a    --th=$s"  'a a/b'                              || fail=1
198dutest "         -S --th=$s"  'a/b'                                || fail=1
199dutest "      -a -S --th=$s"  'a/b'                                || fail=1
200dutest "            --th=-$s" 'a/c'                                || fail=1
201dutest "      -a    --th=-$s" 'a/b/0 a/b/1 a/b/2 a/b/3 a/c'        || fail=1
202dutest "         -S --th=-$s" 'a a/c'                              || fail=1
203dutest "      -a -S --th=-$s" 'a a/b/0 a/b/1 a/b/2 a/b/3 a/c'      || fail=1
204
205
206# Check numbers around the total size of the files a/b/[0123]'.
207echo One byte greater than 'a/b/3'.
208s=$(expr $B3 + 1)  # block size
209dutest "            --th=$s"  'a a/b'                              || fail=1
210dutest "      -a    --th=$s"  'a a/b'                              || fail=1
211dutest "         -S --th=$s"  'a/b'                                || fail=1
212dutest "      -a -S --th=$s"  'a/b'                                || fail=1
213dutest "            --th=-$s" 'a/c'                                || fail=1
214dutest "      -a    --th=-$s" 'a/b/0 a/b/1 a/b/2 a/b/3 a/c'        || fail=1
215dutest "         -S --th=-$s" 'a a/c'                              || fail=1
216dutest "      -a -S --th=-$s" 'a a/b/0 a/b/1 a/b/2 a/b/3 a/c'      || fail=1
217
218# Exactly the size of 'a/b/3'.
219echo Exactly the size of 'a/b/3'.
220s=$B3  # block size
221dutest "            --th=$s"  'a a/b a/c'                          || fail=1
222dutest "      -a    --th=$s"  'a a/b a/b/1 a/b/2 a/b/3 a/c'        || fail=1
223dutest "         -S --th=$s"  'a a/b a/c'                          || fail=1
224dutest "      -a -S --th=$s"  'a a/b a/b/1 a/b/2 a/b/3 a/c'        || fail=1
225dutest "            --th=-$s" 'a/c'                                || fail=1
226dutest "      -a    --th=-$s" 'a/b/0 a/b/1 a/b/2 a/b/3 a/c'        || fail=1
227dutest "         -S --th=-$s" 'a a/c'                              || fail=1
228dutest "      -a -S --th=-$s" 'a a/b/0 a/b/1 a/b/2 a/b/3 a/c'      || fail=1
229
230# Exactly the size of 'a/b/2'.
231echo Exactly the size of 'a/b/2'.
232s=$B2  # block size
233dutest "            --th=$s"  'a a/b a/c'                          || fail=1
234dutest "      -a    --th=$s"  'a a/b a/b/1 a/b/2 a/b/3 a/c'        || fail=1
235dutest "         -S --th=$s"  'a a/b a/c'                          || fail=1
236dutest "      -a -S --th=$s"  'a a/b a/b/1 a/b/2 a/b/3 a/c'        || fail=1
237dutest "            --th=-$s" 'a/c'                                || fail=1
238dutest "      -a    --th=-$s" 'a/b/0 a/b/1 a/b/2 a/b/3 a/c'        || fail=1
239dutest "         -S --th=-$s" 'a a/c'                              || fail=1
240dutest "      -a -S --th=-$s" 'a a/b/0 a/b/1 a/b/2 a/b/3 a/c'      || fail=1
241
242# Exactly the size of 'a/b/1'.
243echo Exactly the size of 'a/b/1'.
244s=$B1  # block size
245dutest "            --th=$s"  'a a/b a/c'                          || fail=1
246dutest "      -a    --th=$s"  'a a/b a/b/1 a/b/2 a/b/3 a/c'        || fail=1
247dutest "         -S --th=$s"  'a a/b a/c'                          || fail=1
248dutest "      -a -S --th=$s"  'a a/b a/b/1 a/b/2 a/b/3 a/c'        || fail=1
249dutest "            --th=-$s" 'a/c'                                || fail=1
250dutest "      -a    --th=-$s" 'a/b/0 a/b/1 a/b/2 a/b/3 a/c'        || fail=1
251dutest "         -S --th=-$s" 'a a/c'                              || fail=1
252dutest "      -a -S --th=-$s" 'a a/b/0 a/b/1 a/b/2 a/b/3 a/c'      || fail=1
253
254# Exactly the size of 'a/b/0'.
255echo Exactly the size of 'a/b/0'.
256s=$B0  # block size
257dutest "            --th=$s"  'a a/b a/c'                          || fail=1
258dutest "      -a    --th=$s"  'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c'  || fail=1
259dutest "         -S --th=$s"  'a a/b a/c'                          || fail=1
260dutest "      -a -S --th=$s"  'a a/b a/b/0 a/b/1 a/b/2 a/b/3 a/c'  || fail=1
261# (maximum tests (-0) not possible).
262
263Exit $fail
264