1#!/bin/sh
2#
3# Copyright (c) 2010 Advanced Computing Technologies 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 test the -I flag to the 'update' command.
31
32WORKDIR=work
33
34usage()
35{
36	echo "Usage: ignore.sh [-s script] [-w workdir]"
37	exit 1
38}
39
40# Allow the user to specify an alternate work directory or script.
41COMMAND=etcupdate
42while 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
55done
56shift $((OPTIND - 1))
57if [ $# -ne 0 ]; then
58	usage
59fi
60
61CONFLICTS=$WORKDIR/conflicts
62OLD=$WORKDIR/old
63NEW=$WORKDIR/current
64TEST=$WORKDIR/test
65
66# These tests deal with ignoring certain patterns of files.  We run the
67# test multiple times ignoring different patterns.
68build_trees()
69{
70	local i
71
72	rm -rf $OLD $NEW $TEST $CONFLICTS
73	mkdir -p $OLD $NEW $TEST
74
75	for i in $OLD $NEW $TEST; do
76		mkdir -p $i/tree
77	done
78
79	# tree: Test three different cases (add, modify, remove) that all
80	# match the tree/* glob.
81	echo "foo" > $NEW/tree/add
82	for i in $OLD $TEST; do
83		echo "old" > $i/tree/modify
84	done
85	echo "new" > $NEW/tree/modify
86	for i in $OLD $TEST; do
87		echo "old" > $i/tree/remove
88	done
89
90	# rmdir: Remove a whole tree.
91	for i in $OLD $TEST; do
92		mkdir $i/rmdir
93		echo "foo" > $i/rmdir/file
94	done
95}
96
97# $1 - relative path to file that should be missing from TEST
98missing()
99{
100	if [ -e $TEST/$1 -o -L $TEST/$1 ]; then
101		echo "File $1 should be missing"
102	fi
103}
104
105# $1 - relative path to file that should be present in TEST
106present()
107{
108	if ! [ -e $TEST/$1 -o -L $TEST/$1 ]; then
109		echo "File $1 should be present"
110	fi
111}
112
113# $1 - relative path to file that should be a directory in TEST
114dir()
115{
116	if ! [ -d $TEST/$1 ]; then
117		echo "File $1 should be a directory"
118	fi
119}
120
121# $1 - relative path to regular file that should be present in TEST
122# $2 - optional string that should match file contents
123# $3 - optional MD5 of the flie contents, overrides $2 if present
124file()
125{
126	local contents sum
127
128	if ! [ -f $TEST/$1 ]; then
129		echo "File $1 should be a regular file"
130	elif [ $# -eq 2 ]; then
131		contents=`cat $TEST/$1`
132		if [ "$contents" != "$2" ]; then
133			echo "File $1 has wrong contents"
134		fi
135	elif [ $# -eq 3 ]; then
136		sum=`md5 -q $TEST/$1`
137		if [ "$sum" != "$3" ]; then
138			echo "File $1 has wrong contents"
139		fi
140	fi
141}
142
143# $1 - relative path to a regular file that should have a conflict
144# $2 - optional MD5 of the conflict file contents
145conflict()
146{
147	local sum
148
149	if ! [ -f $CONFLICTS/$1 ]; then
150		echo "File $1 missing conflict"
151	elif [ $# -gt 1 ]; then
152		sum=`md5 -q $CONFLICTS/$1`
153		if [ "$sum" != "$2" ]; then
154			echo "Conflict $1 has wrong contents"
155		fi
156	fi
157}
158
159# $1 - relative path to a regular file that should not have a conflict
160noconflict()
161{
162	if [ -f $CONFLICTS/$1 ]; then
163		echo "File $1 should not have a conflict"
164	fi
165}
166
167if [ `id -u` -ne 0 ]; then
168	echo "must be root"
169fi
170
171if [ -r /etc/etcupdate.conf ]; then
172	echo "WARNING: /etc/etcupdate.conf settings may break some tests."
173fi
174
175# First run the test ignoring no patterns.
176
177build_trees
178
179$COMMAND -r -d $WORKDIR -D $TEST > $WORKDIR/test.out
180
181cat > $WORKDIR/correct.out <<EOF
182  D /rmdir/file
183  D /tree/remove
184  D /rmdir
185  U /tree/modify
186  A /tree/add
187EOF
188
189echo "Differences for regular:"
190diff -u -L "correct" $WORKDIR/correct.out -L "test" $WORKDIR/test.out
191
192missing /tree/remove
193file /tree/modify "new"
194file /tree/add "foo"
195missing /rmdir/file
196missing /rmdir
197
198# Now test with -I '/tree/*'.  This should preserve the /tree files.
199
200build_trees
201
202$COMMAND -r -I '/tree/*' -d $WORKDIR -D $TEST > $WORKDIR/test1.out
203
204cat > $WORKDIR/correct1.out <<EOF
205  D /rmdir/file
206  D /rmdir
207EOF
208
209echo "Differences for -I '/tree/*':"
210diff -u -L "correct" $WORKDIR/correct1.out -L "test" $WORKDIR/test1.out
211
212file /tree/remove "old"
213file /tree/modify "old"
214missing /tree/add
215missing /rmdir/file
216missing /rmdir
217
218# Now test with two patterns.  This should preserve everything.
219
220build_trees
221
222$COMMAND -r -I '/tree/*' -I '/rmdir*' -d $WORKDIR -D $TEST > \
223    $WORKDIR/test2.out
224
225cat > $WORKDIR/correct2.out <<EOF
226EOF
227
228echo "Differences for -I '/tree/*' -I '/rmdir*':"
229
230diff -u -L "correct" $WORKDIR/correct2.out -L "test" $WORKDIR/test2.out
231
232file /tree/remove "old"
233file /tree/modify "old"
234missing /tree/add
235file /rmdir/file "foo"
236
237# Now test with a pattern that should cause a warning on /rmdir by
238# only ignoring the files under that directory.  Note that this also
239# tests putting two patterns into a single -I argument.
240
241build_trees
242
243$COMMAND -r -I '/tree/* /rmdir/*' -d $WORKDIR -D $TEST > \
244    $WORKDIR/test3.out
245
246cat > $WORKDIR/correct3.out <<EOF
247Warnings:
248  Non-empty directory remains: /rmdir
249EOF
250
251echo "Differences for -I '/tree/* /rmdir/*':"
252
253diff -u -L "correct" $WORKDIR/correct3.out -L "test" $WORKDIR/test3.out
254
255file /tree/remove "old"
256file /tree/modify "old"
257missing /tree/add
258file /rmdir/file "foo"
259dir /rmdir
260