test
1#!/bin/sh
2
3set -eu
4
5PRG="acst"
6
7cleanup() {
8 _RES=$?
9 [ $_RES -ne 0 ] && echo "\033[5;31m*** FAILED WITH CODE $_RES ***\033[0m"
10
11 cd ..
12 rm -rf "$TMPFILE"
13}
14
15fattr() {
16 if [ "$1" = "set" ] && command -v getfattr > /dev/null 2>&1; then
17 setfattr -n "$2" -v "$3" "$4"
18 elif [ "$1" = "get" ] && command -v getfattr > /dev/null 2>&1; then
19 getfattr -n "$2" "$3" -e hex
20 else
21 exit 1
22 fi
23}
24
25get_cs() {
26 fattr "get" "user.acst.cs" "$1"
27}
28
29set_cs() {
30 fattr "set" "user.acst.cs" "0x$1" "$2"
31}
32
33set_ts() {
34 fattr "set" "user.acst.ts" "$1" "$2"
35}
36
37TESTCNT=0
38header() {
39 printf 'test %02d: %s\n' "$((TESTCNT+=1))" "$1"
40}
41
42cd "$(dirname "$0")"
43TMPFILE="$(mktemp -d XXXXXXXXXX)" && {
44 cd "$TMPFILE"
45 trap cleanup EXIT
46
47 #########################################################################
48 header 'new empty file'
49 cat > expected <<- EOF
50 <new> object
51 stored: 0000000000000000000000000000000000000000000000000000000000000000 0000000000.000000000
52 actual: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 1592776800.000000000
53 EOF
54 TZ=CET touch -t 202006220000 object
55 ../"${PRG}" object > output
56 diff -u expected output
57
58 echo "<ok> object" > expected
59 ../"${PRG}" object > output
60 diff -u expected output
61
62 #########################################################################
63 header 'outdated file'
64 cat > expected <<- EOF
65 <outdated> object
66 stored: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 1592776800.000000000
67 actual: 7f8b1dfc466b6249f06cbe55c9174df2578e7754da793fded244ef5cba2a38f1 1655848800.000000000
68 EOF
69 echo changed > object
70 TZ=CET touch -t 202206220000 object
71 ../"${PRG}" object > output
72 diff -u expected output
73
74 #########################################################################
75 header 'touched file'
76 cat > expected <<- EOF
77 <hash ok> object
78 stored: 7c34ee8c3de68a60833ad48675da46483dc2c7b1cb42333fd6a528a93a39f652 1592776800.000000000
79 actual: 7c34ee8c3de68a60833ad48675da46483dc2c7b1cb42333fd6a528a93a39f652 1655848800.000000000
80 EOF
81 rm -f object
82 echo touched > object
83 TZ=CET touch -t 202006220000 object
84 ../"${PRG}" object > /dev/null
85 TZ=CET touch -t 202206220000 object
86 ../"${PRG}" object > output
87 diff -u expected output
88
89 #########################################################################
90 header 'modified empty file'
91 echo > object
92 ../"${PRG}" object > /dev/null
93 ../"${PRG}" object > /dev/null
94
95 #########################################################################
96 header 'new 100 zero file'
97 cat > expected <<- EOF
98 <new> object
99 stored: 0000000000000000000000000000000000000000000000000000000000000000 0000000000.000000000
100 actual: 134e6543ddc35b40abb4f2f8aaaa2d0513a27e267beaf9081e29d84eba94017d 1655848800.000000000
101 EOF
102 rm -f object
103 printf '%0.s0' $(seq 1 100) > object
104 TZ=CET touch -t 202206220000 object
105 ../"${PRG}" object > output
106 diff -u expected output
107
108 echo "<ok> object" > expected
109 ../"${PRG}" object > output
110 diff -u expected output
111
112 #########################################################################
113 header 'attribute with appended NULL byte'
114 rm -f object
115 TZ=CET touch -t 202206220000 object
116 set_ts "1655848800.000000000" "object"
117 set_cs "6533623063343432393866633163313439616662663463383939366662393234323761653431653436343962393334636134393539393162373835326238353500" "object"
118 echo "<ok> object" > expected
119 ../"${PRG}" object > output
120 diff -u expected output
121
122 #########################################################################
123 header 'attribute without appended NULL byte'
124 rm -f object
125 TZ=CET touch -t 202206220000 object
126 set_ts "1655848800.000000000" "object"
127 set_cs "65336230633434323938666331633134396166626634633839393666623932343237616534316534363439623933346361343935393931623738353262383535" "object"
128 echo "<ok> object" > expected
129 ../"${PRG}" object > output
130 diff -u expected output
131
132 #########################################################################
133 header 'backdated file should persistently be flagged'
134 cat > expected <<- EOF
135 <backdated> object
136 stored: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 1655848800.000000000
137 actual: d201858e7b45213e25f68d54255aa9337e77ab082fe023af25d49d4199db004f 1561154400.000000000
138 EOF
139 echo "backdated" > object
140 TZ=CET touch -t 201906220000 object
141 for i in $(seq 2); do
142 set +e
143 ../"${PRG}" object 2>/dev/null > output
144 if [ $? -eq 0 ]; then
145 echo "should have returned an error code, but returned 0"
146 exit 1
147 fi
148 set -e
149 diff -u expected output
150 done
151
152 #########################################################################
153 header 'corrupt file should persistently be flagged'
154 cat > expected <<- EOF
155 <corrupt> object
156 stored: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 1655848800.000000000
157 actual: 06d0083ba740ff26c91cb17f10d15d398eea1affd3112599b429f30452b59db4 1655848800.000000000
158 EOF
159 echo "corrupt" > object
160 TZ=CET touch -t 202206220000 object
161 for i in $(seq 2); do
162 set +e
163 ../"${PRG}" object 2>/dev/null > output
164 if [ $? -eq 0 ]; then
165 echo "should have returned an error code, but returned 0"
166 exit 1
167 fi
168 set -e
169 diff -u expected output
170 done
171
172 #########################################################################
173 header 'file with malformed attributes should persistently be flagged'
174 echo "<malformed> object" > expected
175 echo "malformed" > object
176 set_cs "37323331375834333239653339623737323834366566373335386565666565386438353639626161383962316630366461363632373638336536323136353364" object
177 for i in $(seq 2); do
178 set +e
179 ../"${PRG}" object 2>/dev/null > output
180 if [ $? -eq 0 ]; then
181 echo "should have returned an error code, but returned 0"
182 exit 1
183 fi
184 set -e
185 diff -u expected output
186 done
187
188 #########################################################################
189 header 'uppercase checksum should be changed to lowercase'
190 cat > expected <<- EOF
191 <outdated> object
192 stored: 72317e4329e39b772846ef7358eefee8d8569baa89b1f06da6627683e621653d 1624320000.000000000
193 actual: a6657f91652abf6d193fc9944c3e999d9aebfe5b33ebf3f733be673576f7af03 1655848800.000000000
194 EOF
195 echo "uppercase" > object
196 TZ=CET touch -t 202206220000 object
197 set_ts "1624320000.000000000" "object"
198 set_cs "37323331374534333239453339423737323834364546373335384545464545384438353639424141383942314630364441363632373638334536323136353344" object
199 ../"${PRG}" object > output
200 diff -u expected output
201
202 #########################################################################
203 header 'removal of extended attributes'
204 cat > expected <<- EOF
205 <new> object
206 stored: 0000000000000000000000000000000000000000000000000000000000000000 0000000000.000000000
207 actual: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 1655848800.000000000
208 EOF
209 rm -f object
210 TZ=CET touch -t 202206220000 object
211 ../"${PRG}" object > output
212 diff -u expected output
213 echo "<xattr removed> object" > expected
214 ../"${PRG}" -x object > output
215 diff -u expected output
216 echo "Error: could not remove extended attributes from file \"object\": No data available" > expected
217 set +e
218 ../"${PRG}" -x object > output 2>&1
219 if [ $? -eq 0 ]; then
220 echo "should have returned an error code, but returned 0"
221 exit 1
222 fi
223 set -e
224 diff -u expected output
225
226 #########################################################################
227 header 'nonexisting file'
228 set +e
229 echo "Error: could not open file \"nonexisting\"" > expected
230 ../"${PRG}" nonexisting > output 2>&1
231 if [ $? -ne 2 ]; then
232 echo "should have returned an error code 2, but returned 0"
233 exit 1
234 fi
235 set -e
236 diff -u expected output
237
238 #########################################################################
239 header 'symlink'
240 ln -s object symlink
241 set +e
242 echo "Error: not a regular file \"symlink\"" > expected
243 ../"${PRG}" symlink > output 2>&1
244 if [ $? -ne 3 ]; then
245 echo "should have returned an error code 3, but returned 0"
246 exit 1
247 fi
248 set -e
249 diff -u expected output
250 rm -f symlink
251
252 #########################################################################
253 header 'multiple files, using command line'
254 sort > expected <<- EOF
255 <new> object/level-1/file-1
256 stored: 0000000000000000000000000000000000000000000000000000000000000000 0000000000.000000000
257 actual: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 1655848860.000000000
258 <new> object/level-1/level-2/file-2
259 stored: 0000000000000000000000000000000000000000000000000000000000000000 0000000000.000000000
260 actual: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 1655848920.000000000
261 <new> object/level-1/level-2/level-3/file-3
262 stored: 0000000000000000000000000000000000000000000000000000000000000000 0000000000.000000000
263 actual: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 1655848980.000000000
264 EOF
265 rm -f object
266 mkdir -p object/level-1/level-2/level-3
267 TZ=CET touch -t 202206220001 object/level-1/file-1
268 TZ=CET touch -t 202206220002 object/level-1/level-2/file-2
269 TZ=CET touch -t 202206220003 object/level-1/level-2/level-3/file-3
270 find object -xdev -type f -print0 | xargs -r0 ../"${PRG}" | sort > output
271 diff -u expected output
272 rm -rf object
273
274 #########################################################################
275 header 'multiple files, using STDIN'
276 sort > expected <<- EOF
277 <new> object/level-1/file-1
278 stored: 0000000000000000000000000000000000000000000000000000000000000000 0000000000.000000000
279 actual: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 1655848860.000000000
280 <new> object/level-1/level-2/file-2
281 stored: 0000000000000000000000000000000000000000000000000000000000000000 0000000000.000000000
282 actual: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 1655848920.000000000
283 <new> object/level-1/level-2/level-3/file-3
284 stored: 0000000000000000000000000000000000000000000000000000000000000000 0000000000.000000000
285 actual: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 1655848980.000000000
286 EOF
287 rm -f object
288 mkdir -p object/level-1/level-2/level-3
289 TZ=CET touch -t 202206220001 object/level-1/file-1
290 TZ=CET touch -t 202206220002 object/level-1/level-2/file-2
291 TZ=CET touch -t 202206220003 object/level-1/level-2/level-3/file-3
292 find object -xdev -type f | ../"${PRG}" - | sort > output
293 diff -u expected output
294 rm -rf object
295
296 #########################################################################
297 header 'handle (-) as a file, when argument parsing is interrupted'
298 set +e
299 echo "Error: could not open file \"-\"" > expected
300 ../"${PRG}" -- - > output 2>&1
301 if [ $? -ne 2 ]; then
302 echo "should have returned an error code 2, but returned 0"
303 exit 1
304 fi
305 set -e
306 diff -u expected output
307
308 #########################################################################
309 header 'dry run'
310 cat > expected <<- EOF
311 <new> object
312 stored: 0000000000000000000000000000000000000000000000000000000000000000 0000000000.000000000
313 actual: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 1655848800.000000000
314 EOF
315 TZ=CET touch -t 202206220000 object
316 ../"${PRG}" -n object > output
317 diff -u expected output
318 ../"${PRG}" object > output
319 diff -u expected output
320
321 #########################################################################
322 header 'dry run removal'
323 echo "<xattr removed> object" > expected
324 ../"${PRG}" -xn object > output
325 diff -u expected output
326 ../"${PRG}" -x object > output
327 diff -u expected output
328
329 #########################################################################
330 header 'recursive duplicate check'
331 sort > expected <<- EOF
332 Found 3 files with duplicates.
333 <dup> 1121cfccd5913f0a63fec40a6ffd44ea64f9dc135c66634ba001d10bcf4302a2
334 object/level-1/level-2/level-3/file-3
335 object/level-1/level-2/file-3
336 object/level-1/file-3
337 <dup> 4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865
338 object/level-1/level-2/file-1
339 object/level-1/file-1
340 <dup> 53c234e5e8472b6ac51c1ae1cab3fe06fad053beb8ebfd8977b010655bfdd3c3
341 object/level-1/level-2/file-2
342 object/level-1/file-2
343 EOF
344 rm -f object
345 mkdir -p object/level-1/level-2/level-3
346 echo "1" | tee object/level-1/file-1 > object/level-1/level-2/file-1
347 echo "2" | tee object/level-1/file-2 > object/level-1/level-2/file-2
348 echo "3" | tee object/level-1/file-3 object/level-1/level-2/file-3 >\
349 object/level-1/level-2/level-3/file-3
350 echo "4" > object/level-1/file-4
351 find object -xdev -type f | ../"${PRG}" - > /dev/null 2>&1
352 find object -xdev -type f | ../"${PRG}" -d - 2>&1 | sort > output
353 diff -u expected output
354
355 #########################################################################
356 echo "\033[5;32m*** ALL TESTS WERE PASSED SUCCESSFULLY ***\033[0m"
357}