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