Skip to content

Commit

Permalink
Merge pull request #617 from near/phuong/feat/compile-time-node-builds
Browse files Browse the repository at this point in the history
feat: compile time binary builds for integration tests
  • Loading branch information
volovyks authored May 29, 2024
2 parents c7d6e6d + 3939d63 commit 3901486
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 78 deletions.
5 changes: 5 additions & 0 deletions integration-tests/chain-signatures/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ ethers-core = "2.0.13"
web3 = "0.19.0"
secp256k1 = "0.28.2"

[build-dependencies]
anyhow = "1"
async-process = "1"
tokio = { version = "1", features = ["full"] }

[workspace] # used to ignore higher level workspace

[features]
Expand Down
101 changes: 98 additions & 3 deletions integration-tests/chain-signatures/build.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,98 @@
// HACK: need this build script so that env var OUT_DIR gets set:
// https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates
fn main() {}
use std::path::Path;
use std::{env, io};

use anyhow::Context;
use async_process::{Command, ExitStatus, Stdio};

const PACKAGE_MULTICHAIN: &str = "mpc-recovery-node";
const PACKAGE_CONTRACT: &str = "mpc-contract";
const TARGET_CONTRACT: &str = "wasm32-unknown-unknown";
const TARGET_FOLDER: &str = "target";

fn target_dir() -> io::Result<std::path::PathBuf> {
let out_dir = env::var("OUT_DIR").map_err(|err| {
io::Error::new(
io::ErrorKind::NotFound,
format!("could not find OUT_DIR environment variable: {err:?}"),
)
})?;
let mut out_dir = Path::new(&out_dir);
loop {
if out_dir.ends_with(TARGET_FOLDER) {
break Ok(out_dir.to_path_buf());
}

match out_dir.parent() {
Some(parent) => out_dir = parent,
// We've reached the root directory and didn't find "target"
None => {
break Err(io::Error::new(
io::ErrorKind::NotFound,
"could not find /target",
))
}
}
}
}

async fn build_package(
release: bool,
package: &str,
target: Option<&str>,
target_dir: Option<impl AsRef<Path>>,
) -> anyhow::Result<ExitStatus> {
let mut cmd = Command::new("cargo");
cmd.arg("build")
.arg("--package")
.arg(package)
.envs(env::vars())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit());

if release {
cmd.arg("--release");
}

if let Some(target) = target {
cmd.arg("--target").arg(target);
}

if let Some(target_dir) = target_dir {
cmd.arg("--target-dir").arg(target_dir.as_ref().as_os_str());
}

Ok(cmd.spawn()?.status().await?)
}

async fn build_multichain(release: bool) -> anyhow::Result<ExitStatus> {
let target_dir = target_dir().context("could not find /target while building node")?;
build_package(release, PACKAGE_MULTICHAIN, None, Some(target_dir)).await
}

async fn build_multichain_contract(release: bool) -> anyhow::Result<ExitStatus> {
let target_dir = target_dir().context("could not find /target while building contract")?;
// We use a different target directory to stop the different rustflags between targets from clobbering the build cache
build_package(
release,
PACKAGE_CONTRACT,
Some(TARGET_CONTRACT),
Some(target_dir),
)
.await
}

fn main() -> anyhow::Result<()> {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=../../contract/");
println!("cargo:rerun-if-changed=../../keys/");
println!("cargo:rerun-if-changed=../../node/");

let release = true;
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async {
build_multichain_contract(release).await?;
build_multichain(release).await?;

Ok(())
})
}
61 changes: 2 additions & 59 deletions integration-tests/chain-signatures/src/execute.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
use std::path::Path;
use anyhow::Context;
use async_process::Child;

use anyhow::{anyhow, Context};
use async_process::{Child, Command, ExitStatus, Stdio};

const PACKAGE_CONTRACT: &str = "mpc-contract";
const PACKAGE_MULTICHAIN: &str = "mpc-recovery-node";
const TARGET_CONTRACT: &str = "wasm32-unknown-unknown";

pub fn target_dir() -> Option<std::path::PathBuf> {
let mut out_dir = std::path::Path::new(std::env!("OUT_DIR"));
Expand All @@ -21,59 +17,6 @@ pub fn target_dir() -> Option<std::path::PathBuf> {
}
}

async fn build_package(
release: bool,
package: &str,
target: Option<&str>,
target_dir: Option<impl AsRef<Path>>,
) -> anyhow::Result<ExitStatus> {
let mut cmd = Command::new("cargo");
cmd.arg("build")
.arg("--package")
.arg(package)
.envs(std::env::vars())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit());

if release {
cmd.arg("--release");
}

if let Some(target) = target {
cmd.arg("--target").arg(target);
}

