194 lines · 7.2 KB · Rust
RawDownload
mod all {    use git_tempfile::create_dir;     #[test]    fn a_deeply_nested_directory() -> crate::Result {        let dir = tempfile::tempdir()?;        let target = &dir.path().join("1").join("2").join("3").join("4").join("5").join("6");        let dir = create_dir::all(target, Default::default())?;        assert_eq!(dir, target, "all subdirectories can be created");        Ok(())    }}mod iter {    pub use std::io::ErrorKind::*;     use git_tempfile::{        create_dir,        create_dir::{Error::*, Retries},    };     #[test]    fn an_existing_directory_causes_immediate_success() -> crate::Result {        let dir = tempfile::tempdir()?;        let mut it = create_dir::Iter::new(dir.path());        assert_eq!(            it.next().expect("item").expect("success"),            dir.path(),            "first iteration is immediately successful"        );        assert!(it.next().is_none(), "iterator exhausted afterwards");        Ok(())    }     #[test]    fn a_single_directory_can_be_created_too() -> crate::Result {        let dir = tempfile::tempdir()?;        let new_dir = dir.path().join("new");        let mut it = create_dir::Iter::new(&new_dir);        assert_eq!(            it.next().expect("item").expect("success"),            &new_dir,            "first iteration is immediately successful"        );        assert!(it.next().is_none(), "iterator exhausted afterwards");        assert!(new_dir.is_dir(), "the directory exists");        Ok(())    }     #[test]    fn multiple_intermediate_directories_are_created_automaticaly() -> crate::Result {        let dir = tempfile::tempdir()?;        let new_dir = dir.path().join("s1").join("s2").join("new");        let mut it = create_dir::Iter::new(&new_dir);        assert!(            matches!(it.next(), Some(Err(Intermediate{dir, kind: k})) if k == NotFound && dir == new_dir),            "dir is not present"        );        assert!(            matches!(it.next(), Some(Err(Intermediate{dir, kind:k})) if k == NotFound && dir == new_dir.parent().unwrap()),            "parent dir is not present"        );        assert_eq!(            it.next().expect("item").expect("success"),            new_dir.parent().unwrap().parent().unwrap(),            "first subdir is created"        );        assert_eq!(            it.next().expect("item").expect("success"),            new_dir.parent().unwrap(),            "second subdir is created"        );        assert_eq!(            it.next().expect("item").expect("success"),            new_dir,            "target directory is created"        );        assert!(it.next().is_none(), "iterator depleted");        assert!(new_dir.is_dir(), "the directory exists");        Ok(())    }     #[test]    fn multiple_intermediate_directories_are_created_up_to_retries_limit() -> crate::Result {        let dir = tempfile::tempdir()?;        let new_dir = dir.path().join("s1").join("s2").join("new");        let mut it = create_dir::Iter::new_with_retries(            &new_dir,            Retries {                on_create_directory_failure: 1,                ..Default::default()            },        );        assert!(            matches!(it.next(), Some(Err(Permanent{ retries_left, dir, err, ..})) if retries_left.on_create_directory_failure == 0                                                                    && err.kind() == NotFound                                                                    && dir == new_dir),            "parent dir is not present and we run out of attempts"        );        assert!(it.next().is_none(), "iterator depleted");        assert!(!new_dir.is_dir(), "the wasn't created");        Ok(())    }     #[test]    fn an_existing_file_makes_directory_creation_fail_permanently() -> crate::Result {        let dir = tempfile::tempdir()?;        let new_dir = dir.path().join("also-file");        std::fs::write(&new_dir, &[42])?;        assert!(new_dir.is_file());         let mut it = create_dir::Iter::new(&new_dir);        assert!(            matches!(it.next(), Some(Err(Permanent{ dir, err, .. })) if err.kind() == AlreadyExists                                                                    && dir == new_dir),            "parent dir is not present and we run out of attempts"        );        assert!(it.next().is_none(), "iterator depleted");        assert!(new_dir.is_file(), "file is untouched");        Ok(())    }    #[test]    fn racy_directory_creation_with_new_directory_being_deleted_not_enough_retries() -> crate::Result {        let dir = tempfile::tempdir()?;        let new_dir = dir.path().join("a").join("new");        let parent_dir = new_dir.parent().unwrap();        let mut it = create_dir::Iter::new_with_retries(            &new_dir,            Retries {                to_create_entire_directory: 2,                on_create_directory_failure: 2,                ..Default::default()            },        );         assert!(            matches!(it.nth(1), Some(Ok(dir)) if dir == parent_dir),            "parent dir is created"        );        // Someone deletes the new directory        std::fs::remove_dir(parent_dir)?;         assert!(            matches!(it.nth(1), Some(Ok(dir)) if dir == parent_dir),            "parent dir is created"        );        // Someone deletes the new directory, again        std::fs::remove_dir(parent_dir)?;         assert!(            matches!(it.next(), Some(Err(Permanent{ retries_left, dir, err, .. })) if retries_left.to_create_entire_directory == 0                                                                    && retries_left.on_create_directory_failure == 1                                                                    && err.kind() == NotFound                                                                    && dir == new_dir),            "we run out of attempts to retry to combat against raciness"        );        Ok(())    }     #[test]    fn racy_directory_creation_with_new_directory_being_deleted() -> crate::Result {        let dir = tempfile::tempdir()?;        let new_dir = dir.path().join("a").join("new");        let parent_dir = new_dir.parent().unwrap();        let mut it = create_dir::Iter::new(&new_dir);         assert!(            matches!(it.next(), Some(Err(Intermediate{dir, kind:k})) if k == NotFound && dir == new_dir),            "dir is not present, and we go up a level"        );        assert!(            matches!(it.next(), Some(Ok(dir)) if dir == parent_dir),            "parent dir is created"        );        // Someone deletes the new directory        std::fs::remove_dir(parent_dir)?;         assert!(            matches!(it.next(), Some(Err(Intermediate{dir, kind:k})) if k == NotFound && dir == new_dir),            "now when it tries the actual dir its not found"        );        assert!(            matches!(it.next(), Some(Ok(dir)) if dir == parent_dir),            "parent dir is created as it retries"        );        assert!(            matches!(it.next(), Some(Ok(dir)) if dir == new_dir),            "target dir is created successfully"        );        assert!(it.next().is_none(), "iterator depleted");        assert!(new_dir.is_dir());         Ok(())    }}