summaryrefslogtreecommitdiff
path: root/find/testsuite/config/unix.exp
blob: 6c94fd031a9b09c065a58ea08cb2a3610eeb9079 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
# -*- TCL -*-
# Test-specific TCL procedures required by DejaGNU.
# Copyright (C) 2000-2023 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.

# Modified by Kevin Dalley <kevind@rahul.net> from the xargs files.
# Modified by David MacKenzie <djm@gnu.ai.mit.edu> from the gcc files
# written by Rob Savoye <rob@cygnus.com>.


global FTSFIND

verbose "base_dir is $base_dir" 2
global env;
set env(GNU_FINDUTILS_FD_LEAK_CHECK) "1"

# look for FTSFIND
if { ![info exists FTSFIND] } {
    verbose "Searching for find"
    set dir "$base_dir/.."

    set objfile "ftsfind.o"
    if ![file exists "$dir/$objfile"] then {
	error "dir is $dir, but I cannot see $objfile in that directory"
    }
    set FTSFIND [findfile $dir/find    $dir/find    [transform find   ]]
}

verbose "ftsfind is at $FTSFIND" 2

if [file exists $FTSFIND] then {
    verbose "FTSFIND=$FTSFIND exists." 2
} else {
    error "FTSFIND=$FTSFIND, but that program does not exist (base_dir is $base_dir)"
}


global FINDFLAGS
if ![info exists FINDFLAGS] then {
    set FINDFLAGS ""
}

# Called by runtest.
# Extract and print the version number of find.
proc find_version {} {
    global FTSFIND
    global FINDFLAGS

    if {[which $FTSFIND] != 0} then {
	set tmp [ eval exec $FTSFIND $FINDFLAGS --version </dev/null | sed 1q ]
	clone_output $tmp
    } else {
	warning "$FTSFIND, program does not exist"
    }
}

# Run find
# Called by individual test scripts.
proc do_find_start { suffix findprogram flags passfail options infile output } {
    global verbose

    set scriptname [uplevel {info script}]
    set testbase [file rootname $scriptname]


    if { [string match "f*" $passfail] } {
	set fail_good 1
    } else {
	if { [string match "p*" $passfail] } {
	    set fail_good 0
	} else {
	    if { [string match "xf*" $passfail] } {
		setup_xfail "*-*-*"
		set fail_good 1
	    } else {
		if { [string match "xp*" $passfail] } {
		    setup_xfail "*-*-*"
		    set fail_good 0
		} else {
		    # badly formed
		    untested "Badly defined test"
		    error "The first argument to find_start was $passfail but it should begin with p (pass) or f (fail) or xf (should fail but we know it passes) or xp (should pass but we know it fails)"
		}
	    }
	}
    }

    set test [file tail $testbase]
    set testname "$test.$suffix"

    # set compareprog "cmp"
    set compareprog "diff -u"

    set tmpout ""
    if { $output != "" } {
	error "The output option is not supported yet"
    }

    set outfile "$testbase.xo"
    if {$infile != ""} then {
	set infile "[file dirname [file dirname $testbase]]/inputs/$infile"
    } else {
	set infile /dev/null
    }

    set cmd "$findprogram $flags $options < $infile > find.out.uns"
    send_log "$cmd\n"
    if $verbose>1 then {
	send_user "Spawning \"$cmd\"\n"
    }

    if $fail_good then {
	send_log "Hoping for this command to return nonzero\n"
    } else {
	send_log "Hoping for this command to return 0\n"
    }
    set failed [ catch "exec $cmd" result ]
    send_log "return value is $failed, result is '$result'\n"
    if $failed {
	# The command failed.
	if $fail_good then {
	    send_log "As expected, $cmd returned nonzero\n"
	} else {
	    fail "$testname, $result"
	}
    } else {
	# The command returned 0.
	if $fail_good then {
	    fail "$testname, $result"
	} else {
	    send_log "As expected, $cmd returned 0\n"
	}
    }

    exec sort < find.out.uns > find.out
    file delete find.out.uns

    if [file exists $outfile] then {
	# We use the 'sort' above to sort the output of find to ensure
	# that the directory entries appear in a predictable order.
	# Because in the general case the person compiling and running
	# "make check" will have a different collating order to the
	# maintainer, we can't guarantee that our "correct" answer
	# is already sorted in the correct order.  To avoid trying
	# to figure out how to select a POSIX environment on a
	# random system, we just sort the data again here, using
	# the local user's environment.
	exec sort < $outfile > cmp.out
	set cmp_cmd "$compareprog find.out cmp.out"

	send_log "$cmp_cmd\n"
	catch "exec $cmp_cmd" cmpout
	if {$cmpout != ""} then {
	    fail "$testname, standard output differs from the expected result:\n$cmpout"
	    return
	}
    } else {
	if {[file size find.out] != 0} then {
	    fail "$testname, output should be empty"
	    return
	}
    }
    pass "$testname"
}

