deb: fix concurrent testing (by making them serial)
All checks were successful
CI / build (push) Successful in 8m34s
All checks were successful
CI / build (push) Successful in 8m34s
Co-authored-by: Valentin Haudiquet <valentin.haudiquet@canonical.com> Co-committed-by: Valentin Haudiquet <valentin.haudiquet@canonical.com>
This commit was merged in pull request #2.
This commit is contained in:
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -2,7 +2,7 @@ name: CI
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "ci-test" ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ "main" ]
|
branches: [ "main" ]
|
||||||
|
|
||||||
|
|||||||
@@ -27,8 +27,9 @@ xz2 = "0.1"
|
|||||||
serde_json = "1.0.145"
|
serde_json = "1.0.145"
|
||||||
directories = "6.0.0"
|
directories = "6.0.0"
|
||||||
ssh2 = "0.9.5"
|
ssh2 = "0.9.5"
|
||||||
tempfile = "3.10.1"
|
|
||||||
gpgme = "0.11"
|
gpgme = "0.11"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
test-log = "0.2.19"
|
test-log = "0.2.19"
|
||||||
|
serial_test = "3.3.1"
|
||||||
|
tempfile = "3.10.1"
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use super::api::ContextDriver;
|
|||||||
use std::io;
|
use std::io;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
use std::time::SystemTime;
|
||||||
|
|
||||||
pub struct LocalDriver;
|
pub struct LocalDriver;
|
||||||
|
|
||||||
@@ -20,8 +21,34 @@ impl ContextDriver for LocalDriver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn create_temp_dir(&self) -> io::Result<String> {
|
fn create_temp_dir(&self) -> io::Result<String> {
|
||||||
let temp_dir = tempfile::Builder::new().prefix("pkh-").tempdir()?;
|
// Generate a unique temporary directory name with random string
|
||||||
Ok(temp_dir.keep().to_string_lossy().to_string())
|
let base_timestamp = SystemTime::now()
|
||||||
|
.duration_since(SystemTime::UNIX_EPOCH)
|
||||||
|
.unwrap()
|
||||||
|
.as_secs();
|
||||||
|
|
||||||
|
let mut attempt = 0;
|
||||||
|
loop {
|
||||||
|
let work_dir_name = if attempt == 0 {
|
||||||
|
format!("pkh-{}", base_timestamp)
|
||||||
|
} else {
|
||||||
|
format!("pkh-{}-{}", base_timestamp, attempt)
|
||||||
|
};
|
||||||
|
|
||||||
|
let temp_dir_path = std::env::temp_dir().join(&work_dir_name);
|
||||||
|
|
||||||
|
// Check if directory already exists
|
||||||
|
if temp_dir_path.exists() {
|
||||||
|
attempt += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the directory
|
||||||
|
std::fs::create_dir_all(&temp_dir_path)?;
|
||||||
|
|
||||||
|
// Return the path as a string
|
||||||
|
return Ok(temp_dir_path.to_string_lossy().to_string());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn retrieve_path(&self, src: &Path, dest: &Path) -> io::Result<()> {
|
fn retrieve_path(&self, src: &Path, dest: &Path) -> io::Result<()> {
|
||||||
|
|||||||
@@ -112,27 +112,41 @@ impl ContextDriver for UnshareDriver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn create_temp_dir(&self) -> io::Result<String> {
|
fn create_temp_dir(&self) -> io::Result<String> {
|
||||||
// Create a temporary directory inside the chroot
|
// Create a temporary directory inside the chroot with unique naming
|
||||||
let timestamp = std::time::SystemTime::now()
|
let base_timestamp = std::time::SystemTime::now()
|
||||||
.duration_since(std::time::UNIX_EPOCH)
|
.duration_since(std::time::UNIX_EPOCH)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_secs();
|
.as_secs();
|
||||||
|
|
||||||
let work_dir_name = format!("pkh-build-{}", timestamp);
|
let mut attempt = 0;
|
||||||
let work_dir_inside_chroot = format!("/tmp/{}", work_dir_name);
|
loop {
|
||||||
|
let work_dir_name = if attempt == 0 {
|
||||||
|
format!("pkh-build-{}", base_timestamp)
|
||||||
|
} else {
|
||||||
|
format!("pkh-build-{}-{}", base_timestamp, attempt)
|
||||||
|
};
|
||||||
|
|
||||||
// Create the directory on the host filesystem
|
let work_dir_inside_chroot = format!("/tmp/{}", work_dir_name);
|
||||||
let host_path = Path::new(&self.path).join("tmp").join(&work_dir_name);
|
let host_path = Path::new(&self.path).join("tmp").join(&work_dir_name);
|
||||||
std::fs::create_dir_all(&host_path)?;
|
|
||||||
|
|
||||||
debug!(
|
// Check if directory already exists
|
||||||
"Created work directory: {} (host: {})",
|
if host_path.exists() {
|
||||||
work_dir_inside_chroot,
|
attempt += 1;
|
||||||
host_path.display()
|
continue;
|
||||||
);
|
}
|
||||||
|
|
||||||
// Return the path as it appears inside the chroot
|
// Create the directory on the host filesystem
|
||||||
Ok(work_dir_inside_chroot)
|
std::fs::create_dir_all(&host_path)?;
|
||||||
|
|
||||||
|
debug!(
|
||||||
|
"Created work directory: {} (host: {})",
|
||||||
|
work_dir_inside_chroot,
|
||||||
|
host_path.display()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Return the path as it appears inside the chroot
|
||||||
|
return Ok(work_dir_inside_chroot);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copy_path(&self, src: &Path, dest: &Path) -> io::Result<()> {
|
fn copy_path(&self, src: &Path, dest: &Path) -> io::Result<()> {
|
||||||
|
|||||||
@@ -105,6 +105,7 @@ fn find_dsc_file(
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use serial_test::serial;
|
||||||
async fn test_build_end_to_end(
|
async fn test_build_end_to_end(
|
||||||
package: &str,
|
package: &str,
|
||||||
series: &str,
|
series: &str,
|
||||||
@@ -159,8 +160,16 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests below will be marked 'serial'
|
||||||
|
// As builds are using ephemeral contexts, tests running on the same
|
||||||
|
// process could use the ephemeral context of another thread and
|
||||||
|
// interfere with each other.
|
||||||
|
// FIXME: This is not ideal. In the future, we might want to
|
||||||
|
// either explicitely pass context (instead of shared state) or
|
||||||
|
// fork for building?
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[test_log::test]
|
#[test_log::test]
|
||||||
|
#[serial]
|
||||||
async fn test_deb_hello_ubuntu_end_to_end() {
|
async fn test_deb_hello_ubuntu_end_to_end() {
|
||||||
test_build_end_to_end("hello", "noble", None, None, false).await;
|
test_build_end_to_end("hello", "noble", None, None, false).await;
|
||||||
}
|
}
|
||||||
@@ -168,6 +177,7 @@ mod tests {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[test_log::test]
|
#[test_log::test]
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
#[serial]
|
||||||
async fn test_deb_hello_ubuntu_cross_end_to_end() {
|
async fn test_deb_hello_ubuntu_cross_end_to_end() {
|
||||||
test_build_end_to_end("hello", "noble", None, Some("riscv64"), true).await;
|
test_build_end_to_end("hello", "noble", None, Some("riscv64"), true).await;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user