def test_model_checkpoint_link_checkpoint(tmp_path):
    """Test that linking a checkpoint works and overwrites an existing link if present."""
    trainer = Mock()

    # link doesn't exist
    file = tmp_path / "file"
    file.touch()
    link = tmp_path / "link"
    ModelCheckpoint._link_checkpoint(trainer, filepath=str(file), linkpath=str(link))
    assert os.path.islink(link)
    assert os.path.realpath(link) == str(file)
    assert not os.path.isabs(os.readlink(link))

    # link exists (is a file)
    new_file1 = tmp_path / "new_file1"
    new_file1.touch()
    ModelCheckpoint._link_checkpoint(trainer, filepath=str(new_file1), linkpath=str(link))
    assert os.path.islink(link)
    assert os.path.realpath(link) == str(new_file1)
    assert not os.path.isabs(os.readlink(link))

    # link exists (is a link)
    new_file2 = tmp_path / "new_file2"
    new_file2.touch()
    ModelCheckpoint._link_checkpoint(trainer, filepath=str(new_file2), linkpath=str(link))
    assert os.path.islink(link)
    assert os.path.realpath(link) == str(new_file2)
    assert not os.path.isabs(os.readlink(link))

    # link exists (is a folder)
    folder = tmp_path / "folder"
    folder.mkdir()
    folder_link = tmp_path / "folder_link"
    folder_link.mkdir()
    ModelCheckpoint._link_checkpoint(trainer, filepath=str(folder), linkpath=str(folder_link))
    assert os.path.islink(folder_link)
    assert os.path.realpath(folder_link) == str(folder)
    assert not os.path.isabs(os.readlink(folder_link))

    # link exists (is a link to a folder)
    new_folder = tmp_path / "new_folder"
    new_folder.mkdir()
    ModelCheckpoint._link_checkpoint(trainer, filepath=str(new_folder), linkpath=str(folder_link))
    assert os.path.islink(folder_link)
    assert os.path.realpath(folder_link) == str(new_folder)
    assert not os.path.isabs(os.readlink(folder_link))

    # simulate permission error on Windows (creation of symbolic links requires privileges)
    file = tmp_path / "win_file"
    file.touch()
    link = tmp_path / "win_link"
    with mock.patch("lightning.pytorch.callbacks.model_checkpoint.os.symlink", Mock(side_effect=OSError)):
        ModelCheckpoint._link_checkpoint(trainer, filepath=str(file), linkpath=str(link))
    assert not os.path.islink(link)
    assert os.path.isfile(link)  # fall back to copying instead of linking
Test that linking a checkpoint works and overwrites an existing link if present.
tests/tests_pytorch/checkpointing/test_model_checkpoint.py