Skip to content

Commit

Permalink
chore: fix up tests after graph load changes
Browse files Browse the repository at this point in the history
  • Loading branch information
ctron committed Jan 21, 2025
1 parent d05e979 commit a19cced
Show file tree
Hide file tree
Showing 6 changed files with 232 additions and 94 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions modules/analysis/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ bytesize = { workspace = true }
chrono = { workspace = true }
hex = { workspace = true }
humantime = { workspace = true }
itertools = { workspace = true }
jsonpath-rust = { workspace = true }
log = { workspace = true }
petgraph = { workspace = true }
Expand Down
64 changes: 37 additions & 27 deletions modules/analysis/src/endpoints/test.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::test::caller;
use actix_http::Request;
use actix_web::test::TestRequest;
use itertools::Itertools;
use serde_json::{json, Value};
use std::collections::HashMap;
use test_context::test_context;
use test_log::test;
use trustify_test_context::{call::CallService, TrustifyContext};
Expand Down Expand Up @@ -179,27 +181,25 @@ async fn test_simple_dep_endpoint(ctx: &TrustifyContext) -> Result<(), anyhow::E
let request: Request = TestRequest::get().uri(uri).to_request();
let response: Value = app.call_and_read_body_json(request).await;

println!("Result: {response:#?}");

assert_eq!(
response["items"][0]["purl"],
Value::from(["pkg:rpm/redhat/[email protected]?arch=src"]),
);

let purls: Value = response["items"][0]["deps"]
let purls = response["items"][0]["deps"]
.as_array()
.iter()
.map(|deps| *deps)
.flatten()
.flat_map(|dep| dep["purl"].as_array())
.flatten()
.cloned()
.collect::<Vec<_>>()
.into();
.flat_map(|purl| purl.as_str().map(|s| s.to_string()))
.sorted()
.collect::<Vec<_>>();

assert_eq!(
purls,
json!(["pkg:rpm/redhat/[email protected]", "pkg:rpm/redhat/[email protected]?arch=src"])
&["pkg:rpm/redhat/[email protected]", "pkg:rpm/redhat/[email protected]?arch=src"]
);

assert_eq!(&response["total"], 2);
Expand Down Expand Up @@ -379,7 +379,7 @@ async fn test_retrieve_query_params_endpoint(ctx: &TrustifyContext) -> Result<()
let uri = format!("/api/v2/analysis/root-component?q=sbom_id={}", sbom_id);
let request: Request = TestRequest::get().uri(uri.clone().as_str()).to_request();
let response: Value = app.call_and_read_body_json(request).await;
assert_eq!(&response["total"], 8);
assert_eq!(&response["total"], 9);

// negative test
let uri =
Expand All @@ -397,6 +397,27 @@ async fn test_retrieve_query_params_endpoint(ctx: &TrustifyContext) -> Result<()
Ok(())
}

fn count_deps<F>(response: &Value, filter: F) -> HashMap<&str, usize>
where
F: Fn(&Value) -> bool,
{
let mut num = HashMap::new();

for item in response["items"].as_array().unwrap() {
num.insert(
item["node_id"].as_str().unwrap(),
item["deps"]
.as_array()
.into_iter()
.flatten()
.filter(|f| filter(f))
.count(),
);
}

num
}