proc optimisation_levels_to_test {} {
    global OPTIMISATION_LEVELS
    if [info exists OPTIMISATION_LEVELS] {
	send_log "Running find at optimisation levels $OPTIMISATION_LEVELS\n"
	return $OPTIMISATION_LEVELS
    } else {
	send_log "Running find at default optimisation levels\n"
	return {0 1 2 3}
    }
}

proc find_start { passfail options {infile ""} {output ""} {setup ""}} {
    global FTSFIND
    global FINDFLAGS
    global SKIP_NEW

    if {$infile != ""} then {
	set msg "Did not expect infile parameter to be set"
	untested $msg
	error $msg
    }

    if {[which $FTSFIND] == 0} then {
	error "$FTSFIND, program does not exist"
	exit 1
    }

    # Now run the test with each binary, once with each optimisation level.
    foreach optlevel [optimisation_levels_to_test] {
	set flags "$FINDFLAGS -O$optlevel"
	if { ![info exists SKIP_NEW] || !$SKIP_NEW } {
	    eval $setup
	    do_find_start new-O$optlevel  $FTSFIND $flags $passfail $options $infile $output
	}
    }
}

# Called by runtest.
# Clean up (remove temporary files) before runtest exits.
proc find_exit {} {
    catch "exec rm -f find.out cmp.out"
}

proc path_setting_is_unsafe {} {
    global env;
    set itemlist [ split $env(PATH) : ]
    foreach item $itemlist {
	if { [ string equal $item "" ] } {
	    return 1;
	}
	if { [ string equal $item "." ] } {
	    return 1;
	}
	if { ! [ string match "/*" $item ] } {
	    # not an absolute path element.
	    return 1
	}
    }
    return 0;
}

proc touch args {
    foreach filename $args {
	set f [open "$filename" "a"]
	close $f
    }
}

proc mkdir { dirname } {
    # Not all versions of Tcl offer 'file mkdir'.
    set failed [ catch "file mkdir $dirname" result ]
    if $failed {
	# Fall back on the external command.
	send_log "file mkdir does not work, falling back on exec mkdir\n"
	exec mkdir "$dirname"
    }
}


proc safe_path [ ] {
    if { [ path_setting_is_unsafe ] } {
	warning { Cannot perform test as your PATH environment variable includes a reference to the current directory or a directory name which is not absolute }
	untested { skipping this test because your PATH variable is wrongly set }
	return 0
    } else {
	return 1
    }
}


proc fs_superuser [ ] {
    set tmpfile "tmp000"
    exec rm -f $tmpfile
    touch $tmpfile
    exec chmod 000 $tmpfile
    set retval 0

    if [ file readable $tmpfile ] {
	# On Cygwin, a user with admin rights can read all files, and
	# access(foo,R_OK) correctly returns 1 for all files.
	warning "You have superuser privileges, skipping this test."
	untested {skipping this test because you have superuser privileges}
	set retval 1
    }
    exec rm -f $tmpfile
    return $retval
}