1# 2# Copyright 2014, Google Inc. All rights reserved. 3# 4# Redistribution and use in source and binary forms, with or without 5# modification, are permitted provided that the following conditions are 6# met: 7# 8# * Redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer. 10# * Redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution. 13# * Neither the name of Google Inc. nor the names of its 14# contributors may be used to endorse or promote products derived from 15# this software without specific written permission. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28# 29# 30 31# Helper function that is always used to create and fill stderr.txt for these 32# tests. 33_custom_create_file() 34{ 35 # The first argument is a command. 36 # The second is just a string. 37 case "${1}" in 38 creat) > stderr.txt ;; 39 print) [ "${2}" ] && \ 40 printf "%s\n" "${2}" >> stderr.txt ;; 41 esac 42} 43 44# Helper function that create the file stderr.txt that contains the string 45# passed in as the first argument. 46create_stderr_file() 47{ 48 _custom_create_file creat 49 _custom_create_file print "${1}" 50} 51 52# Helper function that create the file stderr.txt that contains the expected 53# truncate utility usage message. 54create_stderr_usage_file() 55{ 56 _custom_create_file creat 57 _custom_create_file print "${1}" 58 _custom_create_file print \ 59 "usage: truncate [-c] -s [+|-|%|/]size[K|k|M|m|G|g|T|t] file ..." 60 _custom_create_file print " truncate [-c] -r rfile file ..." 61 _custom_create_file print " truncate [-c] -d [-o offset[K|k|M|m|G|g|T|t]] -l length[K|k|M|m|G|g|T|t] file ..." 62} 63 64atf_test_case illegal_option 65illegal_option_head() 66{ 67 atf_set "descr" "Verifies that truncate exits >0 when passed an" \ 68 "invalid command line option" 69} 70illegal_option_body() 71{ 72 create_stderr_usage_file 'truncate: illegal option -- 7' 73 74 # We expect the error message, with no new files. 75 atf_check -s not-exit:0 -e file:stderr.txt truncate -7 -s0 output.txt 76 [ ! -e output.txt ] || atf_fail "output.txt should not exist" 77} 78 79atf_test_case illegal_size 80illegal_size_head() 81{ 82 atf_set "descr" "Verifies that truncate exits >0 when passed an" \ 83 "invalid power of two convention" 84} 85illegal_size_body() 86{ 87 create_stderr_file "truncate: invalid size argument \`+1L'" 88 89 # We expect the error message, with no new files. 90 atf_check -s not-exit:0 -e file:stderr.txt truncate -s+1L output.txt 91 [ ! -e output.txt ] || atf_fail "output.txt should not exist" 92} 93 94atf_test_case too_large_size 95too_large_size_head() 96{ 97 atf_set "descr" "Verifies that truncate exits >0 when passed an" \ 98 "a size that is INT64_MAX < size <= UINT64_MAX" 99} 100too_large_size_body() 101{ 102 create_stderr_file "truncate: invalid size argument \`8388608t'" 103 104 # We expect the error message, with no new files. 105 atf_check -s not-exit:0 -e file:stderr.txt \ 106 truncate -s8388608t output.txt 107 [ ! -e output.txt ] || atf_fail "output.txt should not exist" 108} 109 110atf_test_case opt_c 111opt_c_head() 112{ 113 atf_set "descr" "Verifies that -c prevents creation of new files" 114} 115opt_c_body() 116{ 117 # No new files and truncate returns 0 as if this is a success. 118 atf_check truncate -c -s 0 doesnotexist.txt 119 [ ! -e output.txt ] || atf_fail "doesnotexist.txt should not exist" 120 > reference 121 atf_check truncate -c -r reference doesnotexist.txt 122 [ ! -e output.txt ] || atf_fail "doesnotexist.txt should not exist" 123 124 create_stderr_file 125 126 # The existing file will be altered by truncate. 127 > exists.txt 128 atf_check -e file:stderr.txt truncate -c -s1 exists.txt 129 [ -s exists.txt ] || atf_fail "exists.txt be larger than zero bytes" 130} 131 132atf_test_case opt_rs 133opt_rs_head() 134{ 135 atf_set "descr" "Verifies that truncate command line flags" \ 136 "-s and -r cannot be specifed together" 137} 138opt_rs_body() 139{ 140 create_stderr_usage_file 141 142 # Force an error due to the use of both -s and -r. 143 > afile 144 atf_check -s not-exit:0 -e file:stderr.txt truncate -s0 -r afile afile 145} 146 147atf_test_case no_files 148no_files_head() 149{ 150 atf_set "descr" "Verifies that truncate needs a list of files on" \ 151 "the command line" 152} 153no_files_body() 154{ 155 create_stderr_usage_file 156 157 # A list of files must be present on the command line. 158 atf_check -s not-exit:0 -e file:stderr.txt truncate -s1 159} 160 161atf_test_case bad_refer 162bad_refer_head() 163{ 164 atf_set "descr" "Verifies that truncate detects a non-existent" \ 165 "reference file" 166} 167bad_refer_body() 168{ 169 create_stderr_file "truncate: afile: No such file or directory" 170 171 # The reference file must exist before you try to use it. 172 atf_check -s not-exit:0 -e file:stderr.txt truncate -r afile afile 173 [ ! -e afile ] || atf_fail "afile should not exist" 174} 175 176atf_test_case bad_truncate 177bad_truncate_head() 178{ 179 atf_set "descr" "Verifies that truncate reports an error during" \ 180 "truncation" 181 atf_set "require.user" "unprivileged" 182} 183bad_truncate_body() 184{ 185 create_stderr_file "truncate: exists.txt: Permission denied" 186 187 # Trying to get the ftruncate() call to return -1. 188 > exists.txt 189 atf_check chmod 444 exists.txt 190 191 atf_check -s not-exit:0 -e file:stderr.txt truncate -s1 exists.txt 192} 193 194atf_test_case new_absolute_grow 195new_absolute_grow_head() 196{ 197 atf_set "descr" "Verifies truncate can make and grow a new 1m file" 198} 199new_absolute_grow_body() 200{ 201 create_stderr_file 202 203 # Create a new file and grow it to 1024 bytes. 204 atf_check -s exit:0 -e file:stderr.txt truncate -s1k output.txt 205 atf_check -s exit:1 cmp -s output.txt /dev/zero 206 eval $(stat -s output.txt) 207 [ ${st_size} -eq 1024 ] || atf_fail "expected file size of 1k" 208 209 create_stderr_file 210 211 # Grow the existing file to 1M. We are using absolute sizes. 212 atf_check -s exit:0 -e file:stderr.txt truncate -c -s1M output.txt 213 atf_check -s exit:1 cmp -s output.txt /dev/zero 214 eval $(stat -s output.txt) 215 [ ${st_size} -eq 1048576 ] || atf_fail "expected file size of 1m" 216} 217 218atf_test_case new_absolute_shrink 219new_absolute_shrink_head() 220{ 221 atf_set "descr" "Verifies that truncate can make and" \ 222 "shrink a new 1m file" 223} 224new_absolute_shrink_body() 225{ 226 create_stderr_file 227 228 # Create a new file and grow it to 1048576 bytes. 229 atf_check -s exit:0 -e file:stderr.txt truncate -s1M output.txt 230 atf_check -s exit:1 cmp -s output.txt /dev/zero 231 eval $(stat -s output.txt) 232 [ ${st_size} -eq 1048576 ] || atf_fail "expected file size of 1m" 233 234 create_stderr_file 235 236 # Shrink the existing file to 1k. We are using absolute sizes. 237 atf_check -s exit:0 -e file:stderr.txt truncate -s1k output.txt 238 atf_check -s exit:1 cmp -s output.txt /dev/zero 239 eval $(stat -s output.txt) 240 [ ${st_size} -eq 1024 ] || atf_fail "expected file size of 1k" 241} 242 243atf_test_case new_relative_grow 244new_relative_grow_head() 245{ 246 atf_set "descr" "Verifies truncate can make and grow a new 1m file" \ 247 "using relative sizes" 248} 249new_relative_grow_body() 250{ 251 create_stderr_file 252 253 # Create a new file and grow it to 1024 bytes. 254 atf_check -s exit:0 -e file:stderr.txt truncate -s+1k output.txt 255 atf_check -s exit:1 cmp -s output.txt /dev/zero 256 eval $(stat -s output.txt) 257 [ ${st_size} -eq 1024 ] || atf_fail "expected file size of 1k" 258 259 create_stderr_file 260 261 # Grow the existing file to 1M. We are using relative sizes. 262 atf_check -s exit:0 -e file:stderr.txt truncate -s+1047552 output.txt 263 atf_check -s exit:1 cmp -s output.txt /dev/zero 264 eval $(stat -s output.txt) 265 [ ${st_size} -eq 1048576 ] || atf_fail "expected file size of 1m" 266} 267 268atf_test_case new_relative_shrink 269new_relative_shrink_head() 270{ 271 atf_set "descr" "Verifies truncate can make and shrink a new 1m file" \ 272 "using relative sizes" 273} 274new_relative_shrink_body() 275{ 276 create_stderr_file 277 278 # Create a new file and grow it to 1049600 bytes. 279 atf_check -s exit:0 -e file:stderr.txt truncate -s+1049600 output.txt 280 atf_check -s exit:1 cmp -s output.txt /dev/zero 281 eval $(stat -s output.txt) 282 [ ${st_size} -eq 1049600 ] || atf_fail "expected file size of 1m" 283 284 create_stderr_file 285 286 # Shrink the existing file to 1k. We are using relative sizes. 287 atf_check -s exit:0 -e file:stderr.txt truncate -s-1M output.txt 288 atf_check -s exit:1 cmp -s output.txt /dev/zero 289 eval $(stat -s output.txt) 290 [ ${st_size} -eq 1024 ] || atf_fail "expected file size of 1k" 291} 292 293atf_test_case cannot_open 294cannot_open_head() 295{ 296 atf_set "descr" "Verifies truncate handles open failures correctly" \ 297 "in a list of files" 298 atf_set "require.user" "unprivileged" 299} 300cannot_open_body() 301{ 302 # Create three files -- the middle file cannot allow writes. 303 > before 304 > 0000 305 > after 306 atf_check chmod 0000 0000 307 308 create_stderr_file "truncate: 0000: Permission denied" 309 310 # Create a new file and grow it to 1024 bytes. 311 atf_check -s not-exit:0 -e file:stderr.txt \ 312 truncate -c -s1k before 0000 after 313 eval $(stat -s before) 314 [ ${st_size} -eq 1024 ] || atf_fail "expected file size of 1k" 315 eval $(stat -s after) 316 [ ${st_size} -eq 1024 ] || atf_fail "expected file size of 1k" 317 eval $(stat -s 0000) 318 [ ${st_size} -eq 0 ] || atf_fail "expected file size of zero" 319} 320 321atf_test_case reference 322reference_head() 323{ 324 atf_set "descr" "Verifies that truncate can use a reference file" 325} 326reference_body() 327{ 328 # Create a 4 byte reference file. 329 printf "123\n" > reference 330 eval $(stat -s reference) 331 [ ${st_size} -eq 4 ] || atf_fail "reference file should be 4 bytes" 332 333 create_stderr_file 334 335 # Create a new file and grow it to 4 bytes. 336 atf_check -e file:stderr.txt truncate -r reference afile 337 eval $(stat -s afile) 338 [ ${st_size} -eq 4 ] || atf_fail "new file should also be 4 bytes" 339} 340 341atf_test_case new_zero 342new_zero_head() 343{ 344 atf_set "descr" "Verifies truncate can make and grow zero byte file" 345} 346new_zero_body() 347{ 348 create_stderr_file 349 350 # Create a new file and grow it to zero bytes. 351 atf_check -s exit:0 -e file:stderr.txt truncate -s0 output.txt 352 eval $(stat -s output.txt) 353 [ ${st_size} -eq 0 ] || atf_fail "expected file size of zero" 354 355 # Pretend to grow the file. 356 atf_check -s exit:0 -e file:stderr.txt truncate -s+0 output.txt 357 eval $(stat -s output.txt) 358 [ ${st_size} -eq 0 ] || atf_fail "expected file size of zero" 359} 360 361atf_test_case negative 362negative_head() 363{ 364 atf_set "descr" "Verifies truncate treats negative sizes as zero" 365} 366negative_body() 367{ 368 # Create a 5 byte file. 369 printf "abcd\n" > afile 370 eval $(stat -s afile) 371 [ ${st_size} -eq 5 ] || atf_fail "afile file should be 5 bytes" 372 373 create_stderr_file 374 375 # Create a new file and do a 100 byte negative relative shrink. 376 atf_check -e file:stderr.txt truncate -s-100 afile 377 eval $(stat -s afile) 378 [ ${st_size} -eq 0 ] || atf_fail "new file should now be zero bytes" 379} 380 381atf_test_case roundup 382roundup_head() 383{ 384 atf_set "descr" "Verifies truncate round up" 385} 386roundup_body() 387{ 388 # Create a 5 byte file. 389 printf "abcd\n" > afile 390 eval $(stat -s afile) 391 [ ${st_size} -eq 5 ] || atf_fail "afile file should be 5 bytes" 392 393 create_stderr_file 394 395 # Create a new file and do a 100 byte roundup. 396 atf_check -e file:stderr.txt truncate -s%100 afile 397 eval $(stat -s afile) 398 [ ${st_size} -eq 100 ] || atf_fail "new file should now be 100 bytes" 399} 400 401atf_test_case rounddown 402rounddown_head() 403{ 404 atf_set "descr" "Verifies truncate round down" 405} 406rounddown_body() 407{ 408 # Create a 5 byte file. 409 printf "abcd\n" > afile 410 eval $(stat -s afile) 411 [ ${st_size} -eq 5 ] || atf_fail "afile file should be 5 bytes" 412 413 create_stderr_file 414 415 # Create a new file and do a 2 byte roundup. 416 atf_check -e file:stderr.txt truncate -s/2 afile 417 eval $(stat -s afile) 418 [ ${st_size} -eq 4 ] || atf_fail "new file should now be 4 bytes" 419} 420 421atf_test_case rounddown_zero 422rounddown_zero_head() 423{ 424 atf_set "descr" "Verifies truncate round down to zero" 425} 426rounddown_zero_body() 427{ 428 # Create a 5 byte file. 429 printf "abcd\n" > afile 430 eval $(stat -s afile) 431 [ ${st_size} -eq 5 ] || atf_fail "afile file should be 5 bytes" 432 433 create_stderr_file 434 435 # Create a new file and do a 10 byte roundup. 436 atf_check -e file:stderr.txt truncate -s/10 afile 437 eval $(stat -s afile) 438 [ ${st_size} -eq 0 ] || atf_fail "new file should now be 0 bytes" 439} 440 441atf_init_test_cases() 442{ 443 atf_add_test_case illegal_option 444 atf_add_test_case illegal_size 445 atf_add_test_case too_large_size 446 atf_add_test_case opt_c 447 atf_add_test_case opt_rs 448 atf_add_test_case no_files 449 atf_add_test_case bad_refer 450 atf_add_test_case bad_truncate 451 atf_add_test_case cannot_open 452 atf_add_test_case new_absolute_grow 453 atf_add_test_case new_absolute_shrink 454 atf_add_test_case new_relative_grow 455 atf_add_test_case new_relative_shrink 456 atf_add_test_case reference 457 atf_add_test_case new_zero 458 atf_add_test_case negative 459 atf_add_test_case roundup 460 atf_add_test_case rounddown 461 atf_add_test_case rounddown_zero 462} 463