]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - usr.sbin/etcupdate/tests/tests_test.sh
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / usr.sbin / etcupdate / tests / tests_test.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2010 Hudson River Trading LLC
4 # Written by: John H. Baldwin <jhb@FreeBSD.org>
5 # All rights reserved.
6 #
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
9 # are met:
10 # 1. Redistributions of source code must retain the above copyright
11 #    notice, this list of conditions and the following disclaimer.
12 # 2. Redistributions in binary form must reproduce the above copyright
13 #    notice, this list of conditions and the following disclaimer in the
14 #    documentation and/or other materials provided with the distribution.
15 #
16 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 # ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 # SUCH DAMAGE.
27 #
28 # $FreeBSD$
29
30 # Various regression tests to run for the 'update' command.
31
32 FAILED=no
33 WORKDIR=work
34
35 usage()
36 {
37         echo "Usage: tests.sh [-s script] [-w workdir]"
38         exit 1
39 }
40
41 # Allow the user to specify an alternate work directory or script.
42 COMMAND=etcupdate
43 while getopts "s:w:" option; do
44         case $option in
45                 s)
46                         COMMAND="sh $OPTARG"
47                         ;;
48                 w)
49                         WORKDIR=$OPTARG
50                         ;;
51                 *)
52                         echo
53                         usage
54                         ;;
55         esac
56 done
57 shift $((OPTIND - 1))
58 if [ $# -ne 0 ]; then
59         usage
60 fi
61
62 CONFLICTS=$WORKDIR/conflicts
63 OLD=$WORKDIR/old
64 NEW=$WORKDIR/current
65 TEST=$WORKDIR/test
66
67 # The various states of the comparison of a file between two trees.
68 states="equal first second difftype difflinks difffiles"
69
70 build_trees()
71 {
72         local i j k
73
74         rm -rf $OLD $NEW $TEST $CONFLICTS
75         mkdir -p $OLD/etc $NEW/etc $TEST/etc
76
77         # For an given file, there are three different pair-wise
78         # relations between the three threes (old, new, and test): old
79         # vs new, old vs test, and new vs test.  Each of these
80         # relations takes on one of six different states from the
81         # 'compare()' function in etcupdate: equal, onlyfirst,
82         # onlysecond, difftype, difflinks, difffiles.  In addition,
83         # there are special considerations for considering cases such
84         # as a file merge that results in conflicts versus one that
85         # does not, special treatment of directories, etc.  The tests
86         # below attempt to enumerate the three dimensional test matrix
87         # by having the path name use the three different tree states
88         # for the parent directories.
89         #
90         # Note that if the old and new files are identical (so first
91         # compare is "equal"), then the second and third comparisons
92         # will be the same.
93         #
94         # Note also that etcupdate only cares about files that are
95         # present in at least one of the old or new trees.  Thus, none
96         # of the '*/second/second' cases are relevant.
97
98         for i in $states; do
99                 for j in $states; do
100                         for k in $states; do
101                                 mkdir -p $OLD/$i/$j/$k $NEW/$i/$j/$k \
102                                     $TEST/$i/$j/$k
103                         done
104                 done
105         done
106
107         # /equal/equal/equal: Everything is equal.  Nothing should happen.
108         for i in $OLD $NEW $TEST; do
109                 mkfifo $i/equal/equal/equal/fifo
110                 echo "foo" > $i/equal/equal/equal/file
111                 mkdir $i/equal/equal/equal/dir
112                 ln -s "bar" $i/equal/equal/equal/link
113         done
114
115         # /equal/first/first: The file is missing from the test
116         # directory.  Nothing should happen.
117         for i in $OLD $NEW; do
118                 mkfifo $i/equal/first/first/fifo
119                 echo "foo" > $i/equal/first/first/file
120                 mkdir $i/equal/first/first/dir
121                 ln -s "bar" $i/equal/first/first/link
122         done
123
124         # /equal/difftype/difftype: The local file is a different
125         # type.  Nothing should happen.
126         for i in $OLD $NEW; do
127                 mkfifo $i/equal/difftype/difftype/fifo
128                 mkdir $i/equal/difftype/difftype/fromdir
129         done
130         echo "bar" > $TEST/equal/difftype/difftype/fifo
131         ln -s "test" $TEST/equal/difftype/difftype/fromdir
132
133         # /equal/difflinks/difflinks: The local file is a modified
134         # link. Nothing should happen.
135         for i in $OLD $NEW; do
136                 ln -s "foo" $i/equal/difflinks/difflinks/link
137         done
138         ln -s "bar" $TEST/equal/difflinks/difflinks/link
139
140         # /equal/difffiles/difffiles: The local file is a modified
141         # file.  Nothing should happen.
142         for i in $OLD $NEW; do
143                 echo "foo" > $i/equal/difffiles/difffiles/file
144         done
145         echo "bar" > $TEST/equal/difffiles/difffiles/file
146
147         # /first/equal/second: Remove unmodified files.  The files
148         # should all be removed.
149         for i in $OLD $TEST; do
150                 mkfifo $i/first/equal/second/fifo
151                 echo "foo" > $i/first/equal/second/file
152                 mkdir $i/first/equal/second/emptydir
153                 ln -s "bar" $i/first/equal/second/link
154                 mkdir $i/first/equal/second/fulldir
155                 echo "foo" > $i/first/equal/second/fulldir/file
156         done
157
158         # /first/equal/*: Cannot occur.  If the file is missing from
159         # new, then new vs test will always be 'second'.
160
161         # /first/first/equal: Removed files are already removed.
162         # Nothing should happen.
163         mkfifo $OLD/first/first/equal/fifo
164         echo "foo" > $OLD/first/first/equal/file
165         mkdir $OLD/first/first/equal/dir
166         ln -s "bar" $OLD/first/first/equal/link
167
168         # /first/first/*: Cannot occur.  The files are missing from
169         # both new and test.
170
171         # /first/second/*: Cannot happen, if the file is in old for
172         # old vs new, it cannot be missing for old vs test.
173
174         # /first/difftype/second: File with different local type
175         # removed.  Should generate a warning.
176         mkfifo $OLD/first/difftype/second/fifo
177         mkdir $TEST/first/difftype/second/fifo
178
179         # /first/difftype/*: Cannot happen since the file is missing
180         # from new but present in test.
181
182         # /first/difflinks/second: Modified link removed.  Should
183         # generate a warning.
184         ln -s "old link" $OLD/first/difflinks/second/link
185         ln -s "test link" $TEST/first/difflinks/second/link
186
187         # /first/difflinks/*: Cannot happen since the file is missing
188         # from new but present in test.
189
190         # /first/difffiles/second: Modified file removed.  Should
191         # generate a warning.
192         echo "foo" > $OLD/first/difffiles/second/file
193         echo "bar" > $TEST/first/difffiles/second/file
194
195         # /first/difffiles/*: Cannot happen since the file is missing
196         # from new but present in test.
197
198         # /second/equal/first: Added a new file that isn't present in
199         # test.  The empty directory should be ignored.
200         echo "bar" > $NEW/second/equal/first/file
201         mkfifo $NEW/second/equal/first/fifo
202         ln -s "new" $NEW/second/equal/first/link
203         mkdir $NEW/second/equal/first/emptydir
204         mkdir $NEW/second/equal/first/fulldir
205         echo "foo" > $NEW/second/equal/first/fulldir/file
206
207         # /second/equal/*: Cannot happen since the file is missing
208         # from test but present in new.
209
210         # /second/first/*: Cannot happen since the file is missing
211         # from old.
212
213         # /second/second/equal: Newly added file is already present in
214         # the test directory and identical to the new file.  Nothing
215         # should happen.
216         for i in $NEW $TEST; do
217                 mkfifo $i/second/second/equal/fifo
218                 echo "foo" > $i/second/second/equal/file
219                 mkdir $i/second/second/equal/dir
220                 ln -s "bar" $i/second/second/equal/link
221         done
222
223         # /second/second/first: Cannot happen.  The file is in dest in
224         # the second test, so it can't be missing from the third test.
225
226         # /second/second/second: Cannot happen.  The file is in new in
227         # the first test, so it can't be missing from the third test.
228
229         # /second/second/difftype: Newly added file conflicts with
230         # existing file in test tree of a different type.  Should
231         # generate a warning.
232         mkdir $NEW/second/second/difftype/dir
233         mkfifo $TEST/second/second/difftype/dir
234
235         # /second/second/difflinks: Newly added link conflicts with
236         # existing link in test tree.  Should generate a warning.
237         ln -s "new link" $NEW/second/second/difflinks/link
238         ln -s "test link" $TEST/second/second/difflinks/link
239
240         # /second/second/difffiles: Newly added file conflicts with
241         # existing file in test tree.  Should generate a warning.
242         echo "new" > $NEW/second/second/difffiles/file
243         echo "test" > $TEST/second/second/difffiles/file
244
245         # /second/difftype/*: Cannot happen since the file is missing
246         # from old.
247
248         # /second/difflinks/*: Cannot happen since the file is missing
249         # from old.
250
251         # /second/difffiles/*: Cannot happen since the file is missing
252         # from old.
253
254         # /difftype/equal/difftype: Unmodified file has changed type.
255         # File should be updated to the new file.  In the 'todir' case
256         # the directory won't actually be created because it is empty.
257         for i in $OLD $TEST; do
258                 echo "foo" > $i/difftype/equal/difftype/file
259                 mkdir $i/difftype/equal/difftype/fromdir
260                 ln -s "old" $i/difftype/equal/difftype/todir
261         done
262         ln -s "test" $NEW/difftype/equal/difftype/file
263         mkfifo $NEW/difftype/equal/difftype/fromdir
264         mkdir $NEW/difftype/equal/difftype/todir
265
266         # /difftype/equal/*: Cannot happen.  Since the old file is a
267         # difftype from the new file and the test file is identical to
268         # the old file, the test file must be a difftype from the new
269         # file.
270
271         # /difftype/first/first: A removed file has changed type.
272         # This should generate a warning.
273         mkfifo $OLD/difftype/first/first/fifo
274         mkdir $NEW/difftype/first/first/fifo
275
276         # /difftype/first/*: Cannot happen.  Since the new file exists
277         # and the dest file is missing, the last test must be 'first'.
278
279         # /difftype/second/*: Cannot happen.  The old file exists in
280         # the first test, so it cannot be missing in the second test.
281
282         # /difftype/difftype/equal: A file has changed type, but the
283         # file in the test directory already matches the new file.  Do
284         # nothing.
285         echo "foo" > $OLD/difftype/difftype/equal/fifo
286         mkfifo $OLD/difftype/difftype/equal/file
287         for i in $NEW $TEST; do
288                 mkfifo $i/difftype/difftype/equal/fifo
289                 echo "bar" > $i/difftype/difftype/equal/file
290         done
291
292         # /difftype/difftype/first: Cannot happen.  The dest file
293         # exists in the second test.
294
295         # /difftype/difftype/second: Cannot happen.  The new file
296         # exists in the first test.
297
298         # /difftype/difftype/difftype: All three files (old, new, and
299         # test) are different types from each other.  This should
300         # generate a warning.
301         mkfifo $OLD/difftype/difftype/difftype/one
302         mkdir $NEW/difftype/difftype/difftype/one
303         echo "foo" > $TEST/difftype/difftype/difftype/one
304         mkdir $OLD/difftype/difftype/difftype/two
305         echo "baz" > $NEW/difftype/difftype/difftype/two
306         ln -s "bar" $TEST/difftype/difftype/difftype/two
307
308         # /difftype/difftype/difflinks: A file has changed from a
309         # non-link to a link in both the new and test trees, but the
310         # target of the new and test links differ.  This should
311         # generate a new link conflict.
312         mkfifo $OLD/difftype/difftype/difflinks/link
313         ln -s "new" $NEW/difftype/difftype/difflinks/link
314         ln -s "test" $TEST/difftype/difftype/difflinks/link
315
316         # /difftype/difftype/difffile: A file has changed from a
317         # non-regular file to a regular file in both the new and test
318         # trees, but the contents in the new and test files differ.
319         # This should generate a new file conflict.
320         ln -s "old" $OLD/difftype/difftype/difffiles/file
321         echo "foo" > $NEW/difftype/difftype/difffiles/file
322         echo "bar" > $TEST/difftype/difftype/difffiles/file
323
324         # /difflinks/equal/difflinks: An unmodified symlink has
325         # changed.  The link should be updated.
326         for i in $OLD $TEST; do
327                 ln -s "old" $i/difflinks/equal/difflinks/link
328         done
329         ln -s "new" $NEW/difflinks/equal/difflinks/link
330
331         # /difflinks/equal/*: Cannot happen.  Since old is identical
332         # to test, the third test must be 'difflinks'.
333
334         # /difflinks/first/first: A modified link is missing in the
335         # test tree.  This should generate a warning.
336         ln -s "old" $OLD/difflinks/first/first/link
337         ln -s "new" $NEW/difflinks/first/first/link
338
339         # /difflinks/first/*: Cannot happen.  Since the test file is
340         # missing in the second test, it must be missing in the third
341         # test.
342
343         # /difflinks/second/*: Cannot happen.  The old link is present
344         # in the first test, so it cannot be missing in the second
345         # test.
346
347         # /difflinks/difftype/difftype: An updated link has been
348         # changed to a different file type in the test tree.  This
349         # should generate a warning.
350         ln -s "old" $OLD/difflinks/difftype/difftype/link
351         ln -s "new" $NEW/difflinks/difftype/difftype/link
352         echo "test" > $TEST/difflinks/difftype/difftype/link
353
354         # /difflinks/difftype/*: Cannot happen.  The old and new files
355         # are both links and the test file is not a link, so the third
356         # test must be 'difftype'.
357
358         # /difflinks/difflinks/equal: An updated link has already been
359         # updated to the new target in the test tree.  Nothing should
360         # happen.
361         ln -s "old" $OLD/difflinks/difflinks/equal/link
362         for i in $NEW $TEST; do
363                 ln -s "new" $i/difflinks/difflinks/equal/link
364         done
365
366         # /difflinks/difflinks/difflinks: An updated link has been
367         # modified in the test tree and doesn't match either the old
368         # or new links.  This should generate a warning.
369         ln -s "old" $OLD/difflinks/difflinks/difflinks/link
370         ln -s "new" $NEW/difflinks/difflinks/difflinks/link
371         ln -s "test" $TEST/difflinks/difflinks/difflinks/link
372
373         # /difflinks/difflinks/*: Cannot happen.  All three files are
374         # links from the first two tests, so the third test can only
375         # be 'equal' or 'difflink'.
376
377         # /difflinks/difffiles/*: Cannot happen.  The old file is a
378         # link in the first test, so it cannot be a regular file in
379         # the second.
380
381         # /difffiles/equal/difffiles: An unmodified file has been
382         # changed in new tree.  The file should be updated to the new
383         # version.
384         for i in $OLD $TEST; do
385                 echo "foo" > $i/difffiles/equal/difffiles/file
386         done
387         echo "bar" > $NEW/difffiles/equal/difffiles/file
388
389         # /difffiles/equal/*: Cannot happen.  Since the old file is
390         # identical to the test file, the third test must be
391         # 'difffiles'.
392
393         # /difffiles/first/first: A removed file has been changed in
394         # the new tree.  This should generate a warning.
395         echo "foo" > $OLD/difffiles/first/first/file
396         echo "bar" > $NEW/difffiles/first/first/file
397
398         # /difffiles/first/*: Cannot happen.  The new file is a
399         # regular file from the first test and the test file is
400         # missing in the second test, so the third test must be
401         # 'first'.
402
403         # /difffiles/second/*: Cannot happen.  The old file is present
404         # in the first test, so it must be present in the second test.
405
406         # /difffiles/difftype/difftype: An updated regular file has
407         # been changed to a different file type in the test tree.
408         # This should generate a warning.
409         echo "old" > $OLD/difffiles/difftype/difftype/file
410         echo "new" > $NEW/difffiles/difftype/difftype/file
411         mkfifo $TEST/difffiles/difftype/difftype/file
412
413         # /difffiles/difftype/*: Cannot happen.  The new file is known
414         # to be a regular file from the first test, and the test file
415         # is known to exist as a different file type from the second
416         # test.  The third test must be 'difftype'.
417
418         # /difffiles/difflink/*: Cannot happen.  The old file is known
419         # to be a regular file from the first test, so it cannot be a
420         # link in the second test.
421
422         # /difffiles/difffiles/equal: An updated regular file has
423         # already been updated to match the new file in the test tree.
424         # Nothing should happen.
425         echo "foo" > $OLD/difffiles/difffiles/equal/file
426         for i in $NEW $TEST; do
427                 echo "bar" > $i/difffiles/difffiles/equal/file
428         done
429
430         # /difffiles/difffiles/difffiles: A modified regular file was
431         # updated in the new tree.  The changes should be merged into
432         # to the new file if possible.  If the merge fails, a conflict
433         # should be generated.
434         cat > $OLD/difffiles/difffiles/difffiles/simple <<EOF
435 this is an old line
436
437 EOF
438         cat > $NEW/difffiles/difffiles/difffiles/simple <<EOF
439 this is a new line
440
441 EOF
442         cat > $TEST/difffiles/difffiles/difffiles/simple <<EOF
443 this is an old line
444
445 this is a local line
446 EOF
447         cat > $OLD/difffiles/difffiles/difffiles/conflict <<EOF
448 this is an old file
449 EOF
450         cat > $NEW/difffiles/difffiles/difffiles/conflict <<EOF
451 this is a new file
452 EOF
453         cat > $TEST/difffiles/difffiles/difffiles/conflict <<EOF
454 this is a test file
455 EOF
456
457         # /difffiles/difffiles/*: Cannot happen.  From the first three
458         # tests, all three files are regular files.  The test file can
459         # either be identical to the new file ('equal') or not
460         # ('difffiles').
461
462         ## Tests for adding directories
463         mkdir -p $OLD/adddir $NEW/adddir $TEST/adddir
464
465         # /adddir/conflict: Add a new file in a directory that already
466         # exists as a file.  This should generate two warnings.
467         mkdir $NEW/adddir/conflict
468         touch $NEW/adddir/conflict/newfile
469         touch $TEST/adddir/conflict
470
471         # /adddir/partial: Add a new file in a directory.  The
472         # directory already exists in the test tree and contains a
473         # different local file.  The new file from the new tree should
474         # be added.
475         for i in $NEW $TEST; do
476                 mkdir $i/adddir/partial
477         done
478         echo "foo" > $NEW/adddir/partial/file
479         mkfifo $TEST/adddir/partial/fifo
480
481         ## Tests for removing directories
482         mkdir -p $OLD/rmdir $NEW/rmdir $TEST/rmdir
483
484         # /rmdir/extra: Do not remove a directory with an extra local file.
485         # This should generate a warning.
486         for i in $OLD $TEST; do
487                 mkdir $i/rmdir/extra
488         done
489         echo "foo" > $TEST/rmdir/extra/localfile.txt
490
491         # /rmdir/conflict: Do not remove a directory with a conflicted
492         # remove file.  This should generate a warning.
493         for i in $OLD $TEST; do
494                 mkdir $i/rmdir/conflict
495         done
496         mkfifo $OLD/rmdir/conflict/difftype
497         mkdir $TEST/rmdir/conflict/difftype
498
499         # /rmdir/partial: Remove a complete hierarchy when part of the
500         # tree has already been removed locally.
501         for i in $OLD $TEST; do
502                 mkdir -p $i/rmdir/partial/subdir
503                 mkfifo $i/rmdir/partial/subdir/fifo
504         done
505         echo "foo" > $OLD/rmdir/partial/subdir/file
506
507         ## Tests for converting files to directories and vice versa
508         for i in $OLD $NEW $TEST; do
509                 for j in already old fromdir todir; do
510                         mkdir -p $i/dirchange/$j
511                 done
512         done
513
514         # /dirchange/already/fromdir: Convert a directory tree to a
515         # file without conflicts where the test tree already has the
516         # new file.  Nothing should happen.
517         mkdir $OLD/dirchange/already/fromdir
518         echo "blah" > $OLD/dirchange/already/fromdir/somefile
519         for i in $NEW $TEST; do
520                 echo "bar" > $i/dirchange/already/fromdir
521         done
522
523         # /dirchange/already/todir: Convert an unmodified file to a
524         # directory tree where the test tree already has the new
525         # tree.  Nothing should happen.
526         echo "baz" > $OLD/dirchange/already/todir
527         for i in $NEW $TEST; do
528                 mkdir $i/dirchange/already/todir
529                 echo "blah" > $i/dirchange/already/todir/somefile
530         done
531
532         # /dirchange/old/fromdir: Convert a directory tree to a file.
533         # The old files are unmodified and should be changed to the new tree.
534         for i in $OLD $TEST; do
535                 mkdir $i/dirchange/old/fromdir
536                 echo "blah" > $i/dirchange/old/fromdir/somefile
537         done
538         echo "bar" > $NEW/dirchange/old/fromdir
539
540         # /dirchange/old/todir: Convert a file to a directory tree.
541         # The old file is unmodified and should be changed to the new
542         # tree.
543         for i in $OLD $TEST; do
544                 echo "foo" > $i/dirchange/old/todir
545         done
546         mkdir $NEW/dirchange/old/todir
547         echo "bar" > $NEW/dirchange/old/todir/file
548
549         # /dirchange/fromdir/extradir: Convert a directory tree to a
550         # file.  The test tree includes an extra file in the directory
551         # that is not present in the old tree.  This should generate a
552         # warning.
553         for i in $OLD $TEST; do
554                 mkdir $i/dirchange/fromdir/extradir
555                 echo "foo" > $i/dirchange/fromdir/extradir/file
556         done
557         mkfifo $TEST/dirchange/fromdir/extradir/fifo
558         ln -s "bar" $NEW/dirchange/fromdir/extradir
559
560         # /dirchange/fromdir/conflict: Convert a directory tree to a
561         # file.  The test tree includes a local change that generates
562         # a warning and prevents the removal of the directory.
563         for i in $OLD $TEST; do
564                 mkdir $i/dirchange/fromdir/conflict
565         done
566         echo "foo" > $OLD/dirchange/fromdir/conflict/somefile
567         echo "bar" > $TEST/dirchange/fromdir/conflict/somefile
568         mkfifo $NEW/dirchange/fromdir/conflict
569
570         # /dirchange/todir/difffile: Convert a file to a directory
571         # tree.  The test tree has a locally modified version of the
572         # file so that the conversion fails with a warning.
573         echo "foo" > $OLD/dirchange/todir/difffile
574         mkdir $NEW/dirchange/todir/difffile
575         echo "baz" > $NEW/dirchange/todir/difffile/file
576         echo "bar" > $TEST/dirchange/todir/difffile
577
578         # /dirchange/todir/difftype: Similar to the previous test, but
579         # the conflict is due to a change in the file type.
580         echo "foo" > $OLD/dirchange/todir/difftype
581         mkdir $NEW/dirchange/todir/difftype
582         echo "baz" > $NEW/dirchange/todir/difftype/file
583         mkfifo $TEST/dirchange/todir/difftype
584
585         ## Tests for post-install actions
586
587         # - Adding /etc/master.passwd should cause pwd_mkdb to be run
588         echo "foo:*:16000:100::0:0:& user:/home/foo:/bin/tcsh" > \
589             $NEW/etc/master.passwd
590
591         # - Verify that updating an unmodified /etc/login.conf builds
592         # /etc/login.conf.db.
593         cat > $OLD/etc/login.conf <<EOF
594 default:\\
595         :passwd_format=md5:
596 EOF
597         cat > $NEW/etc/login.conf <<EOF
598 default:\\
599         :passwd_format=md5:\\
600         :copyright=/etc/COPYRIGHT
601 EOF
602         cp $OLD/etc/login.conf $TEST/etc/login.conf
603
604         # - Verify that a merge without conflicts to /etc/mail/aliases
605         # will trigger a newaliases run request.
606         mkdir -p $OLD/etc/mail $NEW/etc/mail $TEST/etc/mail
607         cat > $OLD/etc/mail/aliases <<EOF
608 # root: me@my.domain
609
610 # Basic system aliases -- these MUST be present
611 MAILER-DAEMON: postmaster
612 postmaster: root
613 EOF
614         cat > $NEW/etc/mail/aliases <<EOF
615 # root: me@my.domain
616
617 # Basic system aliases -- these MUST be present
618 MAILER-DAEMON: postmaster
619 postmaster: root
620
621 # General redirections for pseudo accounts
622 _dhcp:  root
623 _pflogd: root
624 EOF
625         cat > $TEST/etc/mail/aliases <<EOF
626 root: someone@example.com
627
628 # Basic system aliases -- these MUST be present
629 MAILER-DAEMON: postmaster
630 postmaster: root
631 EOF
632
633         # - Verify that updating an unmodified /etc/services builds
634         # /var/db/services.db.
635         cat > $OLD/etc/services <<EOF
636 rtmp              1/ddp    #Routing Table Maintenance Protocol
637 tcpmux            1/tcp    #TCP Port Service Multiplexer
638 tcpmux            1/udp    #TCP Port Service Multiplexer
639 EOF
640         cat > $NEW/etc/services <<EOF
641 rtmp              1/ddp    #Routing Table Maintenance Protocol
642 tcpmux            1/tcp    #TCP Port Service Multiplexer
643 tcpmux            1/udp    #TCP Port Service Multiplexer
644 nbp               2/ddp    #Name Binding Protocol
645 compressnet       2/tcp    #Management Utility
646 compressnet       2/udp    #Management Utility
647 EOF
648         cp $OLD/etc/services $TEST/etc/services
649         mkdir -p $TEST/var/db
650 }
651
652 # $1 - relative path to file that should be missing from TEST
653 missing()
654 {
655         if [ -e $TEST/$1 -o -L $TEST/$1 ]; then
656                 echo "File $1 should be missing"
657                 FAILED=yes
658         fi
659 }
660
661 # $1 - relative path to file that should be present in TEST
662 present()
663 {
664         if ! [ -e $TEST/$1 -o -L $TEST/$1 ]; then
665                 echo "File $1 should be present"
666                 FAILED=yes
667         fi
668 }
669
670 # $1 - relative path to file that should be a fifo in TEST
671 fifo()
672 {
673         if ! [ -p $TEST/$1 ]; then
674                 echo "File $1 should be a FIFO"
675                 FAILED=yes
676         fi
677 }
678
679 # $1 - relative path to file that should be a directory in TEST
680 dir()
681 {
682         if ! [ -d $TEST/$1 ]; then
683                 echo "File $1 should be a directory"
684                 FAILED=yes
685         fi
686 }
687
688 # $1 - relative path to file that should be a symlink in TEST
689 # $2 - optional value of the link
690 link()
691 {
692         local val
693
694         if ! [ -L $TEST/$1 ]; then
695                 echo "File $1 should be a link"
696                 FAILED=yes
697         elif [ $# -gt 1 ]; then
698                 val=`readlink $TEST/$1`
699                 if [ "$val" != "$2" ]; then
700                         echo "Link $1 should link to \"$2\""
701                         FAILED=yes
702                 fi
703         fi
704 }
705
706 # $1 - relative path to regular file that should be present in TEST
707 # $2 - optional string that should match file contents
708 # $3 - optional MD5 of the flie contents, overrides $2 if present
709 file()
710 {
711         local contents sum
712
713         if ! [ -f $TEST/$1 ]; then
714                 echo "File $1 should be a regular file"
715                 FAILED=yes
716         elif [ $# -eq 2 ]; then
717                 contents=`cat $TEST/$1`
718                 if [ "$contents" != "$2" ]; then
719                         echo "File $1 has wrong contents"
720                         FAILED=yes
721                 fi
722         elif [ $# -eq 3 ]; then
723                 sum=`md5 -q $TEST/$1`
724                 if [ "$sum" != "$3" ]; then
725                         echo "File $1 has wrong contents"
726                         FAILED=yes
727                 fi
728         fi
729 }
730
731 # $1 - relative path to a regular file that should have a conflict
732 # $2 - optional MD5 of the conflict file contents
733 conflict()
734 {
735         local sum
736
737         if ! [ -f $CONFLICTS/$1 ]; then
738                 echo "File $1 missing conflict"
739                 FAILED=yes
740         elif [ $# -gt 1 ]; then
741                 sum=`md5 -q $CONFLICTS/$1`
742                 if [ "$sum" != "$2" ]; then
743                         echo "Conflict $1 has wrong contents"
744                         FAILED=yes
745                 fi
746         fi
747 }
748
749 check_trees()
750 {
751
752         echo "Checking tree for correct results:"
753
754         ## /equal/equal/equal:
755         fifo /equal/equal/equal/fifo
756         file /equal/equal/equal/file "foo"
757         dir /equal/equal/equal/dir
758         link /equal/equal/equal/link "bar"
759
760         ## /equal/first/first:
761         missing /equal/first/first/fifo
762         missing /equal/first/first/file
763         missing /equal/first/first/dir
764         missing /equal/first/first/link
765
766         ## /equal/difftype/difftype:
767         file /equal/difftype/difftype/fifo "bar"
768         link /equal/difftype/difftype/fromdir "test"
769
770         ## /equal/difflinks/difflinks:
771         link /equal/difflinks/difflinks/link "bar"
772
773         ## /equal/difffiles/difffiles:
774         file /equal/difffiles/difffiles/file "bar"
775
776         ## /first/equal/second:
777         missing /first/equal/second/fifo
778         missing /first/equal/second/file
779         missing /first/equal/second/emptydir
780         missing /first/equal/second/link
781         missing /first/equal/second/fulldir
782
783         ## /first/first/equal:
784         missing /first/first/equal/fifo
785         missing /first/first/equal/file
786         missing /first/first/equal/dir
787         missing /first/first/equal/link
788
789         ## /first/difftype/second:
790         present /first/difftype/second/fifo
791
792         ## /first/difflinks/second:
793         link /first/difflinks/second/link "test link"
794
795         ## /first/difffiles/second:
796         file /first/difffiles/second/file "bar"
797
798         ## /second/equal/first:
799         file /second/equal/first/file "bar"
800         fifo /second/equal/first/fifo
801         link /second/equal/first/link "new"
802         missing /second/equal/first/emptydir
803         file /second/equal/first/fulldir/file "foo"
804
805         ## /second/second/equal:
806         fifo /second/second/equal/fifo
807         file /second/second/equal/file "foo"
808         dir /second/second/equal/dir
809         link /second/second/equal/link "bar"
810
811         ## /second/second/difftype:
812         fifo /second/second/difftype/dir
813
814         ## /second/second/difflinks:
815         link /second/second/difflinks/link "test link"
816
817         ## /second/second/difffiles:
818         file /second/second/difffiles/file "test"
819         conflict /second/second/difffiles/file 4f2ee8620a251fd53f06bb6112eb6ffa
820
821         ## /difftype/equal/difftype:
822         link /difftype/equal/difftype/file "test"
823         fifo /difftype/equal/difftype/fromdir
824         missing /difftype/equal/difftype/todir
825
826         ## /difftype/first/first:
827         missing /difftype/first/first/fifo
828
829         ## /difftype/difftype/equal:
830         fifo /difftype/difftype/equal/fifo
831         file /difftype/difftype/equal/file "bar"
832
833         ## /difftype/difftype/difftype:
834         file /difftype/difftype/difftype/one "foo"
835         link /difftype/difftype/difftype/two "bar"
836
837         ## /difftype/difftype/difflinks:
838         link /difftype/difftype/difflinks/link "test"
839
840         ## /difftype/difftype/difffile:
841         conflict /difftype/difftype/difffiles/file \
842             117f2bcd1f6491f6044e79e5a57a9229
843
844         ## /difflinks/equal/difflinks:
845         link /difflinks/equal/difflinks/link "new"
846
847         ## /difflinks/first/first:
848         missing /difflinks/first/first/link
849
850         ## /difflinks/difftype/difftype:
851         file /difflinks/difftype/difftype/link "test"
852
853         ## /difflinks/difflinks/equal:
854         link /difflinks/difflinks/equal/link "new"
855
856         ## /difflinks/difflinks/difflinks:
857         link /difflinks/difflinks/difflinks/link "test"
858
859         ## /difffiles/equal/difffiles:
860         file /difffiles/equal/difffiles/file "bar"
861
862         ## /difffiles/first/first:
863         missing /difffiles/first/first/file
864
865         ## /difffiles/difftype/difftype:
866         fifo /difffiles/difftype/difftype/file
867
868         ## /difffiles/difffiles/equal:
869         file /difffiles/difffiles/equal/file "bar"
870
871         ## /difffiles/difffiles/difffiles:
872         file /difffiles/difffiles/difffiles/simple "" \
873             cabc7e5e80b0946d79edd555e9648486
874         file /difffiles/difffiles/difffiles/conflict "this is a test file"
875         conflict /difffiles/difffiles/difffiles/conflict \
876             8261cfdd89280c4a6c26e4ac86541fe9
877
878         ## /adddir/conflict:
879         file /adddir/conflict
880
881         ## /adddir/partial:
882         file /adddir/partial/file "foo"
883         fifo /adddir/partial/fifo
884
885         ## /rmdir/extra:
886         dir /rmdir/extra
887         file /rmdir/extra/localfile.txt "foo"
888
889         ## /rmdir/conflict:
890         dir /rmdir/conflict/difftype
891         present /rmdir/conflict
892
893         ## /rmdir/partial:
894         missing /rmdir/partial
895
896         ## /dirchange/already/fromdir:
897         file /dirchange/already/fromdir "bar"
898
899         ## /dirchange/already/todir:
900         file /dirchange/already/todir/somefile "blah"
901
902         ## /dirchange/old/fromdir:
903         file /dirchange/old/fromdir "bar"
904
905         ## /dirchange/old/todir
906         file /dirchange/old/todir/file "bar"
907
908         ## /dirchange/fromdir/extradir:
909         missing /dirchange/fromdir/extradir/file
910         fifo /dirchange/fromdir/extradir/fifo
911
912         ## /dirchange/fromdir/conflict:
913         file /dirchange/fromdir/conflict/somefile "bar"
914
915         ## /dirchange/todir/difffile:
916         file /dirchange/todir/difffile "bar"
917
918         ## /dirchange/todir/difftype:
919         fifo /dirchange/todir/difftype
920
921         ## Tests for post-install actions
922         file /etc/master.passwd
923         file /etc/passwd
924         file /etc/pwd.db
925         file /etc/spwd.db
926         file /etc/login.conf "" 7774a0f9a3a372c7c109c32fd31c4b6b
927         file /etc/login.conf.db
928         file /etc/mail/aliases "" 7d598f89ec040ab56af54011bdb83337
929         file /etc/services "" 37fb6a8d1273f3b78329d431f21d9c7d
930         file /var/db/services.db
931 }
932
933 if [ `id -u` -ne 0 ]; then
934         echo "must be root"
935         exit 0
936 fi
937
938 if [ -r /etc/etcupdate.conf ]; then
939         echo "WARNING: /etc/etcupdate.conf settings may break some tests."
940 fi
941
942 build_trees
943
944 $COMMAND -nr -d $WORKDIR -D $TEST > $WORKDIR/testn.out
945
946 cat > $WORKDIR/correct.out <<EOF
947   D /dirchange/fromdir/extradir/file
948   D /dirchange/old/fromdir/somefile
949   D /first/equal/second/fifo
950   D /first/equal/second/file
951   D /first/equal/second/fulldir/file
952   D /first/equal/second/link
953   D /rmdir/partial/subdir/fifo
954   D /rmdir/partial/subdir
955   D /rmdir/partial
956   D /first/equal/second/fulldir
957   D /first/equal/second/emptydir
958   C /difffiles/difffiles/difffiles/conflict
959   M /difffiles/difffiles/difffiles/simple
960   U /difffiles/equal/difffiles/file
961   U /difflinks/equal/difflinks/link
962   C /difftype/difftype/difffiles/file
963   U /difftype/equal/difftype/file
964   U /difftype/equal/difftype/fromdir
965   D /difftype/equal/difftype/todir
966   U /dirchange/old/fromdir
967   U /dirchange/old/todir
968   U /etc/login.conf
969   M /etc/mail/aliases
970   U /etc/services
971   A /adddir/partial/file
972   A /dirchange/old/todir/file
973   A /etc/master.passwd
974   A /second/equal/first/fifo
975   A /second/equal/first/file
976   A /second/equal/first/fulldir/file
977   A /second/equal/first/link
978   C /second/second/difffiles/file
979 Warnings:
980   Modified regular file remains: /dirchange/fromdir/conflict/somefile
981   Modified regular file remains: /first/difffiles/second/file
982   Modified symbolic link remains: /first/difflinks/second/link
983   Modified directory remains: /first/difftype/second/fifo
984   Modified directory remains: /rmdir/conflict/difftype
985   Non-empty directory remains: /rmdir/extra
986   Non-empty directory remains: /rmdir/conflict
987   Modified mismatch: /difffiles/difftype/difftype/file (regular file vs fifo file)
988   Removed file changed: /difffiles/first/first/file
989   Modified link changed: /difflinks/difflinks/difflinks/link ("old" became "new")
990   Modified mismatch: /difflinks/difftype/difftype/link (symbolic link vs regular file)
991   Removed link changed: /difflinks/first/first/link ("old" became "new")
992   New link conflict: /difftype/difftype/difflinks/link ("new" vs "test")
993   Modified regular file changed: /difftype/difftype/difftype/one (fifo file became directory)
994   Modified symbolic link changed: /difftype/difftype/difftype/two (directory became regular file)
995   Remove mismatch: /difftype/first/first/fifo (fifo file became directory)
996   Modified directory changed: /dirchange/fromdir/conflict (directory became fifo file)
997   Modified directory changed: /dirchange/fromdir/extradir (directory became symbolic link)
998   Modified regular file changed: /dirchange/todir/difffile (regular file became directory)
999   Modified fifo file changed: /dirchange/todir/difftype (regular file became directory)
1000   New file mismatch: /adddir/conflict (directory vs regular file)
1001   Directory mismatch: $TEST/adddir/conflict (regular file)
1002   Directory mismatch: $TEST/dirchange/todir/difffile (regular file)
1003   Directory mismatch: $TEST/dirchange/todir/difftype (fifo file)
1004   New link conflict: /second/second/difflinks/link ("new link" vs "test link")
1005   New file mismatch: /second/second/difftype/dir (directory vs fifo file)
1006   Needs update: /etc/mail/aliases.db (requires manual update via newaliases(1))
1007 EOF
1008
1009 echo "Differences for -n:"
1010 diff -u -L "correct" $WORKDIR/correct.out -L "test" $WORKDIR/testn.out \
1011     || failed=YES
1012
1013 $COMMAND -r -d $WORKDIR -D $TEST > $WORKDIR/test.out
1014
1015 echo "Differences for real:"
1016 diff -u -L "correct" $WORKDIR/correct.out -L "test" $WORKDIR/test.out \
1017     || failed=YES
1018
1019 check_trees
1020
1021 [ "${FAILED}" = no ]