From cea21b15d0021bc985cfd3a5b02a9dd41c2a33bb Mon Sep 17 00:00:00 2001 From: Mikhail Shchatko Date: Thu, 30 Jun 2022 10:58:26 +0300 Subject: [PATCH] DAG-1899 Randomize test order when creating sub-tasks and historic runtime information is not available --- CHANGELOG.md | 4 ++++ Cargo.lock | 41 +++++++++++++++++++++++++++++++-- Cargo.toml | 3 ++- src/task_types/resmoke_tasks.rs | 25 +++++++++++--------- 4 files changed, 59 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 667ee17..56afafe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.4.4 - 2022-06-30 + +* Randomize test order when creating sub-tasks and historic runtime information is not available. + ## 0.4.3 - 2022-06-28 * Relax requirement to have the enterprise repo configuration defined. diff --git a/Cargo.lock b/Cargo.lock index 4d20252..c989527 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1054,7 +1054,7 @@ dependencies = [ [[package]] name = "mongo-task-generator" -version = "0.4.3" +version = "0.4.4" dependencies = [ "anyhow", "assert_cmd", @@ -1067,6 +1067,7 @@ dependencies = [ "futures", "lazy_static", "maplit", + "rand 0.8.5", "regex", "rstest", "serde", @@ -1364,6 +1365,12 @@ version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + [[package]] name = "predicates" version = "2.1.1" @@ -1466,6 +1473,27 @@ dependencies = [ "winapi", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core 0.6.3", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.3", +] + [[package]] name = "rand_core" version = "0.3.1" @@ -1481,6 +1509,15 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom", +] + [[package]] name = "rayon" version = "1.5.1" @@ -1951,7 +1988,7 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" dependencies = [ - "rand", + "rand 0.4.6", "remove_dir_all", ] diff --git a/Cargo.toml b/Cargo.toml index 65c5ca8..6925f8e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mongo-task-generator" -version = "0.4.3" +version = "0.4.4" repository = "https://github.com/mongodb/mongo-task-generator" authors = ["Decision Automation Group "] edition = "2018" @@ -15,6 +15,7 @@ evg-api-rs = "0.2.2" futures = "0.3" lazy_static = "1.4" maplit = "1" +rand = "0.8.5" regex = "1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/src/task_types/resmoke_tasks.rs b/src/task_types/resmoke_tasks.rs index bb8cd4a..61e07b8 100644 --- a/src/task_types/resmoke_tasks.rs +++ b/src/task_types/resmoke_tasks.rs @@ -12,6 +12,7 @@ use std::{cmp::min, collections::HashMap, sync::Arc}; use anyhow::Result; use async_trait::async_trait; use maplit::hashmap; +use rand::{prelude::SliceRandom, thread_rng}; use shrub_rs::models::{ commands::{fn_call, fn_call_with_params, EvgCommand}, params::ParamValue, @@ -512,7 +513,8 @@ impl GenResmokeTaskServiceImpl { multiversion_tags: Option, ) -> Result> { let origin_suite = multiversion_name.unwrap_or(¶ms.suite_name); - let test_list = self.get_test_list(params, multiversion_name)?; + let mut test_list = self.get_test_list(params, multiversion_name)?; + test_list.shuffle(&mut thread_rng()); let n_suites = min(test_list.len(), self.config.n_suites); let tasks_per_suite = test_list.len() / n_suites; @@ -1205,7 +1207,8 @@ mod tests { #[test] fn test_split_task_fallback_should_split_tasks_count() { let n_suites = 3; - let test_list: Vec = (0..6) + let n_tests = 6; + let test_list: Vec = (0..n_tests) .into_iter() .map(|i| format!("test_{}.js", i)) .collect(); @@ -1225,15 +1228,15 @@ mod tests { .unwrap(); assert_eq!(sub_suites.len(), n_suites); - let suite_0 = &sub_suites[0]; - assert!(suite_0.test_list.contains(&"test_0.js".to_string())); - assert!(suite_0.test_list.contains(&"test_1.js".to_string())); - let suite_1 = &sub_suites[1]; - assert!(suite_1.test_list.contains(&"test_2.js".to_string())); - assert!(suite_1.test_list.contains(&"test_3.js".to_string())); - let suite_2 = &sub_suites[2]; - assert!(suite_2.test_list.contains(&"test_4.js".to_string())); - assert!(suite_2.test_list.contains(&"test_5.js".to_string())); + for sub_suite in &sub_suites { + assert_eq!(sub_suite.test_list.len(), n_tests / n_suites); + } + + let all_tests: Vec = sub_suites + .iter() + .flat_map(|s| s.test_list.clone()) + .collect(); + assert_eq!(all_tests.len(), n_tests); } // tests for get_test_list.