From 4b3c9b2c5ba080fc8e2a9e051157b509eef5bc35 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. --- ...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();