Skip to content

Commit

Permalink
test: add test of cargo test on cargo near new result
Browse files Browse the repository at this point in the history
  • Loading branch information
dj8yf0μl committed Oct 23, 2024
1 parent 3d76a76 commit d6fa2f6
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 61 deletions.
128 changes: 71 additions & 57 deletions integration-tests/tests/cargo_near_new.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
use std::process::{Command, Stdio};

use camino::Utf8PathBuf;
use serde_json::json;
mod crate_metadata;
mod toolchain_channels;

/// This tests logic of `../../cargo-near/src/commands/new/new-project-template/tests/test_basics.rs`,
/// on contract, which is docker-built from project, generated by `cargo near new`
#[cfg(target_os = "linux")]
#[tokio::test]
async fn test_docker_build() -> Result<(), Box<dyn std::error::Error>> {
use cargo_near_integration_tests::setup_tracing;

setup_tracing();

let generated_manifest = {
let generated_dir = run_cargo_near_new()?;
generated_dir.join("Cargo.toml")
};
assert_new_cmd_workspaces_version_equal_to_test(&generated_manifest)?;
let generated_manifest = run_cargo_near_new()?;
crate_metadata::assert_versions_equal(
&tests_manifest(),
&generated_manifest,
"near_workspaces",
)?;

let opts = cargo_near_build::docker::DockerBuildOpts::builder()
.manifest_path(generated_manifest.clone())
Expand All @@ -35,66 +43,61 @@ async fn test_docker_build() -> Result<(), Box<dyn std::error::Error>> {

include! {"../../cargo-near/src/commands/new/test_basics_on.rs.in"}

fn extract_locked_workspaces_version(
manifest_path: &camino::Utf8PathBuf,
package_name: &str,
) -> color_eyre::Result<semver::Version> {
let meta =
cargo_near_build::CrateMetadata::collect(manifest_path.clone().try_into()?, false, None)?;
#[tokio::test]
/// This runs `cargo test` on project, generated by `cargo near new`
async fn test_cargo_test_on_generated_project() -> Result<(), Box<dyn std::error::Error>> {
use cargo_near_integration_tests::setup_tracing;

setup_tracing();

let package = meta.find_dependency(package_name)?;
let generated_manifest = run_cargo_near_new()?;

Ok(package.version.clone())
}
toolchain_channels::assert_equal(
&tests_toolchain(),
&generated_manifest
.parent()
.expect("has a parent")
.join("rust-toolchain.toml"),
)?;

/// This asserts sync of versions in lock-file of `cargo-near-integration-tests` and
/// `cargo near new` generated template
fn assert_new_cmd_workspaces_version_equal_to_test(
generated_manifest: &camino::Utf8PathBuf,
) -> cargo_near::CliResult {
let tests_manifest = {
let cargo_near_integration_tests_dir: camino::Utf8PathBuf =
env!("CARGO_MANIFEST_DIR").into();
cargo_near_integration_tests_dir.join("Cargo.toml")
// somehow `rustup` doesn't respect `rust-toolchain.toml` in
// the target generated dir
let mut cmd = Command::new("cargo");
cmd.arg("test")
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.current_dir(
generated_manifest
.parent()
.expect("expected to have parent")
.as_str(),
);

let (output, output_string) = {
let child = cmd.spawn()?;
let output = child.wait_with_output()?;
let mut output_string = String::new();
output_string.push_str(&String::from_utf8_lossy(&output.stderr));
output_string.push_str(&String::from_utf8_lossy(&output.stdout));
(output, output_string)
};
let versions = [&tests_manifest, generated_manifest]
.iter()
.map(|manifest| extract_locked_workspaces_version(manifest, "near_workspaces"))
.collect::<Result<Vec<_>, color_eyre::Report>>()?;

assert_eq!(versions[0], versions[1]);
Ok(())
}
assert!(
output.status.success(),
"running `cargo test` errored with msg: {}",
output_string
);

// TODO: add sync of versions of rust-toolchain.toml-s
#[allow(unused)]
fn get_workspaces_rs_version(manifest_path: &camino::Utf8PathBuf) -> color_eyre::Result<String> {
use color_eyre::eyre::OptionExt;
std::fs::remove_dir_all(
generated_manifest
.parent()
.expect("expected to have parent"),
)?;

let toml_table_str = {
let bytes = std::fs::read(manifest_path).map_err(|err| {
color_eyre::eyre::eyre!("read file, {:?}, err {}", manifest_path, err)
})?;
core::str::from_utf8(&bytes)?.to_owned()
};
let toml_table = toml_table_str.parse::<toml::Table>()?;
let entry = toml_table["dev-dependencies"]["near-workspaces"].clone();
let result = match entry {
toml::Value::String(version_string) => version_string,
toml::Value::Table(workspaces_table) => workspaces_table["version"]
.as_str()
.ok_or_eyre(format!("expected version string {:#?}", workspaces_table))?
.to_owned(),
_ => {
return Err(color_eyre::eyre::eyre!(
"unexpected variant of toml.dev-dependencies.near-workspaces"
))
}
};
Ok(result)
Ok(())
}

/// runs a `cargo near new FOLDER` routine while returning the FOLDER
/// runs a `cargo near new FOLDER` routine while returning the FOLDER/Cargo.toml
fn run_cargo_near_new() -> color_eyre::Result<camino::Utf8PathBuf> {
let out_path = {
let tmp_dir = tempfile::Builder::new()
Expand All @@ -114,5 +117,16 @@ fn run_cargo_near_new() -> color_eyre::Result<camino::Utf8PathBuf> {
},
&scope,
)?;
Ok(out_path.try_into()?)
let out_path: Utf8PathBuf = out_path.try_into()?;
Ok(out_path.join("Cargo.toml"))
}

fn tests_manifest() -> camino::Utf8PathBuf {
let cargo_near_integration_tests_dir: camino::Utf8PathBuf = env!("CARGO_MANIFEST_DIR").into();
cargo_near_integration_tests_dir.join("Cargo.toml")
}

fn tests_toolchain() -> camino::Utf8PathBuf {
let cargo_near_integration_tests_dir: camino::Utf8PathBuf = env!("CARGO_MANIFEST_DIR").into();
cargo_near_integration_tests_dir.join("../rust-toolchain.toml")
}
36 changes: 36 additions & 0 deletions integration-tests/tests/crate_metadata.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/// finds version of package in a crate's Cargo.lock
fn get_locked_package_version(
manifest_path: &camino::Utf8PathBuf,
package_name: &str,
) -> color_eyre::Result<semver::Version> {
let meta =
cargo_near_build::CrateMetadata::collect(manifest_path.clone().try_into()?, false, None)?;

let package = meta.find_dependency(package_name)?;

Ok(package.version.clone())
}

/// This asserts sync of versions of *package_name* in lock-file of
/// project_one vs project_two
pub fn assert_versions_equal(
manifest_one: &camino::Utf8PathBuf,
manifest_two: &camino::Utf8PathBuf,
package_name: &str,
) -> cargo_near::CliResult {
let versions = [manifest_one, manifest_two]
.iter()
.map(|manifest| get_locked_package_version(manifest, package_name))
.collect::<Result<Vec<_>, color_eyre::Report>>()?;

assert_eq!(
versions[0],
versions[1],
"no sync of versions of `{}` in lock-file of `{}` and \
`{}` projects",
package_name,
manifest_one.as_str(),
manifest_two.as_str(),
);
Ok(())
}
4 changes: 0 additions & 4 deletions integration-tests/tests/lib.rs

This file was deleted.

40 changes: 40 additions & 0 deletions integration-tests/tests/toolchain_channels.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/// this asserts sync of rust toolchains channels of file_one vs file_two
pub fn assert_equal(
toolchain_one: &camino::Utf8PathBuf,
toolchain_two: &camino::Utf8PathBuf,
) -> cargo_near::CliResult {
let channels = [toolchain_one, toolchain_two]
.iter()
.map(|file| get_toolchain_channel(file.as_std_path()))
.collect::<Result<Vec<_>, color_eyre::Report>>()?;
assert_eq!(
channels[0],
channels[1],
"no sync of channels of the toolchain `{}` \
and `{}`",
toolchain_one.as_str(),
toolchain_two.as_str(),
);
Ok(())
}

/// parses `rust-toolchain.toml` and returns `channel`
fn get_toolchain_channel(toolchain_file: &std::path::Path) -> color_eyre::Result<String> {
let toml_table_str = {
let bytes = std::fs::read(toolchain_file).map_err(|err| {
color_eyre::eyre::eyre!("read file, {:?}, err {}", toolchain_file, err)
})?;
core::str::from_utf8(&bytes)?.to_owned()
};
let toml_table = toml_table_str.parse::<toml::Table>()?;
let entry = toml_table["toolchain"]["channel"].clone();
let result = match entry {
toml::Value::String(channel_string) => channel_string,
_ => {
return Err(color_eyre::eyre::eyre!(
"unexpected variant of toml.toolchain.channel"
))
}
};
Ok(result)
}

0 comments on commit d6fa2f6

Please sign in to comment.