Странное поведение при создании, чтении и удалении файлов в тестах в Rust - PullRequest
0 голосов
/ 07 мая 2020

Пытаюсь написать тест на модуль, сам модуль не важен.

Тестовая часть выглядит так. В этих двух тестах я пытаюсь сделать то же самое: создать файл JSON, прочитать его и удалить (это не настоящие тесты, но эти действия нужно повторять от тестов к тесту).

src / archive.rs

#[cfg(test)]
mod tests {
    use super::*;
    use std::{fs, path};
    use crate::tests;

    #[test]
    fn test_archive_tar_archive_test1() {
        tests::create_custom_settings(
            r#"{
                "tmp_path": "/tmp1",
                "archive_tmp_path": "/tmp1"
            }"#,
        );
        println!("reading {}", fs::read_to_string(tests::CUSTOM_SETTINGS_PATH).unwrap());
        tests::delete_custom_settings();
    }

    #[test]
    fn test_archive_tar_archive_test2() {
        tests::create_custom_settings(
            r#"{
                "tmp_path": "/tmp2",
                "archive_tmp_path": "/tmp2"
            }"#,
        );

        println!("reading {}", fs::read_to_string(tests::CUSTOM_SETTINGS_PATH).unwrap());
        tests::delete_custom_settings();
    }
}

Второй файл как basi c как первый, это общие части, используемые в нескольких модулях:

src / tests.rs

use std::fs;

pub const CUSTOM_SETTINGS_PATH: &str = "/tmp/hvtools_custom_settings.json";

pub fn create_custom_settings(file_data: &str) {
    println!("writing {}", file_data);
    match fs::write(CUSTOM_SETTINGS_PATH, file_data) {
        Ok(_) => {},
        Err(e) => panic!(
            "Could not create custom settings file under '{}': {}",
            CUSTOM_SETTINGS_PATH, e
        ),
    };
}

pub fn delete_custom_settings() {
    match fs::remove_file(CUSTOM_SETTINGS_PATH) {
        Ok(_) => {},
        Err(e) => panic!(
            "Could not delete custom settings file under '{}': {}",
            CUSTOM_SETTINGS_PATH, e
        ),
    };
}

При запуске этих тестов я получаю примерно одно и то же каждый раз с небольшими отличиями:

running 2 tests
writing {
                "tmp_path": "/tmp1",
                "archive_tmp_path": "/tmp1"
            }
writing {
                "tmp_path": "/tmp2",
                "archive_tmp_path": "/tmp2"
            }
reading {
                "tmp_path": "/tmp2",
                "archive_tmp_path": "/tmp2"
            }
reading {
                "tmp_path": "/tmp2",
                "archive_tmp_path": "/tmp2"
            }
thread 'archive::tests::test_archive_tar_archive_test2' panicked at 'Could not delete custom settings file under '/tmp/hvtools_custom_settings.json': No such file or directory (os error 2)', src/tests.rs:19:19

Как мы видим:

  • чтение файла в первый тест возвращает значение, которое записано во втором тесте
  • попытка удалить JSON файл во втором тесте не удалась (пока чтение работает)

Иногда оба теста читают записанное содержимое в первом тесте иногда первая попытка чтения возвращает пустую строку (результаты меняются без изменения кода):

running 2 tests
writing {
                "tmp_path": "/tmp1",
                "archive_tmp_path": "/tmp1"
            }
writing {
                "tmp_path": "/tmp2",
                "archive_tmp_path": "/tmp2"
            }
reading 
reading {
                "tmp_path": "/tmp2",
                "archive_tmp_path": "/tmp2"
            }

Это физическая файловая система (без общего доступа NFS или чего-то еще). Кроме того, в качестве примечания, если я перемещу содержимое второго теста в первый следующим образом:

fn test_archive_tar_archive_test1() {
    tests::create_custom_settings(
        r#"{
                "tmp_path": "/tmp1",
                "archive_tmp_path": "/tmp1"
            }"#,
    );
    println!(
        "reading {}",
        fs::read_to_string(tests::CUSTOM_SETTINGS_PATH).unwrap()
    );
    tests::delete_custom_settings();

    tests::create_custom_settings(
        r#"{
                "tmp_path": "/tmp2",
                "archive_tmp_path": "/tmp2"
            }"#,
    );

    println!(
        "reading {}",
        fs::read_to_string(tests::CUSTOM_SETTINGS_PATH).unwrap()
    );
    tests::delete_custom_settings();
}

, все будет работать, как ожидалось. Пытался добавить thread::sleep, похоже, результат не изменился.

Что я делаю не так?

1 Ответ

1 голос
/ 07 мая 2020

Тесты выполняются параллельно, поэтому вполне вероятно, что два теста, которые обращаются к одним и тем же путям, будут мешать друг другу. Чтобы предотвратить это, используйте разные пути в каждом тесте.

В качестве альтернативы вы можете принудительно запускать тесты последовательно, в одном потоке:

...