Skip to content

Commit 82dcd5d

Browse files
committed
Add a function for getting jobs of the current in progress requests and their parents
1 parent f75d4a2 commit 82dcd5d

File tree

5 files changed

+239
-496
lines changed

5 files changed

+239
-496
lines changed

database/src/lib.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,13 +1254,3 @@ pub struct CompletedBenchmarkRequestWithErrors {
12541254
/// Benchmark (name) -> error
12551255
errors: HashMap<String, String>,
12561256
}
1257-
1258-
/// The data that can be retrived from the database directly to populate the
1259-
/// status page
1260-
#[derive(Debug, PartialEq)]
1261-
pub struct PartialStatusPageData {
1262-
/// A Vector of; completed requests with any associated errors
1263-
pub completed_requests: Vec<(BenchmarkRequest, Vec<String>)>,
1264-
/// In progress requests along with their associated jobs
1265-
pub in_progress: Vec<InProgressRequestWithJobs>,
1266-
}

database/src/pool.rs

Lines changed: 97 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ use crate::selector::CompileTestCase;
22
use crate::{
33
ArtifactCollection, ArtifactId, ArtifactIdNumber, BenchmarkJob, BenchmarkJobConclusion,
44
BenchmarkRequest, BenchmarkRequestIndex, BenchmarkRequestStatus, BenchmarkSet, CodegenBackend,
5-
CollectorConfig, CompileBenchmark, CompletedBenchmarkRequestWithErrors, PartialStatusPageData,
6-
Target,
5+
CollectorConfig, CompileBenchmark, CompletedBenchmarkRequestWithErrors, Target,
76
};
87
use crate::{CollectionId, Index, Profile, QueuedCommit, Scenario, Step};
98
use chrono::{DateTime, Utc};
@@ -276,8 +275,6 @@ pub trait Connection: Send + Sync {
276275
conclusion: BenchmarkJobConclusion,
277276
) -> anyhow::Result<()>;
278277

279-
async fn get_status_page_data(&self) -> anyhow::Result<PartialStatusPageData>;
280-
281278
/// Return the last `count` completed benchmark requests, along with all errors associated with
282279
/// them.
283280
///
@@ -287,6 +284,12 @@ pub trait Connection: Send + Sync {
287284
count: u64,
288285
) -> anyhow::Result<Vec<CompletedBenchmarkRequestWithErrors>>;
289286

287+
/// Return jobs of all requests that are currently in progress, and the jobs of their parents.
288+
/// The keys of the hashmap contain the request tags.
289+
async fn get_jobs_of_in_progress_benchmark_requests(
290+
&self,
291+
) -> anyhow::Result<HashMap<String, Vec<BenchmarkJob>>>;
292+
290293
/// Get all of the configuration for all of the collectors
291294
async fn get_collector_configs(&self) -> anyhow::Result<Vec<CollectorConfig>>;
292295

