Skip to content

Commit

Permalink
fix(docker-tests): implement containers runtime directories (#2162)
Browse files Browse the repository at this point in the history
This commit introduces containers runtime directories for dockerized tests to ensure files consistency with each run and prevent local file changes with each test execution.
  • Loading branch information
shamardy authored Jul 12, 2024
1 parent aae70ee commit 2fa7153
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 32 deletions.
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,10 @@ MM2.json
[._]sw[a-p]

# mergetool
*.orig
*.orig

# Ignore containers runtime directories for dockerized tests
# This directory contains temporary data used by Docker containers during tests execution.
# It is recreated from container-state data each time test containers are started,
# and should not be tracked in version control.
.docker/container-runtime/
17 changes: 16 additions & 1 deletion mm2src/mm2_io/src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use serde::de::DeserializeOwned;
use serde::Serialize;
use serde_json::{self as json, Error as JsonError};
use std::ffi::OsStr;
use std::fs::{self, DirEntry};
use std::fs::{self, create_dir_all, DirEntry};
use std::io::{self, Read, Write};
use std::path::{Path, PathBuf};
use std::time::UNIX_EPOCH;
Expand Down Expand Up @@ -279,3 +279,18 @@ pub fn json_dir_entries(path: &dyn AsRef<Path>) -> Result<Vec<DirEntry>, String>
})
.collect())
}

/// Helper function to copy directories recursively
pub fn copy_dir_all(src: &dyn AsRef<Path>, dst: &dyn AsRef<Path>) -> io::Result<()> {
create_dir_all(dst)?;
for entry in fs::read_dir(src)? {
let entry = entry?;
let ty = entry.file_type()?;
if ty.is_dir() {
copy_dir_all(&entry.path(), &dst.as_ref().join(entry.file_name()))?;
} else {
std::fs::copy(entry.path(), dst.as_ref().join(entry.file_name()))?;
}
}
Ok(())
}
39 changes: 12 additions & 27 deletions mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,17 +352,12 @@ pub fn geth_docker_node<'a>(docker: &'a Cli, ticker: &'static str, port: u16) ->
}
}

pub fn nucleus_node(docker: &'_ Cli) -> DockerNode<'_> {
let nucleus_node_state_dir = {
let mut current_dir = std::env::current_dir().unwrap();
current_dir.pop();
current_dir.pop();
current_dir.join(".docker/container-state/nucleus-testnet-data")
};
assert!(nucleus_node_state_dir.exists());
pub fn nucleus_node(docker: &'_ Cli, runtime_dir: PathBuf) -> DockerNode<'_> {
let nucleus_node_runtime_dir = runtime_dir.join("nucleus-testnet-data");
assert!(nucleus_node_runtime_dir.exists());

let image = GenericImage::new(NUCLEUS_IMAGE, "latest")
.with_volume(nucleus_node_state_dir.to_str().unwrap(), "/root/.nucleus");
.with_volume(nucleus_node_runtime_dir.to_str().unwrap(), "/root/.nucleus");
let image = RunnableImage::from((image, vec![])).with_network("host");
let container = docker.run(image);

Expand All @@ -373,17 +368,12 @@ pub fn nucleus_node(docker: &'_ Cli) -> DockerNode<'_> {
}
}

pub fn atom_node(docker: &'_ Cli) -> DockerNode<'_> {
let atom_node_state_dir = {
let mut current_dir = std::env::current_dir().unwrap();
current_dir.pop();
current_dir.pop();
current_dir.join(".docker/container-state/atom-testnet-data")
};
assert!(atom_node_state_dir.exists());
pub fn atom_node(docker: &'_ Cli, runtime_dir: PathBuf) -> DockerNode<'_> {
let atom_node_runtime_dir = runtime_dir.join("atom-testnet-data");
assert!(atom_node_runtime_dir.exists());

let image =
GenericImage::new(ATOM_IMAGE, "latest").with_volume(atom_node_state_dir.to_str().unwrap(), "/root/.gaia");
GenericImage::new(ATOM_IMAGE, "latest").with_volume(atom_node_runtime_dir.to_str().unwrap(), "/root/.gaia");
let image = RunnableImage::from((image, vec![])).with_network("host");
let container = docker.run(image);

Expand All @@ -394,17 +384,12 @@ pub fn atom_node(docker: &'_ Cli) -> DockerNode<'_> {
}
}

pub fn ibc_relayer_node(docker: &'_ Cli) -> DockerNode<'_> {
let relayer_node_state_dir = {
let mut current_dir = std::env::current_dir().unwrap();
current_dir.pop();
current_dir.pop();
current_dir.join(".docker/container-state/ibc-relayer-data")
};
assert!(relayer_node_state_dir.exists());
pub fn ibc_relayer_node(docker: &'_ Cli, runtime_dir: PathBuf) -> DockerNode<'_> {
let relayer_node_runtime_dir = runtime_dir.join("ibc-relayer-data");
assert!(relayer_node_runtime_dir.exists());

let image = GenericImage::new(IBC_RELAYER_IMAGE, "latest")
.with_volume(relayer_node_state_dir.to_str().unwrap(), "/home/relayer/.relayer");
.with_volume(relayer_node_runtime_dir.to_str().unwrap(), "/home/relayer/.relayer");
let image = RunnableImage::from((image, vec![])).with_network("host");
let container = docker.run(image);

Expand Down
31 changes: 28 additions & 3 deletions mm2src/mm2_main/tests/docker_tests_main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ extern crate serde_json;

use std::env;
use std::io::{BufRead, BufReader};
use std::path::PathBuf;
use std::process::Command;
use test::{test_main, StaticBenchFn, StaticTestFn, TestDescAndFn};
use testcontainers::clients::Cli;
Expand Down Expand Up @@ -62,9 +63,11 @@ pub fn docker_tests_runner(tests: &[&TestDescAndFn]) {
remove_docker_containers(image);
}

let nucleus_node = nucleus_node(&docker);
let atom_node = atom_node(&docker);
let ibc_relayer_node = ibc_relayer_node(&docker);
let runtime_dir = prepare_runtime_dir().unwrap();

let nucleus_node = nucleus_node(&docker, runtime_dir.clone());
let atom_node = atom_node(&docker, runtime_dir.clone());
let ibc_relayer_node = ibc_relayer_node(&docker, runtime_dir);
let utxo_node = utxo_asset_docker_node(&docker, "MYCOIN", 7000);
let utxo_node1 = utxo_asset_docker_node(&docker, "MYCOIN1", 8000);
let qtum_node = qtum_docker_node(&docker, 9000);
Expand Down Expand Up @@ -143,3 +146,25 @@ fn remove_docker_containers(name: &str) {
.expect("Failed to execute docker command");
}
}
fn prepare_runtime_dir() -> std::io::Result<PathBuf> {
let project_root = {
let mut current_dir = std::env::current_dir().unwrap();
current_dir.pop();
current_dir.pop();
current_dir
};

let containers_state_dir = project_root.join(".docker/container-state");
assert!(containers_state_dir.exists());
let containers_runtime_dir = project_root.join(".docker/container-runtime");

// Remove runtime directory if it exists to copy containers files to a clean directory
if containers_runtime_dir.exists() {
std::fs::remove_dir_all(&containers_runtime_dir).unwrap();
}

// Copy container files to runtime directory
mm2_io::fs::copy_dir_all(&containers_state_dir, &containers_runtime_dir).unwrap();

Ok(containers_runtime_dir)
}

0 comments on commit 2fa7153

Please sign in to comment.