Skip to content

Commit 20a7147

Browse files
committed
Merge branch 'main' into project-scoped-oxql
# Conflicts: # nexus/tests/integration_tests/metrics.rs
2 parents 683df3e + 9285a7c commit 20a7147

File tree

1 file changed

+66
-12
lines changed

1 file changed

+66
-12
lines changed

nexus/tests/integration_tests/metrics.rs

Lines changed: 66 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -305,28 +305,67 @@ pub async fn timeseries_query(
305305
cptestctx: &ControlPlaneTestContext<omicron_nexus::Server>,
306306
query: impl ToString,
307307
) -> Vec<oxql_types::Table> {
308-
execute_timeseries_query(cptestctx, "/v1/system/timeseries/query", query)
309-
.await
308+
timeseries_query_until_success(
309+
cptestctx,
310+
"/v1/system/timeseries/query",
311+
query,
312+
)
313+
.await
310314
}
311315

312316
pub async fn project_timeseries_query(
313317
cptestctx: &ControlPlaneTestContext<omicron_nexus::Server>,
314318
project: &str,
315319
query: impl ToString,
316320
) -> Vec<oxql_types::Table> {
317-
execute_timeseries_query(
321+
timeseries_query_until_success(
318322
cptestctx,
319323
&format!("/v1/timeseries/query?project={}", project),
320324
query,
321325
)
322326
.await
323327
}
324328

325-
async fn execute_timeseries_query(
329+
/// Run an OxQL query until it succeeds or panics.
330+
async fn timeseries_query_until_success(
326331
cptestctx: &ControlPlaneTestContext<omicron_nexus::Server>,
327332
endpoint: &str,
328333
query: impl ToString,
329334
) -> Vec<oxql_types::Table> {
335+
const POLL_INTERVAL: Duration = Duration::from_secs(1);
336+
const POLL_MAX: Duration = Duration::from_secs(30);
337+
let query_ = query.to_string();
338+
wait_for_condition(
339+
|| async {
340+
match execute_timeseries_query(cptestctx, endpoint, &query_).await {
341+
Some(r) => Ok(r),
342+
None => Err(CondCheckError::<()>::NotYet),
343+
}
344+
},
345+
&POLL_INTERVAL,
346+
&POLL_MAX,
347+
)
348+
.await
349+
.unwrap_or_else(|_| {
350+
panic!(
351+
"Timeseries named in query are not available \
352+
after {:?}, query: '{}'",
353+
POLL_MAX,
354+
query.to_string(),
355+
)
356+
})
357+
}
358+
359+
/// Run an OxQL query.
360+
///
361+
/// This returns `None` if the query resulted in client error and the body
362+
/// indicates that a timeseries named in the query could not be found. In all
363+
/// other cases, it either succeeds or panics.
364+
pub async fn execute_timeseries_query(
365+
cptestctx: &ControlPlaneTestContext<omicron_nexus::Server>,
366+
endpoint: &str,
367+
query: impl ToString,
368+
) -> Option<Vec<oxql_types::Table>> {
330369
// first, make sure the latest timeseries have been collected.
331370
cptestctx
332371
.oximeter
@@ -353,14 +392,29 @@ async fn execute_timeseries_query(
353392
.unwrap_or_else(|e| {
354393
panic!("timeseries query failed: {e:?}\nquery: {query}")
355394
});
356-
rsp.parsed_body::<OxqlQueryResult>()
357-
.unwrap_or_else(|e| {
358-
panic!(
359-
"could not parse timeseries query response: {e:?}\n\
360-
query: {query}\nresponse: {rsp:#?}"
361-
);
362-
})
363-
.tables
395+
396+
// Check for a timeseries-not-found error specifically.
397+
if rsp.status.is_client_error() {
398+
let text = std::str::from_utf8(&rsp.body)
399+
.expect("Timeseries query response body should be UTF-8");
400+
if text.contains("Schema for timeseries") && text.contains("not found")
401+
{
402+
return None;
403+
}
404+
}
405+
406+
// Try to parse the query as usual, which will fail on other kinds of
407+
// errors.
408+
Some(
409+
rsp.parsed_body::<OxqlQueryResult>()
410+
.unwrap_or_else(|e| {
411+
panic!(
412+
"could not parse timeseries query response: {e:?}\n\
413+
query: {query}\nresponse: {rsp:#?}"
414+
);
415+
})
416+
.tables,
417+
)
364418
}
365419

366420
#[nexus_test]

0 commit comments

Comments
 (0)