Skip to content

Commit 6716b16

Browse files
committed
Add failing test for missing quay repos
This affirms the downstream bug, https://issues.redhat.com/browse/TC-2686 It also reduces some log noise. There is no fix in this commit, only a failing test.
1 parent be39d3b commit 6716b16

File tree

11 files changed

+275
-13
lines changed

11 files changed

+275
-13
lines changed

Cargo.lock

Lines changed: 69 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ utoipa-swagger-ui = "9.0.0"
151151
uuid = "1.7.0"
152152
walkdir = "2.5"
153153
walker-common = "0.14.1"
154+
wiremock = "0.6"
154155
zip = "5"
155156

156157
trustify-auth = { path = "common/auth", features = ["actix", "swagger"] }
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
{
2+
"namespace": "redhat-user-workloads",
3+
"name": "rhtap-o11y-tenant/o11y/o11y",
4+
"kind": "image",
5+
"description": "AppStudio repository for the user",
6+
"is_public": true,
7+
"is_organization": true,
8+
"is_starred": false,
9+
"status_token": "",
10+
"trust_enabled": false,
11+
"tag_expiration_s": 1209600,
12+
"is_free_account": false,
13+
"state": "NORMAL",
14+
"tags": {
15+
"sha256-1e52a468c89471a4491c664457659d3b2de5d65bfc0f956df20bb21c25c79743.src": {
16+
"name": "sha256-1e52a468c89471a4491c664457659d3b2de5d65bfc0f956df20bb21c25c79743.src",
17+
"size": 126899461,
18+
"last_modified": "Tue, 14 Oct 2025 18:29:41 -0000",
19+
"manifest_digest": "sha256:748c1aeb94767ac1e5fbe6cb57ebb284c33874076aff616897be37bc34581a24"
20+
},
21+
"sha256-1e52a468c89471a4491c664457659d3b2de5d65bfc0f956df20bb21c25c79743.sig": {
22+
"name": "sha256-1e52a468c89471a4491c664457659d3b2de5d65bfc0f956df20bb21c25c79743.sig",
23+
"size": 273,
24+
"last_modified": "Tue, 14 Oct 2025 18:29:25 -0000",
25+
"manifest_digest": "sha256:a8e16cb9ba9068596e3b18a6cff2c728db24bf07250265e1b059500c0a605638"
26+
},
27+
"sha256-1e52a468c89471a4491c664457659d3b2de5d65bfc0f956df20bb21c25c79743.sbom": {
28+
"name": "sha256-1e52a468c89471a4491c664457659d3b2de5d65bfc0f956df20bb21c25c79743.sbom",
29+
"size": 141513,
30+
"last_modified": "Tue, 14 Oct 2025 18:29:22 -0000",
31+
"manifest_digest": "sha256:ef9e2a9b69501d05ecaf57ca5b46c70f27eb094a88081661530500c32b9d5e67"
32+
},
33+
"sha256-e5e92b128daf08bdc05121b7e07b82da2941926a03b87d1fa8cfb8edfb9a1554.src": {
34+
"name": "sha256-e5e92b128daf08bdc05121b7e07b82da2941926a03b87d1fa8cfb8edfb9a1554.src",
35+
"size": 126899440,
36+
"last_modified": "Tue, 14 Oct 2025 17:44:30 -0000",
37+
"manifest_digest": "sha256:8714ba13b5dc3b3c00944bcde169e20ff205feb1fdcdf1560dddd2f2618f1c31"
38+
},
39+
"sha256-e5e92b128daf08bdc05121b7e07b82da2941926a03b87d1fa8cfb8edfb9a1554.sig": {
40+
"name": "sha256-e5e92b128daf08bdc05121b7e07b82da2941926a03b87d1fa8cfb8edfb9a1554.sig",
41+
"size": 273,
42+
"last_modified": "Tue, 14 Oct 2025 17:44:14 -0000",
43+
"manifest_digest": "sha256:1675200b73a4c4c47e9402d5943c274673bf8fa838bba5f0d798ae551b46a6e6"
44+
},
45+
"sha256-e5e92b128daf08bdc05121b7e07b82da2941926a03b87d1fa8cfb8edfb9a1554.sbom": {
46+
"name": "sha256-e5e92b128daf08bdc05121b7e07b82da2941926a03b87d1fa8cfb8edfb9a1554.sbom",
47+
"size": 141519,
48+
"last_modified": "Tue, 14 Oct 2025 17:44:10 -0000",
49+
"manifest_digest": "sha256:2dddf41ed0bd13f224e5db5547ffe868c1491f8df23d0bba2a0133b4ca81faf7"
50+
},
51+
"sha256-a5f1dddbb40548b64cb4d04825e207cfc7699a84629a2fbf27e143c1b87293bd.sig": {
52+
"name": "sha256-a5f1dddbb40548b64cb4d04825e207cfc7699a84629a2fbf27e143c1b87293bd.sig",
53+
"size": 273,
54+
"last_modified": "Tue, 14 Oct 2025 16:31:15 -0000",
55+
"manifest_digest": "sha256:ff8b878badd63d1cffd9dfc99aa0e1e8570c07b61767f9aca1b08c1cddef2269"
56+
},
57+
"sha256-a5f1dddbb40548b64cb4d04825e207cfc7699a84629a2fbf27e143c1b87293bd.sbom": {
58+
"name": "sha256-a5f1dddbb40548b64cb4d04825e207cfc7699a84629a2fbf27e143c1b87293bd.sbom",
59+
"size": 141519,
60+
"last_modified": "Tue, 14 Oct 2025 16:31:11 -0000",
61+
"manifest_digest": "sha256:7defd07f42f0904645c8f8a21dc25211f11b41cada0986ddeb020e699c879969"
62+
},
63+
"sha256-e35282a95cae70cca60eabd27bb564cd7822872cd32b9cb5d4c89b3907be16a8.sig": {
64+
"name": "sha256-e35282a95cae70cca60eabd27bb564cd7822872cd32b9cb5d4c89b3907be16a8.sig",
65+
"size": 273,
66+
"last_modified": "Tue, 14 Oct 2025 16:31:10 -0000",
67+
"manifest_digest": "sha256:3ecfef1f6602b11612ff10133408b64f2c3e4b3dd94dc33f5a7c0292900c303c"
68+
},
69+
"sha256-e35282a95cae70cca60eabd27bb564cd7822872cd32b9cb5d4c89b3907be16a8.sbom": {
70+
"name": "sha256-e35282a95cae70cca60eabd27bb564cd7822872cd32b9cb5d4c89b3907be16a8.sbom",
71+
"size": 141522,
72+
"last_modified": "Tue, 14 Oct 2025 16:31:05 -0000",
73+
"manifest_digest": "sha256:dc87ece0469950ea6e5354c438116f7cdd56577f1f7cfce8e005a9ef73cf36ba"
74+
}
75+
},
76+
"can_write": false,
77+
"can_admin": false
78+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
{
2+
"repositories": [
3+
{
4+
"namespace": "redhat-user-workloads",
5+
"name": "rhtap-o11y-tenant/o11y/o11y",
6+
"description": "AppStudio repository for the user",
7+
"is_public": true,
8+
"kind": "image",
9+
"state": "NORMAL",
10+
"last_modified": 1760466595,
11+
"quota_report": {
12+
"quota_bytes": 37095445321,
13+
"configured_quota": null
14+
}
15+
},
16+
{
17+
"namespace": "redhat-user-workloads",
18+
"name": "crt-redhat-acm-tenant/config-policy-controller/config-policy-controller-0pyc",
19+
"description": "AppStudio repository for the user",
20+
"is_public": true,
21+
"kind": "image",
22+
"state": "NORMAL",
23+
"last_modified": 1714660256,
24+
"quota_report": {
25+
"quota_bytes": 7054253958,
26+
"configured_quota": null
27+
}
28+
},
29+
{
30+
"namespace": "redhat-user-workloads",
31+
"name": "crt-redhat-acm-tenant/governance-policy-addon-controller/governance-policy-addon-controller-ocyz",
32+
"description": "AppStudio repository for the user",
33+
"is_public": true,
34+
"kind": "image",
35+
"state": "NORMAL",
36+
"last_modified": 1714658754,
37+
"quota_report": {
38+
"quota_bytes": 7875486728,
39+
"configured_quota": null
40+
}
41+
},
42+
{
43+
"namespace": "redhat-user-workloads",
44+
"name": "crt-redhat-acm-tenant/governance-policy-framework-addon/governance-policy-framework-addon-dfsa",
45+
"description": "AppStudio repository for the user",
46+
"is_public": true,
47+
"kind": "image",
48+
"state": "NORMAL",
49+
"last_modified": 1714660711,
50+
"quota_report": {
51+
"quota_bytes": 5840585101,
52+
"configured_quota": null
53+
}
54+
}
55+
],
56+
"next_page": null
57+
}

modules/importer/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,4 @@ bytesize = { workspace = true }
6060
test-log = { workspace = true, features = ["log", "trace"] }
6161
test-context = { workspace = true }
6262
trustify-test-context = { workspace = true }
63+
wiremock = { workspace = true }

modules/importer/src/model/quay.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,19 @@ impl QuayImporter {
6767
// returned for a namespace
6868
let ns = self.namespace.as_deref().unwrap_or_default();
6969
format!(
70-
"https://{}/api/v1/repository?public=true&last_modified=true&next_page={page}&namespace={ns}",
71-
self.source
70+
"{}/api/v1/repository?public=true&last_modified=true&next_page={page}&namespace={ns}",
71+
self.base_url()
7272
)
7373
}
7474
pub fn repository_url(&self, namespace: &str, name: &str) -> String {
75-
format!(
76-
"https://{}/api/v1/repository/{namespace}/{name}",
77-
self.source
78-
)
75+
format!("{}/api/v1/repository/{namespace}/{name}", self.base_url())
76+
}
77+
78+
pub fn base_url(&self) -> String {
79+
if self.source.to_lowercase().starts_with("http") {
80+
self.source.clone()
81+
} else {
82+
format!("https://{}", self.source)
83+
}
7984
}
8085
}