#[test_context(TrustifyContext)]
#[test(actix_web::test)]
async fn issue_tc_2050(ctx: &TrustifyContext) -> Result<(), anyhow::Error> {
Expand All @@ -411,15 +432,8 @@ async fn issue_tc_2050(ctx: &TrustifyContext) -> Result<(), anyhow::Error> {
let response: Value = app.call_and_read_body_json(request).await;
log::debug!("{response:#?}");

assert_eq!(
35,
response["items"][0]["deps"]
.as_array()
.into_iter()
.flatten()
.filter(|m| m["relationship"] == "GeneratedFrom")
.count()
);
let num = count_deps(&response, |m| m["relationship"] == "GeneratedFrom");
assert_eq!(num["pkg:rpm/redhat/[email protected]_2?arch=src"], 35);

// Ensure binary rpm GeneratedFrom src rpm
let x86 = "pkg:rpm/redhat/[email protected]_2?arch=x86_64";
Expand Down Expand Up @@ -455,15 +469,9 @@ async fn issue_tc_2051(ctx: &TrustifyContext) -> Result<(), anyhow::Error> {
let request: Request = TestRequest::get().uri(&uri).to_request();
let response: Value = app.call_and_read_body_json(request).await;
log::debug!("{response:#?}");
assert_eq!(
35,
response["items"][0]["deps"]
.as_array()
.into_iter()
.flatten()
.filter(|m| m["relationship"] == "GeneratedFrom")
.count()
);

let num = count_deps(&response, |m| m["relationship"] == "GeneratedFrom");
assert_eq!(num["SPDXRef-SRPM"], 35);

// Ensure binary rpm GeneratedFrom src rpm
let x86 = "pkg:rpm/redhat/[email protected]_2?arch=x86_64";
Expand Down Expand Up @@ -499,7 +507,9 @@ async fn issue_tc_2052(ctx: &TrustifyContext) -> Result<(), anyhow::Error> {
let request: Request = TestRequest::get().uri(&uri).to_request();
let response: Value = app.call_and_read_body_json(request).await;
log::debug!("{response:#?}");
assert_eq!(1, response["items"][0]["deps"].as_array().unwrap().len());

let num = count_deps(&response, |_| true);
assert_eq!(num["pkg:oci/openshift-ose-console@sha256%3A94a0d7feec34600a858c8e383ee0e8d5f4a077f6bbc327dcad8762acfcf40679"], 1);

// Ensure child is variant of src
let child = "pkg:oci/ose-console@sha256:c2d69e860b7457eb42f550ba2559a0452ec3e5c9ff6521d758c186266247678e?arch=s390x&os=linux&tag=v4.14.0-202412110104.p0.g350e1ea.assembly.stream.el8";
Expand Down
14 changes: 11 additions & 3 deletions modules/analysis/src/service/load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,8 @@ impl AnalysisService {
product_version: package.product_version.clone().unwrap_or_default(),
});

log::debug!("Inserting - id: {}, index: {index:?}", entry.key());

entry.insert(index);
}
Entry::Occupied(_) => {}
Expand All @@ -259,10 +261,11 @@ impl AnalysisService {
}
};

// the nodes describing the document
let mut describedby_node_id: Vec<NodeIndex> = Default::default();

for edge in edges {
// remove all node IDs we somehow connected
log::debug!("Adding edge {:?}", edge);

// insert edge into the graph
match (
Expand All @@ -271,9 +274,10 @@ impl AnalysisService {
) {
(Some(left), Some(right)) => {
if edge.relationship == Relationship::DescribedBy {
describedby_node_id.push(*right);
describedby_node_id.push(*left);
}

// remove all node IDs we somehow connected
detected_nodes.remove(&edge.left_node_id);
detected_nodes.remove(&edge.right_node_id);

Expand All @@ -283,13 +287,17 @@ impl AnalysisService {
}
}

log::debug!("Describing nodes: {describedby_node_id:?}");
log::debug!("Unconnected nodes: {detected_nodes:?}");

if !describedby_node_id.is_empty() {
// search of unconnected nodes and create dummy relationships
// search of unconnected nodes and create undefined relationships
// all nodes not removed are unconnected
for id in detected_nodes {
let Some(id) = nodes.get(&id) else { continue };
// add "undefined" relationship
for from in &describedby_node_id {
log::debug!("Creating undefined relationship - left: {id:?}, right: {from:?}");
g.add_edge(*id, *from, Relationship::Undefined);
}
}
Expand Down
145 changes: 82 additions & 63 deletions modules/analysis/src/service/test.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::*;
use std::str::FromStr;
use std::time::SystemTime;
use crate::test::*;
use std::{str::FromStr, time::SystemTime};
use test_context::test_context;
use test_log::test;
use trustify_common::{
Expand Down Expand Up @@ -107,29 +107,30 @@ async fn test_simple_by_name_analysis_service(ctx: &TrustifyContext) -> Result<(
.retrieve_root_components("B", Paginated::default(), &ctx.db)
.await?;

assert_eq!(
analysis_graph
.items
.last()
.unwrap()
.ancestors
.last()
.unwrap()
.purl,
vec![Purl::from_str("pkg:rpm/redhat/[email protected]?arch=src")?]
);
assert_eq!(
analysis_graph
.items
.last()
.unwrap()
.ancestors
.last()
.unwrap()
.node_id,
"SPDXRef-A".to_string()
);
assert_ancestors(&analysis_graph.items, |ancestors| {
assert_eq!(
ancestors,
&[&[
Node {
id: "SPDXRef-A",
name: "A",
version: "1",
cpes: &["cpe:/a:redhat:simple:1:*:el9:*"],
purls: &["pkg:rpm/redhat/[email protected]?arch=src"],
},
Node {
id: "SPDXRef-DOCUMENT",
name: "simple",
version: "",
cpes: &[],
purls: &[],
},
]]
);
});

assert_eq!(analysis_graph.total, 1);

Ok(())
}

Expand All @@ -146,28 +147,28 @@ async fn test_simple_by_purl_analysis_service(ctx: &TrustifyContext) -> Result<(
.retrieve_root_components(&component_purl, Paginated::default(), &ctx.db)
.await?;

assert_eq!(
analysis_graph
.items
.last()
.unwrap()
.ancestors
.last()
.unwrap()
.purl,
vec![Purl::from_str("pkg:rpm/redhat/[email protected]?arch=src")?]
);
assert_eq!(
analysis_graph
.items
.last()
.unwrap()
.ancestors
.last()
.unwrap()
.node_id,
"SPDXRef-A".to_string()
);
assert_ancestors(&analysis_graph.items, |ancestors| {
assert_eq!(
ancestors,
[[
Node {
id: "SPDXRef-A",
name: "A",
version: "1",
purls: &["pkg:rpm/redhat/[email protected]?arch=src"],
cpes: &["cpe:/a:redhat:simple:1:*:el9:*"],
},
Node {
id: "SPDXRef-DOCUMENT",
name: "simple",
version: "",
cpes: &[],
purls: &[],
}
]]
);
});

assert_eq!(analysis_graph.total, 1);
Ok(())
}
Expand All @@ -187,23 +188,36 @@ async fn test_quarkus_analysis_service(ctx: &TrustifyContext) -> Result<(), anyh
.retrieve_root_components(&Query::q("spymemcached"), Paginated::default(), &ctx.db)
.await?;

assert_eq!(
analysis_graph.items.last().unwrap().ancestors.last().unwrap().purl,
vec![Purl::from_str("pkg:maven/com.redhat.quarkus.platform/[email protected]?type=pom&repository_url=https%3a%2f%2fmaven.repository.redhat.com%2fga%2f")?]
);
assert_eq!(
analysis_graph
.items
.last()
.unwrap()
.ancestors
.last()
.unwrap()
.node_id,
"SPDXRef-e24fec28-1001-499c-827f-2e2e5f2671b5".to_string()
);
assert_ancestors(&analysis_graph.items, |ancestors| {
assert!(
matches!(ancestors, [
[..],
[
Node {
id: "SPDXRef-DOCUMENT",
name: "quarkus-bom-3.2.12.Final-redhat-00002",
version: "",
..
},
Node {
id: "SPDXRef-e24fec28-1001-499c-827f-2e2e5f2671b5",
name: "quarkus-bom",
version: "3.2.12.Final-redhat-00002",
cpes: [
"cpe:/a:redhat:quarkus:3.2:*:el8:*",
],
purls: [
"pkg:maven/com.redhat.quarkus.platform/[email protected]?repository_url=https://maven.repository.redhat.com/ga/&type=pom"
],
},
]
]),
"must match: {ancestors:#?}"
);
});

assert_eq!(analysis_graph.total, 2);

Ok(())
}

Expand Down Expand Up @@ -384,7 +398,7 @@ async fn test_circular_deps_spdx_service(ctx: &TrustifyContext) -> Result<(), an

#[test_context(TrustifyContext)]
#[test(tokio::test)]
async fn test_retrieve_all_sbom_roots_by_name1(ctx: &TrustifyContext) -> Result<(), anyhow::Error> {
async fn test_retrieve_all_sbom_roots_by_name(ctx: &TrustifyContext) -> Result<(), anyhow::Error> {
ctx.ingest_documents(["spdx/quarkus-bom-3.2.11.Final-redhat-00001.json"])
.await?;

Expand All @@ -395,6 +409,8 @@ async fn test_retrieve_all_sbom_roots_by_name1(ctx: &TrustifyContext) -> Result<
.retrieve_root_components(&Query::q(&component_name), Paginated::default(), &ctx.db)
.await?;

log::debug!("Result: {analysis_graph:#?}");

let sbom_id = analysis_graph
.items
.last()
Expand All @@ -406,7 +422,10 @@ async fn test_retrieve_all_sbom_roots_by_name1(ctx: &TrustifyContext) -> Result<
.retrieve_all_sbom_roots_by_name(sbom_id, component_name, &ctx.db)
.await?;

assert_eq!(roots.last().unwrap().name, "quarkus-bom");
assert_eq!(
roots.last().unwrap().name,
"quarkus-bom-3.2.11.Final-redhat-00001"
);

Ok(())
}
Expand Down
Loading

0 comments on commit a19cced

Please sign in to comment.