From fb1e614ebb907012e21f69c176710ee117bdbae9 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Tue, 25 Jun 2024 17:50:09 -0400 Subject: [PATCH] Test symlinks to invalid and reserved Windows targets These are effectively special cases of dangling symlinks. They should be treated the same as ordinary dangling symlinks, but the error kind isn't NotFound for these, so currently they are not created. The new tests should pass once that is fixed. See #1420. --- ...ake_dangling_symlink_to_windows_invalid.sh | 13 +++++ ...ke_dangling_symlink_to_windows_reserved.sh | 13 +++++ gix-worktree-state/tests/state/checkout.rs | 48 +++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100755 gix-worktree-state/tests/fixtures/make_dangling_symlink_to_windows_invalid.sh create mode 100755 gix-worktree-state/tests/fixtures/make_dangling_symlink_to_windows_reserved.sh diff --git a/gix-worktree-state/tests/fixtures/make_dangling_symlink_to_windows_invalid.sh b/gix-worktree-state/tests/fixtures/make_dangling_symlink_to_windows_invalid.sh new file mode 100755 index 00000000000..68edb84cba9 --- /dev/null +++ b/gix-worktree-state/tests/fixtures/make_dangling_symlink_to_windows_invalid.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -eu -o pipefail + +git init -q + +# On Windows, the target is an invalid file name. +qmarks_oid=$(echo -n "???" | git hash-object -w --stdin) + +git update-index --index-info < crate::Result { Ok(()) } +#[test] +fn dangling_symlink_to_windows_invalid_target_can_be_created() -> crate::Result { + let opts = opts_from_probe(); + if !opts.fs.symlink { + eprintln!("Skipping dangling symlink test on filesystem that doesn't support it"); + return Ok(()); + } + + let (_source_tree, destination, _index, outcome) = + checkout_index_in_tmp_dir(opts.clone(), "make_dangling_symlink_to_windows_invalid", None)?; + let worktree_files = dir_structure(&destination); + let worktree_files_stripped = stripped_prefix(&destination, &worktree_files); + + assert_eq!(worktree_files_stripped, paths(["dangling-qmarks-symlink"])); + let symlink_path = &worktree_files[0]; + assert!(symlink_path + .symlink_metadata() + .expect("dangling symlink is on disk") + .is_symlink()); + assert_eq!(std::fs::read_link(symlink_path)?, Path::new("???")); + assert!(outcome.collisions.is_empty()); + Ok(()) +} + +#[test] +fn dangling_symlink_to_windows_reserved_target_can_be_created() -> crate::Result { + let opts = opts_from_probe(); + if !opts.fs.symlink { + eprintln!("Skipping dangling symlink test on filesystem that doesn't support it"); + return Ok(()); + } + + let (_source_tree, destination, _index, outcome) = + checkout_index_in_tmp_dir(opts.clone(), "make_dangling_symlink_to_windows_reserved", None)?; + let worktree_files = dir_structure(&destination); + let worktree_files_stripped = stripped_prefix(&destination, &worktree_files); + + assert_eq!(worktree_files_stripped, paths(["dangling-con-symlink"])); + let symlink_path = &worktree_files[0]; + assert!(symlink_path + .symlink_metadata() + .expect("dangling symlink is on disk") + .is_symlink()); + assert_eq!(std::fs::read_link(symlink_path)?, Path::new("CON")); + assert!(outcome.collisions.is_empty()); + Ok(()) +} + #[test] fn allow_or_disallow_symlinks() -> crate::Result { let mut opts = opts_from_probe();