if let Some(target_dir) = target_dir {
cmd.arg("--target-dir").arg(target_dir.as_ref().as_os_str());
}

Ok(cmd.spawn()?.status().await?)
}

pub async fn build_multichain(release: bool) -> anyhow::Result<ExitStatus> {
build_package(
release,
PACKAGE_MULTICHAIN,
None,
Some(target_dir().ok_or_else(|| anyhow!("could not find /target while building node"))?),
)
.await
}

pub async fn build_multichain_contract() -> anyhow::Result<ExitStatus> {
// We use a different target directory to stop the different rustflags between targets from clobbering the build cache
build_package(
true,
PACKAGE_CONTRACT,
Some(TARGET_CONTRACT),
Some(
target_dir()
.ok_or_else(|| anyhow!("could not find /target while building contract"))?,
),
)
.await
}

pub fn executable(release: bool, executable: &str) -> Option<std::path::PathBuf> {
let executable = target_dir()?
.join(if release { "release" } else { "debug" })
Expand Down
8 changes: 0 additions & 8 deletions integration-tests/chain-signatures/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,15 +230,7 @@ pub struct Context<'a> {
}

pub async fn setup(docker_client: &DockerClient) -> anyhow::Result<Context<'_>> {
if !execute::build_multichain_contract().await?.success() {
anyhow::bail!("failed to prebuild multichain contract");
}

let release = true;
if !execute::build_multichain(release).await?.success() {
anyhow::bail!("failed to prebuild multichain node service");
}

let docker_network = NETWORK;
docker_client.create_network(docker_network).await?;

Expand Down
5 changes: 5 additions & 0 deletions integration-tests/fastauth/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ mpc-recovery = { path = "../../mpc-recovery" }
[dev-dependencies]
test-log = { version = "0.2.12", features = ["log", "trace"] }

[build-dependencies]
anyhow = "1"
async-process = "1"
tokio = { version = "1", features = ["full"] }


[workspace] # used to ignore higher level workspace

Expand Down
85 changes: 82 additions & 3 deletions integration-tests/fastauth/build.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,82 @@
// HACK: need this build script so that env var OUT_DIR gets set:
// https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates
fn main() {}
use std::path::Path;
use std::{env, io};

use anyhow::Context;
use async_process::{Command, ExitStatus, Stdio};

const PACKAGE: &str = "mpc-recovery";
const TARGET_FOLDER: &str = "target";

fn target_dir() -> io::Result<std::path::PathBuf> {
let out_dir = env::var("OUT_DIR").map_err(|err| {
io::Error::new(
io::ErrorKind::NotFound,
format!("could not find OUT_DIR environment variable: {err:?}"),
)
})?;
let mut out_dir = Path::new(&out_dir);
loop {
if out_dir.ends_with(TARGET_FOLDER) {
break Ok(out_dir.to_path_buf());
}

match out_dir.parent() {
Some(parent) => out_dir = parent,
// We've reached the root directory and didn't find "target"
None => {
break Err(io::Error::new(
io::ErrorKind::NotFound,
"could not find /target",
))
}
}
}
}

async fn build_package(
release: bool,
package: &str,
target_dir: Option<impl AsRef<Path>>,
) -> anyhow::Result<ExitStatus> {
let mut cmd = Command::new("cargo");
cmd.arg("build")
.arg("--package")
.arg(package)
.envs(std::env::vars())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit());

if release {
cmd.arg("--release");
}

if let Some(target_dir) = target_dir {
cmd.arg("--target-dir").arg(target_dir.as_ref().as_os_str());
}

Ok(cmd.spawn()?.status().await?)
}

pub async fn build_mpc(release: bool) -> anyhow::Result<ExitStatus> {
build_package(
release,
PACKAGE,
Some(target_dir().context("could not find /target while building mpc-recovery")?),
)
.await
}

fn main() -> anyhow::Result<()> {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=../../mpc-recovery/");

#[cfg(not(feature = "flamegraph"))]
{
let release = true;
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async {
build_mpc(release).await?;
Ok(())
})
}
}
5 changes: 0 additions & 5 deletions integration-tests/fastauth/src/env/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,6 @@ pub struct Context<'a> {

pub async fn setup(docker_client: &DockerClient) -> anyhow::Result<Context<'_>> {
let release = true;
#[cfg(not(feature = "flamegraph"))]
if !crate::mpc::build(release).await?.success() {
anyhow::bail!("failed to prebuild MPC service");
}

let gcp_project_id = GCP_PROJECT_ID;
let docker_network = NETWORK;
docker_client.create_network(docker_network).await?;
Expand Down

0 comments on commit 3901486

Please sign in to comment.