fix: migrate vendor rustfmt.toml to stable-only features

- Update vendor/pezkuwi-zombienet-sdk/rustfmt.toml to stable-only
- Reformat 74 vendor files with stable rustfmt
- Remove nightly-only features causing CI failures
This commit is contained in:
2025-12-23 10:00:48 +03:00
parent 9bfa143337
commit ebd8fafdee
74 changed files with 19895 additions and 21681 deletions
@@ -11,14 +11,14 @@ pub const VALIDATION_CHECK: &str = "validation failed ";
pub const PREFIX_CANT_BE_NONE: &str = "name prefix can't be None if a value exists ";
pub const GRAPH_CONTAINS_NAME: &str =
"graph contains node name; we initialize it with all node names";
"graph contains node name; we initialize it with all node names";
pub const GRAPH_CONTAINS_DEP: &str = "graph contains dep_name; we filter out deps not contained in by_name and populate the graph with all nodes";
pub const INDEGREE_CONTAINS_NAME: &str =
"indegree contains node name; we initialize it with all node names";
"indegree contains node name; we initialize it with all node names";
pub const QUEUE_NOT_EMPTY: &str = "queue is not empty; we're looping over its length";
pub const THIS_IS_A_BUG: &str =
"- this is a bug please report it: https://github.com/paritytech/zombienet-sdk/issues";
"- this is a bug please report it: https://github.com/paritytech/zombienet-sdk/issues";
/// environment variable which can be used to override node spawn timeout
pub const ZOMBIE_NODE_SPAWN_TIMEOUT_SECONDS: &str = "ZOMBIE_NODE_SPAWN_TIMEOUT_SECONDS";
+33 -33
View File
@@ -10,51 +10,51 @@ pub mod local;
pub struct FileSystemError(#[from] anyhow::Error);
impl From<std::io::Error> for FileSystemError {
fn from(error: std::io::Error) -> Self {
Self(error.into())
}
fn from(error: std::io::Error) -> Self {
Self(error.into())
}
}
pub type FileSystemResult<T> = Result<T, FileSystemError>;
#[async_trait]
pub trait FileSystem {
async fn create_dir<P>(&self, path: P) -> FileSystemResult<()>
where
P: AsRef<Path> + Send;
async fn create_dir<P>(&self, path: P) -> FileSystemResult<()>
where
P: AsRef<Path> + Send;
async fn create_dir_all<P>(&self, path: P) -> FileSystemResult<()>
where
P: AsRef<Path> + Send;
async fn create_dir_all<P>(&self, path: P) -> FileSystemResult<()>
where
P: AsRef<Path> + Send;
async fn read<P>(&self, path: P) -> FileSystemResult<Vec<u8>>
where
P: AsRef<Path> + Send;
async fn read<P>(&self, path: P) -> FileSystemResult<Vec<u8>>
where
P: AsRef<Path> + Send;
async fn read_to_string<P>(&self, path: P) -> FileSystemResult<String>
where
P: AsRef<Path> + Send;
async fn read_to_string<P>(&self, path: P) -> FileSystemResult<String>
where
P: AsRef<Path> + Send;
async fn write<P, C>(&self, path: P, contents: C) -> FileSystemResult<()>
where
P: AsRef<Path> + Send,
C: AsRef<[u8]> + Send;
async fn write<P, C>(&self, path: P, contents: C) -> FileSystemResult<()>
where
P: AsRef<Path> + Send,
C: AsRef<[u8]> + Send;
async fn append<P, C>(&self, path: P, contents: C) -> FileSystemResult<()>
where
P: AsRef<Path> + Send,
C: AsRef<[u8]> + Send;
async fn append<P, C>(&self, path: P, contents: C) -> FileSystemResult<()>
where
P: AsRef<Path> + Send,
C: AsRef<[u8]> + Send;
async fn copy<P1, P2>(&self, from: P1, to: P2) -> FileSystemResult<()>
where
P1: AsRef<Path> + Send,
P2: AsRef<Path> + Send;
async fn copy<P1, P2>(&self, from: P1, to: P2) -> FileSystemResult<()>
where
P1: AsRef<Path> + Send,
P2: AsRef<Path> + Send;
async fn set_mode<P>(&self, path: P, perm: u32) -> FileSystemResult<()>
where
P: AsRef<Path> + Send;
async fn set_mode<P>(&self, path: P, perm: u32) -> FileSystemResult<()>
where
P: AsRef<Path> + Send;
async fn exists<P>(&self, path: P) -> bool
where
P: AsRef<Path> + Send;
async fn exists<P>(&self, path: P) -> bool
where
P: AsRef<Path> + Send;
}
File diff suppressed because it is too large Load Diff
+286 -299
View File
@@ -10,381 +10,368 @@ pub struct LocalFileSystem;
#[async_trait]
impl FileSystem for LocalFileSystem {
async fn create_dir<P>(&self, path: P) -> FileSystemResult<()>
where
P: AsRef<Path> + Send,
{
tokio::fs::create_dir(path).await.map_err(Into::into)
}
async fn create_dir<P>(&self, path: P) -> FileSystemResult<()>
where
P: AsRef<Path> + Send,
{
tokio::fs::create_dir(path).await.map_err(Into::into)
}
async fn create_dir_all<P>(&self, path: P) -> FileSystemResult<()>
where
P: AsRef<Path> + Send,
{
tokio::fs::create_dir_all(path).await.map_err(Into::into)
}
async fn create_dir_all<P>(&self, path: P) -> FileSystemResult<()>
where
P: AsRef<Path> + Send,
{
tokio::fs::create_dir_all(path).await.map_err(Into::into)
}
async fn read<P>(&self, path: P) -> FileSystemResult<Vec<u8>>
where
P: AsRef<Path> + Send,
{
tokio::fs::read(path).await.map_err(Into::into)
}
async fn read<P>(&self, path: P) -> FileSystemResult<Vec<u8>>
where
P: AsRef<Path> + Send,
{
tokio::fs::read(path).await.map_err(Into::into)
}
async fn read_to_string<P>(&self, path: P) -> FileSystemResult<String>
where
P: AsRef<Path> + Send,
{
tokio::fs::read_to_string(path).await.map_err(Into::into)
}
async fn read_to_string<P>(&self, path: P) -> FileSystemResult<String>
where
P: AsRef<Path> + Send,
{
tokio::fs::read_to_string(path).await.map_err(Into::into)
}
async fn write<P, C>(&self, path: P, contents: C) -> FileSystemResult<()>
where
P: AsRef<Path> + Send,
C: AsRef<[u8]> + Send,
{
tokio::fs::write(path, contents).await.map_err(Into::into)
}
async fn write<P, C>(&self, path: P, contents: C) -> FileSystemResult<()>
where
P: AsRef<Path> + Send,
C: AsRef<[u8]> + Send,
{
tokio::fs::write(path, contents).await.map_err(Into::into)
}
async fn append<P, C>(&self, path: P, contents: C) -> FileSystemResult<()>
where
P: AsRef<Path> + Send,
C: AsRef<[u8]> + Send,
{
let contents = contents.as_ref();
let mut file = tokio::fs::OpenOptions::new()
.create(true)
.append(true)
.open(path)
.await
.map_err(Into::<FileSystemError>::into)?;
async fn append<P, C>(&self, path: P, contents: C) -> FileSystemResult<()>
where
P: AsRef<Path> + Send,
C: AsRef<[u8]> + Send,
{
let contents = contents.as_ref();
let mut file = tokio::fs::OpenOptions::new()
.create(true)
.append(true)
.open(path)
.await
.map_err(Into::<FileSystemError>::into)?;
file.write_all(contents)
.await
.map_err(Into::<FileSystemError>::into)?;
file.write_all(contents).await.map_err(Into::<FileSystemError>::into)?;
file.flush().await.and(Ok(())).map_err(Into::into)
}
file.flush().await.and(Ok(())).map_err(Into::into)
}
async fn copy<P1, P2>(&self, from: P1, to: P2) -> FileSystemResult<()>
where
P1: AsRef<Path> + Send,
P2: AsRef<Path> + Send,
{
tokio::fs::copy(from, to)
.await
.and(Ok(()))
.map_err(Into::into)
}
async fn copy<P1, P2>(&self, from: P1, to: P2) -> FileSystemResult<()>
where
P1: AsRef<Path> + Send,
P2: AsRef<Path> + Send,
{
tokio::fs::copy(from, to).await.and(Ok(())).map_err(Into::into)
}
async fn set_mode<P>(&self, path: P, mode: u32) -> FileSystemResult<()>
where
P: AsRef<Path> + Send,
{
tokio::fs::set_permissions(path, Permissions::from_mode(mode))
.await
.map_err(Into::into)
}
async fn set_mode<P>(&self, path: P, mode: u32) -> FileSystemResult<()>
where
P: AsRef<Path> + Send,
{
tokio::fs::set_permissions(path, Permissions::from_mode(mode)).await.map_err(Into::into)
}
async fn exists<P>(&self, path: P) -> bool
where
P: AsRef<Path> + Send,
{
path.as_ref().exists()
}
async fn exists<P>(&self, path: P) -> bool
where
P: AsRef<Path> + Send,
{
path.as_ref().exists()
}
}
#[cfg(test)]
mod tests {
use uuid::Uuid;
use uuid::Uuid;
use super::*;
use super::*;
const FILE_BITS: u32 = 0o100000;
const DIR_BITS: u32 = 0o40000;
const FILE_BITS: u32 = 0o100000;
const DIR_BITS: u32 = 0o40000;
fn setup() -> String {
let test_dir = format!("/tmp/unit_test_{}", Uuid::new_v4());
std::fs::create_dir(&test_dir).unwrap();
test_dir
}
fn setup() -> String {
let test_dir = format!("/tmp/unit_test_{}", Uuid::new_v4());
std::fs::create_dir(&test_dir).unwrap();
test_dir
}
fn teardown(test_dir: String) {
std::fs::remove_dir_all(test_dir).unwrap();
}
fn teardown(test_dir: String) {
std::fs::remove_dir_all(test_dir).unwrap();
}
#[tokio::test]
async fn create_dir_should_create_a_new_directory_at_path() {
let test_dir = setup();
let fs = LocalFileSystem;
#[tokio::test]
async fn create_dir_should_create_a_new_directory_at_path() {
let test_dir = setup();
let fs = LocalFileSystem;
let new_dir = format!("{test_dir}/mynewdir");
fs.create_dir(&new_dir).await.unwrap();
let new_dir = format!("{test_dir}/mynewdir");
fs.create_dir(&new_dir).await.unwrap();
let new_dir_path = Path::new(&new_dir);
assert!(new_dir_path.exists() && new_dir_path.is_dir());
teardown(test_dir);
}
let new_dir_path = Path::new(&new_dir);
assert!(new_dir_path.exists() && new_dir_path.is_dir());
teardown(test_dir);
}
#[tokio::test]
async fn create_dir_should_bubble_up_error_if_some_happens() {
let test_dir = setup();
let fs = LocalFileSystem;
#[tokio::test]
async fn create_dir_should_bubble_up_error_if_some_happens() {
let test_dir = setup();
let fs = LocalFileSystem;
let new_dir = format!("{test_dir}/mynewdir");
// intentionally create new dir before calling function to force error
std::fs::create_dir(&new_dir).unwrap();
let err = fs.create_dir(&new_dir).await.unwrap_err();
let new_dir = format!("{test_dir}/mynewdir");
// intentionally create new dir before calling function to force error
std::fs::create_dir(&new_dir).unwrap();
let err = fs.create_dir(&new_dir).await.unwrap_err();
assert_eq!(err.to_string(), "File exists (os error 17)");
teardown(test_dir);
}
assert_eq!(err.to_string(), "File exists (os error 17)");
teardown(test_dir);
}
#[tokio::test]
async fn create_dir_all_should_create_a_new_directory_and_all_of_it_ancestors_at_path() {
let test_dir = setup();
let fs = LocalFileSystem;
#[tokio::test]
async fn create_dir_all_should_create_a_new_directory_and_all_of_it_ancestors_at_path() {
let test_dir = setup();
let fs = LocalFileSystem;
let new_dir = format!("{test_dir}/the/path/to/mynewdir");
fs.create_dir_all(&new_dir).await.unwrap();
let new_dir = format!("{test_dir}/the/path/to/mynewdir");
fs.create_dir_all(&new_dir).await.unwrap();
let new_dir_path = Path::new(&new_dir);
assert!(new_dir_path.exists() && new_dir_path.is_dir());
teardown(test_dir);
}
let new_dir_path = Path::new(&new_dir);
assert!(new_dir_path.exists() && new_dir_path.is_dir());
teardown(test_dir);
}
#[tokio::test]
async fn create_dir_all_should_bubble_up_error_if_some_happens() {
let test_dir = setup();
let fs = LocalFileSystem;
#[tokio::test]
async fn create_dir_all_should_bubble_up_error_if_some_happens() {
let test_dir = setup();
let fs = LocalFileSystem;
let new_dir = format!("{test_dir}/the/path/to/mynewdir");
// intentionally create new file as ancestor before calling function to force error
std::fs::write(format!("{test_dir}/the"), b"test").unwrap();
let err = fs.create_dir_all(&new_dir).await.unwrap_err();
let new_dir = format!("{test_dir}/the/path/to/mynewdir");
// intentionally create new file as ancestor before calling function to force error
std::fs::write(format!("{test_dir}/the"), b"test").unwrap();
let err = fs.create_dir_all(&new_dir).await.unwrap_err();
assert_eq!(err.to_string(), "Not a directory (os error 20)");
teardown(test_dir);
}
assert_eq!(err.to_string(), "Not a directory (os error 20)");
teardown(test_dir);
}
#[tokio::test]
async fn read_should_return_the_contents_of_the_file_at_path() {
let test_dir = setup();
let fs = LocalFileSystem;
#[tokio::test]
async fn read_should_return_the_contents_of_the_file_at_path() {
let test_dir = setup();
let fs = LocalFileSystem;
let file_path = format!("{test_dir}/myfile");
std::fs::write(&file_path, b"Test").unwrap();
let contents = fs.read(file_path).await.unwrap();
let file_path = format!("{test_dir}/myfile");
std::fs::write(&file_path, b"Test").unwrap();
let contents = fs.read(file_path).await.unwrap();
assert_eq!(contents, b"Test");
teardown(test_dir);
}
assert_eq!(contents, b"Test");
teardown(test_dir);
}
#[tokio::test]
async fn read_should_bubble_up_error_if_some_happens() {
let test_dir = setup();
let fs = LocalFileSystem;
#[tokio::test]
async fn read_should_bubble_up_error_if_some_happens() {
let test_dir = setup();
let fs = LocalFileSystem;
let file_path = format!("{test_dir}/myfile");
// intentionally forget to create file to force error
let err = fs.read(file_path).await.unwrap_err();
let file_path = format!("{test_dir}/myfile");
// intentionally forget to create file to force error
let err = fs.read(file_path).await.unwrap_err();
assert_eq!(err.to_string(), "No such file or directory (os error 2)");
teardown(test_dir);
}
assert_eq!(err.to_string(), "No such file or directory (os error 2)");
teardown(test_dir);
}
#[tokio::test]
async fn read_to_string_should_return_the_contents_of_the_file_at_path_as_string() {
let test_dir = setup();
let fs = LocalFileSystem;
#[tokio::test]
async fn read_to_string_should_return_the_contents_of_the_file_at_path_as_string() {
let test_dir = setup();
let fs = LocalFileSystem;
let file_path = format!("{test_dir}/myfile");
std::fs::write(&file_path, b"Test").unwrap();
let contents = fs.read_to_string(file_path).await.unwrap();
let file_path = format!("{test_dir}/myfile");
std::fs::write(&file_path, b"Test").unwrap();
let contents = fs.read_to_string(file_path).await.unwrap();
assert_eq!(contents, "Test");
teardown(test_dir);
}
assert_eq!(contents, "Test");
teardown(test_dir);
}
#[tokio::test]
async fn read_to_string_should_bubble_up_error_if_some_happens() {
let test_dir = setup();
let fs = LocalFileSystem;
#[tokio::test]
async fn read_to_string_should_bubble_up_error_if_some_happens() {
let test_dir = setup();
let fs = LocalFileSystem;
let file_path = format!("{test_dir}/myfile");
// intentionally forget to create file to force error
let err = fs.read_to_string(file_path).await.unwrap_err();
let file_path = format!("{test_dir}/myfile");
// intentionally forget to create file to force error
let err = fs.read_to_string(file_path).await.unwrap_err();
assert_eq!(err.to_string(), "No such file or directory (os error 2)");
teardown(test_dir);
}
assert_eq!(err.to_string(), "No such file or directory (os error 2)");
teardown(test_dir);
}
#[tokio::test]
async fn write_should_create_a_new_file_at_path_with_contents() {
let test_dir = setup();
let fs = LocalFileSystem;
#[tokio::test]
async fn write_should_create_a_new_file_at_path_with_contents() {
let test_dir = setup();
let fs = LocalFileSystem;
let file_path = format!("{test_dir}/myfile");
fs.write(&file_path, "Test").await.unwrap();
let file_path = format!("{test_dir}/myfile");
fs.write(&file_path, "Test").await.unwrap();
assert_eq!(std::fs::read_to_string(file_path).unwrap(), "Test");
teardown(test_dir);
}
assert_eq!(std::fs::read_to_string(file_path).unwrap(), "Test");
teardown(test_dir);
}
#[tokio::test]
async fn write_should_overwrite_an_existing_file_with_contents() {
let test_dir = setup();
let fs = LocalFileSystem;
#[tokio::test]
async fn write_should_overwrite_an_existing_file_with_contents() {
let test_dir = setup();
let fs = LocalFileSystem;
let file_path = format!("{test_dir}/myfile");
std::fs::write(&file_path, "Test").unwrap();
assert_eq!(std::fs::read_to_string(&file_path).unwrap(), "Test");
fs.write(&file_path, "Test updated").await.unwrap();
let file_path = format!("{test_dir}/myfile");
std::fs::write(&file_path, "Test").unwrap();
assert_eq!(std::fs::read_to_string(&file_path).unwrap(), "Test");
fs.write(&file_path, "Test updated").await.unwrap();
assert_eq!(std::fs::read_to_string(file_path).unwrap(), "Test updated");
teardown(test_dir);
}
assert_eq!(std::fs::read_to_string(file_path).unwrap(), "Test updated");
teardown(test_dir);
}
#[tokio::test]
async fn write_should_bubble_up_error_if_some_happens() {
let test_dir = setup();
let fs = LocalFileSystem;
#[tokio::test]
async fn write_should_bubble_up_error_if_some_happens() {
let test_dir = setup();
let fs = LocalFileSystem;
let file_path = format!("{test_dir}/myfile");
// intentionally create directory instead of file to force error
std::fs::create_dir(&file_path).unwrap();
let err = fs.write(&file_path, "Test").await.unwrap_err();
let file_path = format!("{test_dir}/myfile");
// intentionally create directory instead of file to force error
std::fs::create_dir(&file_path).unwrap();
let err = fs.write(&file_path, "Test").await.unwrap_err();
assert_eq!(err.to_string(), "Is a directory (os error 21)");
teardown(test_dir);
}
assert_eq!(err.to_string(), "Is a directory (os error 21)");
teardown(test_dir);
}
#[tokio::test]
async fn append_should_create_a_new_file_at_path_with_contents() {
let test_dir = setup();
let fs = LocalFileSystem;
#[tokio::test]
async fn append_should_create_a_new_file_at_path_with_contents() {
let test_dir = setup();
let fs = LocalFileSystem;
let file_path = format!("{test_dir}/myfile");
fs.append(&file_path, "Test").await.unwrap();
let file_path = format!("{test_dir}/myfile");
fs.append(&file_path, "Test").await.unwrap();
assert_eq!(std::fs::read_to_string(file_path).unwrap(), "Test");
teardown(test_dir);
}
assert_eq!(std::fs::read_to_string(file_path).unwrap(), "Test");
teardown(test_dir);
}
#[tokio::test]
async fn append_should_updates_an_existing_file_by_appending_contents() {
let test_dir = setup();
let fs = LocalFileSystem;
#[tokio::test]
async fn append_should_updates_an_existing_file_by_appending_contents() {
let test_dir = setup();
let fs = LocalFileSystem;
let file_path = format!("{test_dir}/myfile");
std::fs::write(&file_path, "Test").unwrap();
assert_eq!(std::fs::read_to_string(&file_path).unwrap(), "Test");
fs.append(&file_path, " updated").await.unwrap();
let file_path = format!("{test_dir}/myfile");
std::fs::write(&file_path, "Test").unwrap();
assert_eq!(std::fs::read_to_string(&file_path).unwrap(), "Test");
fs.append(&file_path, " updated").await.unwrap();
assert_eq!(std::fs::read_to_string(file_path).unwrap(), "Test updated");
teardown(test_dir);
}
assert_eq!(std::fs::read_to_string(file_path).unwrap(), "Test updated");
teardown(test_dir);
}
#[tokio::test]
async fn append_should_bubble_up_error_if_some_happens() {
let test_dir = setup();
let fs = LocalFileSystem;
#[tokio::test]
async fn append_should_bubble_up_error_if_some_happens() {
let test_dir = setup();
let fs = LocalFileSystem;
let file_path = format!("{test_dir}/myfile");
// intentionally create directory instead of file to force error
std::fs::create_dir(&file_path).unwrap();
let err = fs.append(&file_path, "Test").await.unwrap_err();
let file_path = format!("{test_dir}/myfile");
// intentionally create directory instead of file to force error
std::fs::create_dir(&file_path).unwrap();
let err = fs.append(&file_path, "Test").await.unwrap_err();
assert_eq!(err.to_string(), "Is a directory (os error 21)");
teardown(test_dir);
}
assert_eq!(err.to_string(), "Is a directory (os error 21)");
teardown(test_dir);
}
#[tokio::test]
async fn copy_should_create_a_duplicate_of_source() {
let test_dir = setup();
let fs = LocalFileSystem;
#[tokio::test]
async fn copy_should_create_a_duplicate_of_source() {
let test_dir = setup();
let fs = LocalFileSystem;
let from_path = format!("{test_dir}/myfile");
std::fs::write(&from_path, "Test").unwrap();
let to_path = format!("{test_dir}/mycopy");
fs.copy(&from_path, &to_path).await.unwrap();
let from_path = format!("{test_dir}/myfile");
std::fs::write(&from_path, "Test").unwrap();
let to_path = format!("{test_dir}/mycopy");
fs.copy(&from_path, &to_path).await.unwrap();
assert_eq!(std::fs::read_to_string(to_path).unwrap(), "Test");
teardown(test_dir);
}
assert_eq!(std::fs::read_to_string(to_path).unwrap(), "Test");
teardown(test_dir);
}
#[tokio::test]
async fn copy_should_ovewrite_destination_if_alread_exists() {
let test_dir = setup();
let fs = LocalFileSystem;
#[tokio::test]
async fn copy_should_ovewrite_destination_if_alread_exists() {
let test_dir = setup();
let fs = LocalFileSystem;
let from_path = format!("{test_dir}/myfile");
std::fs::write(&from_path, "Test").unwrap();
let to_path = format!("{test_dir}/mycopy");
std::fs::write(&from_path, "Some content").unwrap();
fs.copy(&from_path, &to_path).await.unwrap();
let from_path = format!("{test_dir}/myfile");
std::fs::write(&from_path, "Test").unwrap();
let to_path = format!("{test_dir}/mycopy");
std::fs::write(&from_path, "Some content").unwrap();
fs.copy(&from_path, &to_path).await.unwrap();
assert_eq!(std::fs::read_to_string(to_path).unwrap(), "Some content");
teardown(test_dir);
}
assert_eq!(std::fs::read_to_string(to_path).unwrap(), "Some content");
teardown(test_dir);
}
#[tokio::test]
async fn copy_should_bubble_up_error_if_some_happens() {
let test_dir = setup();
let fs = LocalFileSystem;
#[tokio::test]
async fn copy_should_bubble_up_error_if_some_happens() {
let test_dir = setup();
let fs = LocalFileSystem;
let from_path = format!("{test_dir}/nonexistentfile");
let to_path = format!("{test_dir}/mycopy");
let err = fs.copy(&from_path, &to_path).await.unwrap_err();
let from_path = format!("{test_dir}/nonexistentfile");
let to_path = format!("{test_dir}/mycopy");
let err = fs.copy(&from_path, &to_path).await.unwrap_err();
assert_eq!(err.to_string(), "No such file or directory (os error 2)");
teardown(test_dir);
}
assert_eq!(err.to_string(), "No such file or directory (os error 2)");
teardown(test_dir);
}
#[tokio::test]
async fn set_mode_should_update_the_file_mode_at_path() {
let test_dir = setup();
let fs = LocalFileSystem;
let path = format!("{test_dir}/myfile");
std::fs::write(&path, "Test").unwrap();
assert!(std::fs::metadata(&path).unwrap().permissions().mode() != (FILE_BITS + 0o400));
#[tokio::test]
async fn set_mode_should_update_the_file_mode_at_path() {
let test_dir = setup();
let fs = LocalFileSystem;
let path = format!("{test_dir}/myfile");
std::fs::write(&path, "Test").unwrap();
assert!(std::fs::metadata(&path).unwrap().permissions().mode() != (FILE_BITS + 0o400));
fs.set_mode(&path, 0o400).await.unwrap();
fs.set_mode(&path, 0o400).await.unwrap();
assert_eq!(
std::fs::metadata(&path).unwrap().permissions().mode(),
FILE_BITS + 0o400
);
teardown(test_dir);
}
assert_eq!(std::fs::metadata(&path).unwrap().permissions().mode(), FILE_BITS + 0o400);
teardown(test_dir);
}
#[tokio::test]
async fn set_mode_should_update_the_directory_mode_at_path() {
let test_dir = setup();
let fs = LocalFileSystem;
let path = format!("{test_dir}/mydir");
std::fs::create_dir(&path).unwrap();
assert!(std::fs::metadata(&path).unwrap().permissions().mode() != (DIR_BITS + 0o700));
#[tokio::test]
async fn set_mode_should_update_the_directory_mode_at_path() {
let test_dir = setup();
let fs = LocalFileSystem;
let path = format!("{test_dir}/mydir");
std::fs::create_dir(&path).unwrap();
assert!(std::fs::metadata(&path).unwrap().permissions().mode() != (DIR_BITS + 0o700));
fs.set_mode(&path, 0o700).await.unwrap();
fs.set_mode(&path, 0o700).await.unwrap();
assert_eq!(
std::fs::metadata(&path).unwrap().permissions().mode(),
DIR_BITS + 0o700
);
teardown(test_dir);
}
assert_eq!(std::fs::metadata(&path).unwrap().permissions().mode(), DIR_BITS + 0o700);
teardown(test_dir);
}
#[tokio::test]
async fn set_mode_should_bubble_up_error_if_some_happens() {
let test_dir = setup();
let fs = LocalFileSystem;
let path = format!("{test_dir}/somemissingfile");
// intentionnally don't create file
#[tokio::test]
async fn set_mode_should_bubble_up_error_if_some_happens() {
let test_dir = setup();
let fs = LocalFileSystem;
let path = format!("{test_dir}/somemissingfile");
// intentionnally don't create file
let err = fs.set_mode(&path, 0o400).await.unwrap_err();
let err = fs.set_mode(&path, 0o400).await.unwrap_err();
assert_eq!(err.to_string(), "No such file or directory (os error 2)");
teardown(test_dir);
}
assert_eq!(err.to_string(), "No such file or directory (os error 2)");
teardown(test_dir);
}
}
+38 -38
View File
@@ -8,53 +8,53 @@ use crate::constants::THIS_IS_A_BUG;
type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
pub async fn download_file(url: String, dest: String) -> Result<()> {
let response = reqwest::get(url).await?;
let mut file = std::fs::File::create(dest)?;
let mut content = Cursor::new(response.bytes().await?);
std::io::copy(&mut content, &mut file)?;
Ok(())
let response = reqwest::get(url).await?;
let mut file = std::fs::File::create(dest)?;
let mut content = Cursor::new(response.bytes().await?);
std::io::copy(&mut content, &mut file)?;
Ok(())
}
pub async fn wait_ws_ready(url: &str) -> Result<()> {
let mut parsed = Url::from_str(url)?;
parsed
.set_scheme("http")
.map_err(|_| anyhow::anyhow!("Can not set the scheme, {THIS_IS_A_BUG}"))?;
let mut parsed = Url::from_str(url)?;
parsed
.set_scheme("http")
.map_err(|_| anyhow::anyhow!("Can not set the scheme, {THIS_IS_A_BUG}"))?;
let http_client = reqwest::Client::new();
loop {
let req = Request::new(Method::OPTIONS, parsed.clone());
let res = http_client.execute(req).await;
match res {
Ok(res) => {
if res.status() == StatusCode::OK {
// ready to go!
break;
}
let http_client = reqwest::Client::new();
loop {
let req = Request::new(Method::OPTIONS, parsed.clone());
let res = http_client.execute(req).await;
match res {
Ok(res) => {
if res.status() == StatusCode::OK {
// ready to go!
break;
}
trace!("http_client status: {}, continuing...", res.status());
},
Err(e) => {
if !skip_err_while_waiting(&e) {
return Err(e.into());
}
trace!("http_client status: {}, continuing...", res.status());
},
Err(e) => {
if !skip_err_while_waiting(&e) {
return Err(e.into());
}
trace!("http_client err: {}, continuing... ", e.to_string());
},
}
trace!("http_client err: {}, continuing... ", e.to_string());
},
}
tokio::time::sleep(Duration::from_secs(1)).await;
}
tokio::time::sleep(Duration::from_secs(1)).await;
}
Ok(())
Ok(())
}
pub fn skip_err_while_waiting(e: &reqwest::Error) -> bool {
// if the error is connecting/request could be the case that the node
// is not listening yet, so we keep waiting
// Skipped errs like:
// 'tcp connect error: Connection refused (os error 61)'
// 'operation was canceled: connection closed before message completed'
// 'connection error: Connection reset by peer (os error 54)'
e.is_connect() || e.is_request()
// if the error is connecting/request could be the case that the node
// is not listening yet, so we keep waiting
// Skipped errs like:
// 'tcp connect error: Connection refused (os error 61)'
// 'operation was canceled: connection closed before message completed'
// 'connection error: Connection reset by peer (os error 54)'
e.is_connect() || e.is_request()
}
+138 -140
View File
@@ -7,191 +7,189 @@ use tracing::{trace, warn};
use crate::constants::{SHOULD_COMPILE, THIS_IS_A_BUG};
lazy_static! {
static ref RE: Regex = Regex::new(r#"\{\{([a-zA-Z0-9_]*)\}\}"#)
.unwrap_or_else(|_| panic!("{SHOULD_COMPILE}, {THIS_IS_A_BUG}"));
static ref TOKEN_PLACEHOLDER: Regex = Regex::new(r#"\{\{ZOMBIE:(.*?):(.*?)\}\}"#)
.unwrap_or_else(|_| panic!("{SHOULD_COMPILE}, {THIS_IS_A_BUG}"));
static ref PLACEHOLDER_COMPAT: HashMap<&'static str, &'static str> = {
let mut m = HashMap::new();
m.insert("multiAddress", "multiaddr");
m.insert("wsUri", "ws_uri");
m.insert("prometheusUri", "prometheus_uri");
static ref RE: Regex = Regex::new(r#"\{\{([a-zA-Z0-9_]*)\}\}"#)
.unwrap_or_else(|_| panic!("{SHOULD_COMPILE}, {THIS_IS_A_BUG}"));
static ref TOKEN_PLACEHOLDER: Regex = Regex::new(r#"\{\{ZOMBIE:(.*?):(.*?)\}\}"#)
.unwrap_or_else(|_| panic!("{SHOULD_COMPILE}, {THIS_IS_A_BUG}"));
static ref PLACEHOLDER_COMPAT: HashMap<&'static str, &'static str> = {
let mut m = HashMap::new();
m.insert("multiAddress", "multiaddr");
m.insert("wsUri", "ws_uri");
m.insert("prometheusUri", "prometheus_uri");
m
};
m
};
}
/// Return true if the text contains any TOKEN_PLACEHOLDER
pub fn has_tokens(text: &str) -> bool {
TOKEN_PLACEHOLDER.is_match(text)
TOKEN_PLACEHOLDER.is_match(text)
}
pub fn apply_replacements(text: &str, replacements: &HashMap<&str, &str>) -> String {
let augmented_text = RE.replace_all(text, |caps: &Captures| {
if let Some(replacements_value) = replacements.get(&caps[1]) {
replacements_value.to_string()
} else {
caps[0].to_string()
}
});
let augmented_text = RE.replace_all(text, |caps: &Captures| {
if let Some(replacements_value) = replacements.get(&caps[1]) {
replacements_value.to_string()
} else {
caps[0].to_string()
}
});
augmented_text.to_string()
augmented_text.to_string()
}
pub fn apply_env_replacements(text: &str) -> String {
let augmented_text = RE.replace_all(text, |caps: &Captures| {
if let Ok(replacements_value) = std::env::var(&caps[1]) {
replacements_value
} else {
caps[0].to_string()
}
});
let augmented_text = RE.replace_all(text, |caps: &Captures| {
if let Ok(replacements_value) = std::env::var(&caps[1]) {
replacements_value
} else {
caps[0].to_string()
}
});
augmented_text.to_string()
augmented_text.to_string()
}
pub fn apply_running_network_replacements(text: &str, network: &serde_json::Value) -> String {
let augmented_text = TOKEN_PLACEHOLDER.replace_all(text, |caps: &Captures| {
trace!("appling replacements for caps: {caps:#?}");
if let Some(node) = network.get(&caps[1]) {
trace!("caps1 {} - node: {node}", &caps[1]);
let field = *PLACEHOLDER_COMPAT.get(&caps[2]).unwrap_or(&&caps[2]);
if let Some(val) = node.get(field) {
trace!("caps2 {} - node: {node}", field);
val.as_str().unwrap_or("Invalid string").to_string()
} else {
warn!(
"⚠️ The node with name {} doesn't have the value {} in context",
&caps[1], &caps[2]
);
caps[0].to_string()
}
} else {
warn!("⚠️ No node with name {} in context", &caps[1]);
caps[0].to_string()
}
});
let augmented_text = TOKEN_PLACEHOLDER.replace_all(text, |caps: &Captures| {
trace!("appling replacements for caps: {caps:#?}");
if let Some(node) = network.get(&caps[1]) {
trace!("caps1 {} - node: {node}", &caps[1]);
let field = *PLACEHOLDER_COMPAT.get(&caps[2]).unwrap_or(&&caps[2]);
if let Some(val) = node.get(field) {
trace!("caps2 {} - node: {node}", field);
val.as_str().unwrap_or("Invalid string").to_string()
} else {
warn!(
"⚠️ The node with name {} doesn't have the value {} in context",
&caps[1], &caps[2]
);
caps[0].to_string()
}
} else {
warn!("⚠️ No node with name {} in context", &caps[1]);
caps[0].to_string()
}
});
augmented_text.to_string()
augmented_text.to_string()
}
pub fn get_tokens_to_replace(text: &str) -> HashSet<String> {
let mut tokens = HashSet::new();
let mut tokens = HashSet::new();
TOKEN_PLACEHOLDER
.captures_iter(text)
.for_each(|caps: Captures| {
tokens.insert(caps[1].to_string());
});
TOKEN_PLACEHOLDER.captures_iter(text).for_each(|caps: Captures| {
tokens.insert(caps[1].to_string());
});
tokens
tokens
}
#[cfg(test)]
mod tests {
use serde_json::json;
use serde_json::json;
use super::*;
use super::*;
#[test]
fn replace_should_works() {
let text = "some {{namespace}}";
let mut replacements = HashMap::new();
replacements.insert("namespace", "demo-123");
let res = apply_replacements(text, &replacements);
assert_eq!("some demo-123".to_string(), res);
}
#[test]
fn replace_should_works() {
let text = "some {{namespace}}";
let mut replacements = HashMap::new();
replacements.insert("namespace", "demo-123");
let res = apply_replacements(text, &replacements);
assert_eq!("some demo-123".to_string(), res);
}
#[test]
fn replace_env_should_works() {
let text = "some {{namespace}}";
std::env::set_var("namespace", "demo-123");
// let mut replacements = HashMap::new();
// replacements.insert("namespace", "demo-123");
let res = apply_env_replacements(text);
assert_eq!("some demo-123".to_string(), res);
}
#[test]
fn replace_env_should_works() {
let text = "some {{namespace}}";
std::env::set_var("namespace", "demo-123");
// let mut replacements = HashMap::new();
// replacements.insert("namespace", "demo-123");
let res = apply_env_replacements(text);
assert_eq!("some demo-123".to_string(), res);
}
#[test]
fn replace_multiple_should_works() {
let text = r#"some {{namespace}}
#[test]
fn replace_multiple_should_works() {
let text = r#"some {{namespace}}
other is {{other}}"#;
let augmented_text = r#"some demo-123
let augmented_text = r#"some demo-123
other is other-123"#;
let mut replacements = HashMap::new();
replacements.insert("namespace", "demo-123");
replacements.insert("other", "other-123");
let res = apply_replacements(text, &replacements);
assert_eq!(augmented_text, res);
}
let mut replacements = HashMap::new();
replacements.insert("namespace", "demo-123");
replacements.insert("other", "other-123");
let res = apply_replacements(text, &replacements);
assert_eq!(augmented_text, res);
}
#[test]
fn replace_multiple_with_missing_should_works() {
let text = r#"some {{namespace}}
#[test]
fn replace_multiple_with_missing_should_works() {
let text = r#"some {{namespace}}
other is {{other}}"#;
let augmented_text = r#"some demo-123
let augmented_text = r#"some demo-123
other is {{other}}"#;
let mut replacements = HashMap::new();
replacements.insert("namespace", "demo-123");
let mut replacements = HashMap::new();
replacements.insert("namespace", "demo-123");
let res = apply_replacements(text, &replacements);
assert_eq!(augmented_text, res);
}
let res = apply_replacements(text, &replacements);
assert_eq!(augmented_text, res);
}
#[test]
fn replace_without_replacement_should_leave_text_unchanged() {
let text = "some {{namespace}}";
let mut replacements = HashMap::new();
replacements.insert("other", "demo-123");
let res = apply_replacements(text, &replacements);
assert_eq!(text.to_string(), res);
}
#[test]
fn replace_without_replacement_should_leave_text_unchanged() {
let text = "some {{namespace}}";
let mut replacements = HashMap::new();
replacements.insert("other", "demo-123");
let res = apply_replacements(text, &replacements);
assert_eq!(text.to_string(), res);
}
#[test]
fn replace_running_network_should_work() {
let network = json!({
"alice" : {
"multiaddr": "some/demo/127.0.0.1"
}
});
#[test]
fn replace_running_network_should_work() {
let network = json!({
"alice" : {
"multiaddr": "some/demo/127.0.0.1"
}
});
let res = apply_running_network_replacements("{{ZOMBIE:alice:multiaddr}}", &network);
assert_eq!(res.as_str(), "some/demo/127.0.0.1");
}
let res = apply_running_network_replacements("{{ZOMBIE:alice:multiaddr}}", &network);
assert_eq!(res.as_str(), "some/demo/127.0.0.1");
}
#[test]
fn replace_running_network_with_compat_should_work() {
let network = json!({
"alice" : {
"multiaddr": "some/demo/127.0.0.1"
}
});
#[test]
fn replace_running_network_with_compat_should_work() {
let network = json!({
"alice" : {
"multiaddr": "some/demo/127.0.0.1"
}
});
let res = apply_running_network_replacements("{{ZOMBIE:alice:multiAddress}}", &network);
assert_eq!(res.as_str(), "some/demo/127.0.0.1");
}
let res = apply_running_network_replacements("{{ZOMBIE:alice:multiAddress}}", &network);
assert_eq!(res.as_str(), "some/demo/127.0.0.1");
}
#[test]
fn replace_running_network_with_missing_field_should_not_replace_nothing() {
let network = json!({
"alice" : {
"multiaddr": "some/demo/127.0.0.1"
}
});
#[test]
fn replace_running_network_with_missing_field_should_not_replace_nothing() {
let network = json!({
"alice" : {
"multiaddr": "some/demo/127.0.0.1"
}
});
let res = apply_running_network_replacements("{{ZOMBIE:alice:someField}}", &network);
assert_eq!(res.as_str(), "{{ZOMBIE:alice:someField}}");
}
let res = apply_running_network_replacements("{{ZOMBIE:alice:someField}}", &network);
assert_eq!(res.as_str(), "{{ZOMBIE:alice:someField}}");
}
#[test]
fn get_tokens_to_replace_should_work() {
let res = get_tokens_to_replace("{{ZOMBIE:alice:multiaddr}} {{ZOMBIE:bob:multiaddr}}");
let mut expected = HashSet::new();
expected.insert("alice".to_string());
expected.insert("bob".to_string());
#[test]
fn get_tokens_to_replace_should_work() {
let res = get_tokens_to_replace("{{ZOMBIE:alice:multiaddr}} {{ZOMBIE:bob:multiaddr}}");
let mut expected = HashSet::new();
expected.insert("alice".to_string());
expected.insert("bob".to_string());
assert_eq!(res, expected);
}
assert_eq!(res, expected);
}
}