Files
Jose Luis Duran 93b15dbc1f makefs: tests: Fix timestamp-related tests
Use a variable for mtree that includes the DEFAULT_MTREE_KEYWORDS, in
order to avoid missing the important "time" keyword or passing an
unimplemented "nlink" keyword.

Unskip the "failing" tests, and comment out the specific failing checks,
these will be addressed (or at least discussed) in a different revision.

For MS-DOS tests, use an even value timestamp, as precision is 2s.

For ZFS tests, use import_image instead of mount_image consistently.

Reviewed by:	bnovkov, markj
MFC after:	1 week
Differential Revision:	https://reviews.freebsd.org/D54429
2026-01-05 20:34:03 +00:00

459 lines
11 KiB
Bash

#
# Copyright 2015 EMC Corp.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# A note on specs:
# - A copy of the ISO-9660 spec can be found here:
# https://ecma-international.org/wp-content/uploads/ECMA-119_5th_edition_december_2024.pdf
# - Any references to `rockridge` are referring to the `Rock Ridge` extensions
# of the ISO-9660 spec. A copy of the draft `IEEE-P1282` spec can be found
# here:
# https://people.freebsd.org/~emaste/rrip112.pdf
MAKEFS="makefs -t cd9660"
MOUNT="mount_cd9660"
. "$(dirname "$0")/makefs_tests_common.sh"
common_cleanup()
{
if ! test_md_device=$(cat $TEST_MD_DEVICE_FILE); then
echo "$TEST_MD_DEVICE_FILE could not be opened; has an md(4) device been attached?"
return
fi
umount -f /dev/$test_md_device || :
mdconfig -d -u $test_md_device || :
}
check_base_iso9660_image_contents()
{
# Symlinks are treated like files when rockridge support isn't
# specified, and directories cannot contain a '.'.
check_image_contents "$@" -X c -X .g -X _g
atf_check test -L $TEST_INPUTS_DIR/c
atf_check test -f $TEST_MOUNT_DIR/c
}
atf_test_case D_flag
D_flag_body()
{
create_test_inputs
create_manifest_file
# Check that it works
atf_check $MAKEFS -M 1m $TEST_IMAGE $TEST_SPEC_FILE
# Duplicate entries in the manifest file
cp $TEST_SPEC_FILE spec2.mtree
cat $TEST_SPEC_FILE spec2.mtree | sort > "${TEST_SPEC_FILE}_dupe"
# Check that it errors
atf_check -e not-empty -s not-exit:0 \
$MAKEFS -M 1m $TEST_IMAGE ${TEST_SPEC_FILE}_dupe
# Check that it warns
atf_check -e not-empty \
$MAKEFS -D -M 1m $TEST_IMAGE ${TEST_SPEC_FILE}_dupe
}
atf_test_case F_flag cleanup
F_flag_body()
{
create_test_inputs
atf_check -o save:$TEST_SPEC_FILE $MTREE -c -p $TEST_INPUTS_DIR
atf_check $MAKEFS -F $TEST_SPEC_FILE -M 1m $TEST_IMAGE $TEST_INPUTS_DIR
mount_image
check_base_iso9660_image_contents
}
F_flag_cleanup()
{
common_cleanup
}
atf_test_case from_mtree_spec_file cleanup
from_mtree_spec_file_body()
{
create_test_inputs
atf_check -o save:$TEST_SPEC_FILE $MTREE -c -p $TEST_INPUTS_DIR
cd $TEST_INPUTS_DIR
atf_check $MAKEFS $TEST_IMAGE $TEST_SPEC_FILE
cd -
mount_image
check_base_iso9660_image_contents
}
from_mtree_spec_file_cleanup()
{
common_cleanup
}
atf_test_case from_multiple_dirs cleanup
from_multiple_dirs_body()
{
test_inputs_dir2=$TMPDIR/inputs2
create_test_inputs
atf_check mkdir -p $test_inputs_dir2
atf_check touch $test_inputs_dir2/multiple_dirs_test_file
atf_check $MAKEFS $TEST_IMAGE $TEST_INPUTS_DIR $test_inputs_dir2
mount_image
check_base_iso9660_image_contents -d $test_inputs_dir2
}
from_multiple_dirs_cleanup()
{
common_cleanup
}
atf_test_case from_single_dir cleanup
from_single_dir_body()
{
create_test_inputs
atf_check $MAKEFS $TEST_IMAGE $TEST_INPUTS_DIR
mount_image
check_base_iso9660_image_contents
}
from_single_dir_cleanup()
{
common_cleanup
}
atf_test_case o_flag_allow_deep_trees cleanup
o_flag_allow_deep_trees_body()
{
create_test_inputs
# Make sure the "more than 8 levels deep" requirement is met.
atf_check mkdir -p $TEST_INPUTS_DIR/a/b/c/d/e/f/g/h/i/j
atf_check $MAKEFS -o allow-deep-trees $TEST_IMAGE $TEST_INPUTS_DIR
mount_image
check_base_iso9660_image_contents
}
o_flag_allow_deep_trees_cleanup()
{
common_cleanup
}
atf_test_case o_flag_allow_max_name cleanup
o_flag_allow_max_name_body()
{
atf_skip "-o allow-max-name is not implemented"
create_test_inputs
long_path=$TEST_INPUTS_DIR/$(jot -s '' -b 0 37)
# Make sure the "37 char name" limit requirement is met.
atf_check touch $long_path
atf_check $MAKEFS -o allow-max-name $TEST_IMAGE $TEST_INPUTS_DIR
mount_image
check_base_iso9660_image_contents
}
o_flag_allow_max_name_cleanup()
{
common_cleanup
}
atf_test_case o_flag_isolevel_1 cleanup
o_flag_isolevel_1_body()
{
atf_skip "-o isolevel=1 is failing"
create_test_inputs
atf_check $MAKEFS -o isolevel=1 $TEST_IMAGE $TEST_INPUTS_DIR
mount_image
check_base_iso9660_image_contents
}
o_flag_isolevel_1_cleanup()
{
common_cleanup
}
atf_test_case o_flag_isolevel_2 cleanup
o_flag_isolevel_2_body()
{
create_test_inputs
atf_check $MAKEFS -o isolevel=2 $TEST_IMAGE $TEST_INPUTS_DIR
mount_image
check_base_iso9660_image_contents
}
o_flag_isolevel_2_cleanup()
{
common_cleanup
}
atf_test_case o_flag_isolevel_3 cleanup
o_flag_isolevel_3_body()
{
# XXX: isolevel=3 isn't implemented yet. See FreeBSD bug # 203645
atf_check -e match:'makefs: ISO Level 3 is greater than 2\.' \
-s not-exit:0 \
$MAKEFS -o isolevel=3 $TEST_IMAGE $TEST_INPUTS_DIR
atf_skip "-o isolevel=3 is not implemented"
create_test_inputs
atf_check $MAKEFS -o isolevel=3 $TEST_IMAGE $TEST_INPUTS_DIR
mount_image
check_base_iso9660_image_contents
}
o_flag_isolevel_3_cleanup()
{
common_cleanup
}
atf_test_case o_flag_preparer
o_flag_preparer_head()
{
atf_set "require.progs" "strings"
}
o_flag_preparer_body()
{
create_test_dirs
preparer='My Very First ISO'
preparer_uppercase="$(echo $preparer | tr '[[:lower:]]' '[[:upper:]]')"
atf_check touch $TEST_INPUTS_DIR/dummy_file
atf_check $MAKEFS -o preparer="$preparer" $TEST_IMAGE $TEST_INPUTS_DIR
atf_check -o match:"$preparer_uppercase" strings $TEST_IMAGE
}
atf_test_case o_flag_publisher
o_flag_publisher_head()
{
atf_set "require.progs" "strings"
}
o_flag_publisher_body()
{
create_test_dirs
publisher='My Super Awesome Publishing Company LTD'
publisher_uppercase="$(echo $publisher | tr '[[:lower:]]' '[[:upper:]]')"
atf_check touch $TEST_INPUTS_DIR/dummy_file
atf_check $MAKEFS -o publisher="$publisher" $TEST_IMAGE $TEST_INPUTS_DIR
atf_check -o match:"$publisher_uppercase" strings $TEST_IMAGE
}
atf_test_case o_flag_rockridge cleanup
o_flag_rockridge_body()
{
create_test_dirs
# Make sure the "more than 8 levels deep" requirement is met.
atf_check mkdir -p $TEST_INPUTS_DIR/a/b/c/d/e/f/g/h/i/j
# Make sure the "pathname larger than 255 chars" requirement is met.
#
# $long_path's needs to be nested in a directory, as creating it
# outright as a 256 char filename via touch will fail with ENAMETOOLONG
long_path=$TEST_INPUTS_DIR/$(jot -s '/' -b "$(jot -s '' -b 0 64)" 4)
atf_check mkdir -p "$(dirname $long_path)"
atf_check touch "$long_path"
atf_check $MAKEFS -o rockridge $TEST_IMAGE $TEST_INPUTS_DIR
mount_image
check_image_contents -X .rr_moved
# .rr_moved is a special directory created when you have deep directory
# trees with rock ridge extensions on
atf_check test -d $TEST_MOUNT_DIR/.rr_moved
}
o_flag_rockridge_cleanup()
{
common_cleanup
}
atf_test_case o_flag_rockridge_dev_nodes cleanup
o_flag_rockridge_dev_nodes_head()
{
atf_set "descr" "Functional tests to ensure that dev nodes are handled properly with rockridge extensions (NetBSD kern/48852; FreeBSD bug 203648)"
}
o_flag_rockridge_dev_nodes_body()
{
create_test_dirs
(tar -cvf - -C /dev null && touch .tar_ok) | \
atf_check -e not-empty tar -xvf - -C "$TEST_INPUTS_DIR"
atf_check test -c $TEST_INPUTS_DIR/null
atf_check test -f .tar_ok
atf_check $MAKEFS -o rockridge $TEST_IMAGE $TEST_INPUTS_DIR
mount_image
check_image_contents
}
o_flag_rockridge_dev_nodes_cleanup()
{
common_cleanup
}
atf_test_case T_flag_dir cleanup
T_flag_dir_body()
{
timestamp=1742574909
create_test_dirs
mkdir -p $TEST_INPUTS_DIR/dir1
atf_check $MAKEFS -T $timestamp -o rockridge $TEST_IMAGE $TEST_INPUTS_DIR
mount_image
eval $(stat -s $TEST_MOUNT_DIR/dir1)
atf_check_equal $st_atime $timestamp
atf_check_equal $st_mtime $timestamp
atf_check_equal $st_ctime $timestamp
}
T_flag_dir_cleanup()
{
common_cleanup
}
atf_test_case T_flag_F_flag cleanup
T_flag_F_flag_body()
{
timestamp_F=1742574909
timestamp_T=1742574910
create_test_dirs
mkdir -p $TEST_INPUTS_DIR/dir1
atf_check -o save:$TEST_SPEC_FILE $MTREE -c -p $TEST_INPUTS_DIR
change_mtree_timestamp $TEST_SPEC_FILE $timestamp_F
atf_check \
$MAKEFS -F $TEST_SPEC_FILE -T $timestamp_T -o rockridge $TEST_IMAGE $TEST_INPUTS_DIR
mount_image
eval $(stat -s $TEST_MOUNT_DIR/dir1)
atf_check_equal $st_atime $timestamp_F
atf_check_equal $st_mtime $timestamp_F
# atf_check_equal $st_ctime $timestamp_F
}
T_flag_F_flag_cleanup()
{
common_cleanup
}
atf_test_case T_flag_mtree cleanup
T_flag_mtree_body()
{
timestamp=1742574909
create_test_dirs
mkdir -p $TEST_INPUTS_DIR/dir1
atf_check -o save:$TEST_SPEC_FILE $MTREE -c -p $TEST_INPUTS_DIR
atf_check $MAKEFS -T $timestamp -o rockridge $TEST_IMAGE $TEST_SPEC_FILE
mount_image
eval $(stat -s $TEST_MOUNT_DIR/dir1)
atf_check_equal $st_atime $timestamp
atf_check_equal $st_mtime $timestamp
atf_check_equal $st_ctime $timestamp
}
T_flag_mtree_cleanup()
{
common_cleanup
}
atf_test_case duplicate_names cleanup
duplicate_names_head()
{
atf_set "descr" "Ensure shortened directory names are unique (PR283238)"
}
duplicate_names_body()
{
create_test_dirs
# Create three directories which are identical in the first 31 characters.
dir_prefix="this_directory_name_is_31_chars"
mkdir -p $TEST_INPUTS_DIR/${dir_prefix}1
mkdir -p $TEST_INPUTS_DIR/${dir_prefix}2
mkdir -p $TEST_INPUTS_DIR/${dir_prefix}3
atf_check $MAKEFS -o rockridge $TEST_IMAGE $TEST_INPUTS_DIR
# Disable Rock Ridge extensions to read the plain ISO Level 2 names.
mount_image -r
# The specific way the short names are made unique is not important.
# We verify only that there are three unique names and that the unique
# part is at the end of the name.
atf_check_equal $(ls -1 $TEST_MOUNT_DIR | sort | uniq | wc -l) 3
atf_check_equal $(ls -1 $TEST_MOUNT_DIR | cut -c -29 | sort | uniq | wc -l) 1
}
duplicate_names_cleanup()
{
common_cleanup
}
atf_init_test_cases()
{
atf_add_test_case D_flag
atf_add_test_case F_flag
atf_add_test_case from_mtree_spec_file
atf_add_test_case from_multiple_dirs
atf_add_test_case from_single_dir
atf_add_test_case o_flag_allow_deep_trees
atf_add_test_case o_flag_allow_max_name
atf_add_test_case o_flag_isolevel_1
atf_add_test_case o_flag_isolevel_2
atf_add_test_case o_flag_isolevel_3
atf_add_test_case o_flag_preparer
atf_add_test_case o_flag_publisher
atf_add_test_case o_flag_rockridge
atf_add_test_case o_flag_rockridge_dev_nodes
atf_add_test_case T_flag_dir
atf_add_test_case T_flag_F_flag
atf_add_test_case T_flag_mtree
atf_add_test_case duplicate_names
}