modules/importer/src/runner/quay/walker.rs

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ impl<C: RunContext> QuayWalker<C> {
103103
}
104104

105105
async fn fetch(&self, reference: &Reference) -> Option<Vec<u8>> {
106+
log::debug!("Fetching reference: {reference}");
106107
match self.oci.fetch(reference).await {
107108
Ok(bytes) => Some(bytes),
108109
Err(err) => {
@@ -177,6 +178,7 @@ impl<C: RunContext> QuayWalker<C> {
177178
.get(self.importer.repositories_url(&page))
178179
.send()
179180
.await?
181+
.error_for_status()?
180182
.json()
181183
.await?;
182184
Ok::<_, Error>(Some((
@@ -196,8 +198,15 @@ impl<C: RunContext> QuayWalker<C> {
196198
match (repo.namespace, repo.name) {
197199
(Some(namespace), Some(name)) => {
198200
let url = self.importer.repository_url(&namespace, &name);
199-
log::debug!("Fetching {url}");
200-
Ok(self.client.get(url).send().await?.json().await?)
201+
log::debug!("Fetching repo {url}");
202+
Ok(self
203+
.client
204+
.get(url)
205+
.send()
206+
.await?
207+
.error_for_status()?
208+
.json()
209+
.await?)
201210
}
202211
_ => Err(Error::Processing(anyhow!(
203212
"Repository name and namespace are required"
@@ -299,10 +308,15 @@ mod test {
299308
use test_context::test_context;
300309
use test_log::test;
301310
use trustify_test_context::TrustifyContext;
311+
use wiremock::{
312+
Mock, MockServer, ResponseTemplate,
313+
matchers::{method, path},
314+
};
302315

303316
#[test_context(TrustifyContext)]
304317
#[test(tokio::test)]
305-
async fn walk(ctx: &TrustifyContext) -> Result<(), anyhow::Error> {
318+
#[ignore]
319+
async fn walk_quay(ctx: &TrustifyContext) -> Result<(), anyhow::Error> {
306320
let walker = QuayWalker::new(
307321
QuayImporter {
308322
source: "quay.io".into(),
@@ -322,6 +336,43 @@ mod test {
322336
Ok(())
323337
}
324338

339+
#[test_context(TrustifyContext)]
340+
#[test(tokio::test)]
341+
async fn missing_repo(ctx: &TrustifyContext) -> Result<(), anyhow::Error> {
342+
// Start a background HTTP server on a random local port
343+
let quay = MockServer::start().await;
344+
345+
Mock::given(method("GET"))
346+
.and(path("/api/v1/repository"))
347+
.respond_with(ResponseTemplate::new(200).set_body_string(include_str!(
348+
"../../../../../etc/test-data/quay/sample-repos.json"
349+
)))
350+
.mount(&quay)
351+
.await;
352+
Mock::given(method("GET"))
353+
.and(path(
354+
"/api/v1/repository/redhat-user-workloads/rhtap-o11y-tenant/o11y/o11y",
355+
))
356+
.respond_with(ResponseTemplate::new(200).set_body_string(include_str!(
357+
"../../../../../etc/test-data/quay/sample-repo.json"
358+
)))
359+
.mount(&quay)
360+
.await;
361+
362+
let walker = QuayWalker::new(
363+
QuayImporter {
364+
source: quay.uri(),
365+
..Default::default()
366+
},
367+
ctx.ingestor.clone(),
368+
Arc::new(Mutex::new(ReportBuilder::new())),
369+
(),
370+
)?;
371+
walker.run().await?;
372+
373+
Ok(())
374+
}
375+
325376
#[test_context(TrustifyContext)]
326377
#[test(tokio::test)]
327378
async fn invalid_source(ctx: &TrustifyContext) -> Result<(), anyhow::Error> {

modules/ingestor/src/service/format.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ pub enum Format {
5353
}
5454

5555
impl Format {
56-
#[instrument(skip(self, graph, buffer))]
56+
#[instrument(skip_all)]
5757
pub async fn load(
5858
&self,
5959
graph: &'_ Graph,

0 commit comments

Comments
 (0)