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 -F flag to the 'update' command. 31 32WORKDIR=work 33 34usage() 35{ 36 echo "Usage: fbsdid.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# Store a FreeBSD ID string in a specified file. The first argument 67# is the file, the remaining arguments are the comment to use. 68store_id() 69{ 70 local file 71 72 file=$1 73 shift 74 75 echo -n '# $FreeBSD' >> $file 76 echo -n "$@" >> $file 77 echo '$' >> $file 78} 79 80# These tests deal with FreeBSD ID string conflicts. We run the test 81# twice, once without -F and once with -F. 82build_trees() 83{ 84 local i 85 86 rm -rf $OLD $NEW $TEST $CONFLICTS 87 mkdir -p $OLD $NEW $TEST 88 89 # remove: Remove a file where the only local difference is a 90 # change in the FreeBSD ID string. 91 store_id $OLD/remove 92 store_id $TEST/remove ": head/remove 12345 jhb " 93 94 # old: Modify a file where the only local difference between 95 # the old and test files is a change in the FreeBSD ID string. 96 store_id $OLD/old ": src/old,v 1.1 jhb Exp " 97 store_id $NEW/old ": head/old 12345 jhb " 98 store_id $TEST/old ": head/old 12000 jhb " 99 for i in $OLD $TEST; do 100 cat >> $i/old <<EOF 101 102an old file 103EOF 104 done 105 cat >> $NEW/old <<EOF 106 107a new file 108EOF 109 110 # already: Modify a file where the local file already matches 111 # the new file except for a change in the FreeBSD ID string. 112 store_id $OLD/already ": src/already,v 1.1 jhb Exp " 113 store_id $NEW/already ": head/already 12345 jhb " 114 store_id $TEST/already ": src/already,v 1.2 jhb Exp " 115 cat >> $OLD/already <<EOF 116 117another old file 118EOF 119 for i in $NEW $TEST; do 120 cat >> $i/already <<EOF 121 122another new file 123EOF 124 done 125 126 # add: Add a file that already exists where the only local 127 # difference is a change in the FreeBSD ID string. 128 store_id $NEW/add ": head/add 12345 jhb " 129 store_id $TEST/add "" 130 131 # conflict: Modify a file where the local file has a different 132 # FreeBSD ID string. This should still generate a conflict 133 # even in the -F case. 134 store_id $OLD/conflict ": head/conflict 12000 jhb " 135 store_id $NEW/conflict ": head/conflict 12345 jhb " 136 store_id $TEST/conflict "" 137 cat >> $OLD/conflict <<EOF 138 139this is the old file 140EOF 141 cat >> $NEW/conflict <<EOF 142 143this is the new file 144EOF 145 cat >> $TEST/conflict <<EOF 146 147this is the local file 148EOF 149 150 # local: A file with local modifications has a different 151 # FreeBSD ID string and the only differences between the old 152 # and new versions are a change in the FreeBSD ID string. 153 # This will just update the FreeBSD ID string in the -F case. 154 for i in $OLD $NEW $TEST; do 155 cat >> $i/local <<EOF 156# Some leading text 157# 158EOF 159 done 160 161 store_id $OLD/local ": head/local 12000 jhb " 162 store_id $NEW/local ": head/local 12345 jhb " 163 store_id $TEST/local ": src/local,v 1.5 jhb Exp " 164 165 for i in $OLD $NEW $TEST; do 166 cat >> $i/local <<EOF 167 168this is a file 169EOF 170 done 171 172 cat >> $TEST/local <<EOF 173 174these are some local mods to the file 175EOF 176 177 # local-already: A file with local modifications has the same 178 # FreeBSD ID string as the new version of the file and the 179 # only differences between the old and new versions are a 180 # change in the FreeBSD ID string. Nothing should happen in 181 # the -F case. 182 store_id $OLD/local-already ": head/local 12000 jhb " 183 for i in $NEW $TEST; do 184 store_id $i/local-already ": head/local 12345 jhb " 185 done 186 187 for i in $OLD $NEW $TEST; do 188 cat >> $i/local-already <<EOF 189 190this is a file 191EOF 192 done 193 194 cat >> $TEST/local-already <<EOF 195 196these are some local mods to the file 197EOF 198 199 # local-remove: A file removed locally changed it's FreeBSD ID 200 # but nothing else 201 store_id $OLD/local-remove ": head/local-remove 12000 jhb " 202 store_id $NEW/local-remove ": head/local-remove 12345 jhb " 203 for i in $OLD $NEW; do 204 cat >> $i/local-remove <<EOF 205 206this is a file 207EOF 208 done 209} 210 211# $1 - relative path to file that should be missing from TEST 212missing() 213{ 214 if [ -e $TEST/$1 -o -L $TEST/$1 ]; then 215 echo "File $1 should be missing" 216 fi 217} 218 219# $1 - relative path to file that should be present in TEST 220present() 221{ 222 if ! [ -e $TEST/$1 -o -L $TEST/$1 ]; then 223 echo "File $1 should be present" 224 fi 225} 226 227# $1 - relative path to regular file that should be present in TEST 228# $2 - optional string that should match file contents 229# $3 - optional MD5 of the flie contents, overrides $2 if present 230file() 231{ 232 local contents sum 233 234 if ! [ -f $TEST/$1 ]; then 235 echo "File $1 should be a regular file" 236 elif [ $# -eq 2 ]; then 237 contents=`cat $TEST/$1` 238 if [ "$contents" != "$2" ]; then 239 echo "File $1 has wrong contents" 240 fi 241 elif [ $# -eq 3 ]; then 242 sum=`md5 -q $TEST/$1` 243 if [ "$sum" != "$3" ]; then 244 echo "File $1 has wrong contents" 245 fi 246 fi 247} 248 249# $1 - relative path to a regular file that should have a conflict 250# $2 - optional MD5 of the conflict file contents 251conflict() 252{ 253 local sum 254 255 if ! [ -f $CONFLICTS/$1 ]; then 256 echo "File $1 missing conflict" 257 elif [ $# -gt 1 ]; then 258 sum=`md5 -q $CONFLICTS/$1` 259 if [ "$sum" != "$2" ]; then 260 echo "Conflict $1 has wrong contents" 261 fi 262 fi 263} 264 265# $1 - relative path to a regular file that should not have a conflict 266noconflict() 267{ 268 if [ -f $CONFLICTS/$1 ]; then 269 echo "File $1 should not have a conflict" 270 fi 271} 272 273if [ `id -u` -ne 0 ]; then 274 echo "must be root" 275fi 276 277if [ -r /etc/etcupdate.conf ]; then 278 echo "WARNING: /etc/etcupdate.conf settings may break some tests." 279fi 280 281# First run the test without -F. 282 283build_trees 284 285$COMMAND -r -d $WORKDIR -D $TEST > $WORKDIR/test.out 286 287cat > $WORKDIR/correct.out <<EOF 288 C /already 289 C /conflict 290 C /local 291 M /local-already 292 C /old 293 C /add 294Warnings: 295 Modified regular file remains: /remove 296 Removed file changed: /local-remove 297EOF 298 299echo "Differences for regular:" 300diff -u -L "correct" $WORKDIR/correct.out -L "test" $WORKDIR/test.out 301 302file /remove "" 1bb4776213af107077be78fead8a351c 303file /old "" 2f799a7addc4132563ef9b44adc66157 304conflict /old 8441be64a1540f2ff584015279682425 305file /already "" aa53bd506f65d01d766e7ba028585e1d 306conflict /already f44105abb1fa3293e95c5d77e428d418 307file /add "" 1dc8c617e541d1fd1b4c70212f71d8ae 308conflict /add f99081e0da9a07f3cfebb430c0414941 309file /conflict "" dc27978df125b0daeb7d9b93265f03fd 310conflict /conflict 868452f666fea1c60ffb918ad9ad9607 311file /local "" aa33e614b5e749449f230e2a2b0072eb 312conflict /local 3df93e64043c8e348fc625b93ea220f4 313file /local-already "" 0298b958a603049f45ae6a109c4f7fea 314missing /local-remove 315 316# Now test with -F. 317 318build_trees 319 320$COMMAND -rF -d $WORKDIR -D $TEST > $WORKDIR/testF.out 321 322cat > $WORKDIR/correctF.out <<EOF 323 D /remove 324 U /already 325 C /conflict 326 M /local 327 U /old 328 U /add 329EOF 330 331echo "Differences for -F:" 332diff -u -L "correct" $WORKDIR/correctF.out -L "test" $WORKDIR/testF.out 333 334missing /remove 335file /old "" 6a9f34f109d94406a4de3bc5d72de259 336noconflict /old 337file /already "" 21f4eca3aacc702c49878c8da7afd3d0 338noconflict /already 339file /add "" 0208bd647111fedf6318511712ab9e97 340noconflict /add 341file /conflict "" dc27978df125b0daeb7d9b93265f03fd 342conflict /conflict 868452f666fea1c60ffb918ad9ad9607 343file /local "" 3ed5a35e380c8a93fb5f599d4c052713 344file /local-already "" 0298b958a603049f45ae6a109c4f7fea 345missing /local-remove 346 347# Now test with -F and -A forcing all installs. (-A should have 348# precedence over -F) 349 350build_trees 351 352$COMMAND -A '/*' -rF -d $WORKDIR -D $TEST > $WORKDIR/testAF.out 353 354cat > $WORKDIR/correctAF.out <<EOF 355 D /remove 356 U /already 357 U /conflict 358 U /local 359 U /local-already 360 A /local-remove 361 U /old 362 U /add 363EOF 364 365echo "Differences for -A '/*' -F:" 366diff -u -L "correct" $WORKDIR/correctAF.out -L "test" $WORKDIR/testAF.out 367 368missing /remove 369file /old "" 6a9f34f109d94406a4de3bc5d72de259 370noconflict /old 371file /already "" 21f4eca3aacc702c49878c8da7afd3d0 372noconflict /already 373file /add "" 0208bd647111fedf6318511712ab9e97 374noconflict /add 375file /conflict "" 75ee141c4136beaf14e39de92efa84e4 376noconflict /conflict 377file /local "" 6a8fc5c2755b7a49015089f5e1dbe092 378file /local-already "" 49045f8b51542dd634655301cd296f66 379file /local-remove "" 5c38322efed4014797d7127f5c652d9d 380