@@ -413,9 +416,8 @@ impl Pool {
413416
mod tests {
414417
use super::*;
415418
use crate::metric::Metric;
416-
use crate::tests::builder::{JobBuilder, RequestBuilder};
419+
use crate::tests::builder::{job, RequestBuilder};
417420
use crate::tests::run_postgres_test;
418-
use crate::BenchmarkJobStatus;
419421
use crate::{tests::run_db_test, BenchmarkRequestType, Commit, CommitType, Date};
420422
use chrono::Utc;
421423
use std::str::FromStr;
@@ -1005,13 +1007,12 @@ mod tests {
10051007

10061008
/* From the status page view we can see that the duration has been
10071009
* updated. Albeit that it will be a very short duration. */
1008-
let status_page_view = db.get_status_page_data().await.unwrap();
1009-
let req = &status_page_view
1010-
.completed_requests
1010+
let completed = db.get_last_n_completed_benchmark_requests(1).await.unwrap();
1011+
let req = &completed
10111012
.iter()
1012-
.find(|it| it.0.tag() == Some(tag))
1013+
.find(|it| it.request.tag() == Some(tag))
10131014
.unwrap()
1014-
.0;
1015+
.request;
10151016

10161017
assert!(matches!(
10171018
req.status(),
@@ -1030,143 +1031,6 @@ mod tests {
10301031
.await;
10311032
}
10321033

1033-
#[tokio::test]
1034-
async fn get_status_page_data() {
1035-
run_postgres_test(|ctx| async {
1036-
let db = ctx.db_pool().connection().await;
1037-
let benchmark_set = BenchmarkSet(0u32);
1038-
let time = chrono::DateTime::from_str("2021-09-01T00:00:00.000Z").unwrap();
1039-
let tag = "sha-1";
1040-
let tag_two = "sha-2";
1041-
let collector_name = "collector-1";
1042-
let target = Target::X86_64UnknownLinuxGnu;
1043-
1044-
db.add_collector_config(collector_name, target, benchmark_set.0, true)
1045-
.await
1046-
.unwrap();
1047-
1048-
let benchmark_request = BenchmarkRequest::create_release(tag, time);
1049-
db.insert_benchmark_request(&benchmark_request)
1050-
.await
1051-
.unwrap();
1052-
1053-
complete_request(&*db, tag, collector_name, benchmark_set.0, target).await;
1054-
// record a couple of errors against the tag
1055-
let artifact_id = db.artifact_id(&ArtifactId::Tag(tag.to_string())).await;
1056-
1057-
db.record_error(artifact_id, "example-1", "This is an error")
1058-
.await;
1059-
db.record_error(artifact_id, "example-2", "This is another error")
1060-
.await;
1061-
1062-
let benchmark_request_two = BenchmarkRequest::create_release(tag_two, time);
1063-
db.insert_benchmark_request(&benchmark_request_two)
1064-
.await
1065-
.unwrap();
1066-
1067-
db.enqueue_benchmark_job(
1068-
benchmark_request_two.tag().unwrap(),
1069-
target,
1070-
CodegenBackend::Llvm,
1071-
Profile::Opt,
1072-
benchmark_set.0,
1073-
)
1074-
.await
1075-
.unwrap();
1076-
db.enqueue_benchmark_job(
1077-
benchmark_request_two.tag().unwrap(),
1078-
target,
1079-
CodegenBackend::Llvm,
1080-
Profile::Debug,
1081-
benchmark_set.0,
1082-
)
1083-
.await
1084-
.unwrap();
1085-
1086-
db.update_benchmark_request_status(
1087-
benchmark_request_two.tag().unwrap(),
1088-
BenchmarkRequestStatus::InProgress,
1089-
)
1090-
.await
1091-
.unwrap();
1092-
1093-
let status_page_data = db.get_status_page_data().await.unwrap();
1094-
1095-
assert!(status_page_data.completed_requests.len() == 1);
1096-
assert_eq!(status_page_data.completed_requests[0].0.tag().unwrap(), tag);
1097-
assert!(matches!(
1098-
status_page_data.completed_requests[0].0.status(),
1099-
BenchmarkRequestStatus::Completed { .. }
1100-
));
1101-
// can't really test duration
1102-
// ensure errors are correct
1103-
assert_eq!(
1104-
status_page_data.completed_requests[0].1[0],
1105-
"This is an error".to_string()
1106-
);
1107-
assert_eq!(
1108-
status_page_data.completed_requests[0].1[1],
1109-
"This is another error".to_string()
1110-
);
1111-
1112-
assert!(status_page_data.in_progress.len() == 1);
1113-
// we should have 2 jobs
1114-
assert!(status_page_data.in_progress[0].request.1.len() == 2);
1115-
// the request should be in progress
1116-
assert!(matches!(
1117-
status_page_data.in_progress[0].request.0.status(),
1118-
BenchmarkRequestStatus::InProgress
1119-
));
1120-
1121-
// Test the first job
1122-
assert!(matches!(
1123-
status_page_data.in_progress[0].request.1[0].target(),
1124-
Target::X86_64UnknownLinuxGnu
1125-
));
1126-
assert!(matches!(
1127-
status_page_data.in_progress[0].request.1[0].status(),
1128-
BenchmarkJobStatus::Queued
1129-
));
1130-
assert!(matches!(
1131-
status_page_data.in_progress[0].request.1[0].backend(),
1132-
CodegenBackend::Llvm
1133-
));
1134-
assert!(matches!(
1135-
status_page_data.in_progress[0].request.1[0].profile(),
1136-
Profile::Opt
1137-
));
1138-
assert_eq!(
1139-
status_page_data.in_progress[0].request.1[0].benchmark_set(),
1140-
benchmark_set
1141-
);
1142-
1143-
// test the second job
1144-
assert!(matches!(
1145-
status_page_data.in_progress[0].request.1[1].target(),
1146-
Target::X86_64UnknownLinuxGnu
1147-
));
1148-
assert!(matches!(
1149-
status_page_data.in_progress[0].request.1[1].status(),
1150-
BenchmarkJobStatus::Queued
1151-
));
1152-
assert!(matches!(
1153-
status_page_data.in_progress[0].request.1[1].backend(),
1154-
CodegenBackend::Llvm
1155-
));
1156-
assert!(matches!(
1157-
status_page_data.in_progress[0].request.1[1].profile(),
1158-
Profile::Debug
1159-
));
1160-
assert_eq!(
1161-
status_page_data.in_progress[0].request.1[1].benchmark_set(),
1162-
benchmark_set
1163-
);
1164-
1165-
Ok(ctx)
1166-
})
1167-
.await;
1168-
}
1169-
11701034
#[tokio::test]
11711035
async fn get_collector_configs() {
11721036
run_postgres_test(|ctx| async {
@@ -1223,7 +1087,7 @@ mod tests {
12231087
id,
12241088
)
12251089
.await
1226-
.add_job(db, JobBuilder::new())
1090+
.add_job(db, job())
12271091
.await
12281092
.complete(db, &collector)
12291093
.await,
@@ -1277,4 +1141,88 @@ mod tests {
12771141
})
12781142
.await;
12791143
}
1144+
1145+
#[tokio::test]
1146+
async fn get_in_progress_jobs() {
1147+
run_postgres_test(|ctx| async {
1148+
let db = ctx.db();
1149+
1150+
let collector = ctx.add_collector(Default::default()).await;
1151+
1152+
// Artifacts ready request, should be ignored
1153+
RequestBuilder::master(db, "foo", "bar", 1000).await;
1154+
1155+
// Create a completed parent with jobs
1156+
let completed = RequestBuilder::master(db, "sha4-parent", "sha0", 1001)
1157+
.await
1158+
.add_jobs(
1159+
db,
1160+
&[job().profile(Profile::Doc), job().profile(Profile::Opt)],
1161+
)
1162+
.await
1163+
.complete(db, &collector)
1164+
.await;
1165+
1166+
// In progress request without a parent
1167+
let req1 = RequestBuilder::master(db, "sha1", "sha0", 1)
1168+
.await
1169+
.set_in_progress(db)
1170+
.await;
1171+
1172+
// In progress request with a parent that has no jobs
1173+
let req2 = RequestBuilder::master(db, "sha2", "sha1", 2)
1174+
.await
1175+
.add_jobs(
1176+
db,
1177+
&[job().profile(Profile::Check), job().profile(Profile::Debug)],
1178+
)
1179+
.await
1180+
.set_in_progress(db)
1181+
.await;
1182+
1183+
// In progress request with a parent that has jobs
1184+
let req3 = RequestBuilder::master(db, "sha3", "sha2", 3)
1185+
.await
1186+
.add_jobs(
1187+
db,
1188+
&[job().profile(Profile::Doc), job().profile(Profile::Opt)],
1189+
)
1190+
.await
1191+
.set_in_progress(db)
1192+
.await;
1193+
1194+
// In progress request with a parent that has jobs, but is completed
1195+
let req4 = RequestBuilder::master(db, "sha4", completed.tag(), 4)
1196+
.await
1197+
.add_jobs(
1198+
db,
1199+
&[job().profile(Profile::Doc), job().profile(Profile::Check)],
1200+
)
1201+
.await
1202+
.set_in_progress(db)
1203+
.await;
1204+
1205+
let mut reqs = db
1206+
.get_jobs_of_in_progress_benchmark_requests()
1207+
.await
1208+
.unwrap();
1209+
1210+
// Check that all jobs are unique
1211+
let mut job_ids = HashSet::new();
1212+
for job in reqs.values().flatten() {
1213+
assert!(job_ids.insert(job.id));
1214+
}
1215+
1216+
// Check that all jobs were returned
1217+
assert!(!reqs.contains_key(req1.tag()));
1218+
req2.assert_has_exact_jobs(&reqs.remove(req2.tag()).unwrap());
1219+
req3.assert_has_exact_jobs(&reqs.remove(req3.tag()).unwrap());
1220+
req4.assert_has_exact_jobs(&reqs.remove(req4.tag()).unwrap());
1221+
completed.assert_has_exact_jobs(&reqs.remove(completed.tag()).unwrap());
1222+
assert!(reqs.is_empty());
1223+
1224+
Ok(ctx)
1225+
})
1226+
.await;
1227+
}
12801228
}

0 commit comments

Comments
 (0)