mirror of
https://github.com/msberends/AMR.git
synced 2026-05-31 13:41:42 +02:00
unit tests
This commit is contained in:
@@ -441,94 +441,111 @@ test_that("test-sir.R", {
|
|||||||
# Tests must pass even when only 1 core is available; parallel = TRUE then
|
# Tests must pass even when only 1 core is available; parallel = TRUE then
|
||||||
# silently falls back to sequential, but results must still be identical.
|
# silently falls back to sequential, but results must still be identical.
|
||||||
|
|
||||||
set.seed(42)
|
if (AMR:::pkg_is_available("future.apply")) {
|
||||||
n_par <- 200
|
set.seed(42)
|
||||||
df_par <- data.frame(
|
n_par <- 200
|
||||||
mo = "B_ESCHR_COLI",
|
df_par <- data.frame(
|
||||||
AMC = as.mic(sample(c("0.25", "0.5", "1", "2", "4", "8", "16", "32"), n_par, TRUE)),
|
mo = "B_ESCHR_COLI",
|
||||||
GEN = as.mic(sample(c("0.5", "1", "2", "4", "8", "16", "32", "64"), n_par, TRUE)),
|
AMC = as.mic(sample(c("0.25", "0.5", "1", "2", "4", "8", "16", "32"), n_par, TRUE)),
|
||||||
CIP = as.mic(sample(c("0.001", "0.002", "0.004", "0.008", "0.016", "0.032"), n_par, TRUE)),
|
GEN = as.mic(sample(c("0.5", "1", "2", "4", "8", "16", "32", "64"), n_par, TRUE)),
|
||||||
PEN = sample(c("S", "I", "R", NA_character_), n_par, TRUE),
|
CIP = as.mic(sample(c("0.001", "0.002", "0.004", "0.008", "0.016", "0.032"), n_par, TRUE)),
|
||||||
stringsAsFactors = FALSE
|
PEN = sample(c("S", "I", "R", NA_character_), n_par, TRUE),
|
||||||
)
|
stringsAsFactors = FALSE
|
||||||
|
)
|
||||||
|
|
||||||
# clear any existing history before comparing
|
# clear any existing history before comparing
|
||||||
sir_interpretation_history(clean = TRUE)
|
sir_interpretation_history(clean = TRUE)
|
||||||
sir_seq <- suppressMessages(as.sir(df_par, col_mo = "mo", info = FALSE))
|
sir_seq <- suppressMessages(as.sir(df_par, col_mo = "mo", info = FALSE))
|
||||||
log_seq <- sir_interpretation_history(clean = TRUE)
|
log_seq <- sir_interpretation_history(clean = TRUE)
|
||||||
|
|
||||||
sir_par <- suppressMessages(as.sir(df_par, col_mo = "mo", info = FALSE, parallel = TRUE))
|
future::plan(future::multicore)
|
||||||
log_par <- sir_interpretation_history(clean = TRUE)
|
n_max_workers <- future::nbrOfWorkers()
|
||||||
|
|
||||||
# 1. parallel = TRUE gives identical SIR results to sequential
|
sir_par <- suppressMessages(as.sir(df_par, col_mo = "mo", info = FALSE, parallel = TRUE))
|
||||||
expect_identical(sir_seq[["AMC"]], sir_par[["AMC"]])
|
log_par <- sir_interpretation_history(clean = TRUE)
|
||||||
expect_identical(sir_seq[["GEN"]], sir_par[["GEN"]])
|
|
||||||
expect_identical(sir_seq[["CIP"]], sir_par[["CIP"]])
|
|
||||||
expect_identical(sir_seq[["PEN"]], sir_par[["PEN"]])
|
|
||||||
|
|
||||||
# 2. same number of log rows as sequential
|
# 1. parallel = TRUE gives identical SIR results to sequential
|
||||||
expect_equal(nrow(log_seq), nrow(log_par))
|
expect_identical(sir_seq[["AMC"]], sir_par[["AMC"]])
|
||||||
|
expect_identical(sir_seq[["GEN"]], sir_par[["GEN"]])
|
||||||
|
expect_identical(sir_seq[["CIP"]], sir_par[["CIP"]])
|
||||||
|
expect_identical(sir_seq[["PEN"]], sir_par[["PEN"]])
|
||||||
|
|
||||||
# 3. pre-existing log entries must not be duplicated
|
# 2. same number of log rows as sequential
|
||||||
# run sequential once to populate the history, then run parallel and
|
expect_equal(nrow(log_seq), nrow(log_par))
|
||||||
# verify the new parallel run adds exactly as many rows as sequential
|
|
||||||
sir_interpretation_history(clean = TRUE)
|
|
||||||
suppressMessages(as.sir(df_par, col_mo = "mo", info = FALSE)) # populate history
|
|
||||||
pre_n <- nrow(sir_interpretation_history())
|
|
||||||
suppressMessages(as.sir(df_par, col_mo = "mo", info = FALSE, parallel = TRUE))
|
|
||||||
post_n <- nrow(sir_interpretation_history())
|
|
||||||
expect_equal(post_n - pre_n, nrow(log_seq)) # exactly one run's worth of new rows
|
|
||||||
sir_interpretation_history(clean = TRUE)
|
|
||||||
|
|
||||||
# 4. two sequential runs and two parallel runs yield identical results
|
# 3. pre-existing log entries must not be duplicated
|
||||||
sir_par2 <- suppressMessages(as.sir(df_par, col_mo = "mo", info = FALSE, parallel = TRUE))
|
# run sequential once to populate the history, then run parallel and
|
||||||
expect_identical(sir_par[["AMC"]], sir_par2[["AMC"]])
|
# verify the new parallel run adds exactly as many rows as sequential
|
||||||
expect_identical(sir_par[["GEN"]], sir_par2[["GEN"]])
|
sir_interpretation_history(clean = TRUE)
|
||||||
|
future::plan(future::sequential)
|
||||||
|
suppressMessages(as.sir(df_par, col_mo = "mo", info = FALSE)) # populate history
|
||||||
|
pre_n <- nrow(sir_interpretation_history())
|
||||||
|
future::plan(future::multicore)
|
||||||
|
suppressMessages(as.sir(df_par, col_mo = "mo", info = FALSE, parallel = TRUE))
|
||||||
|
post_n <- nrow(sir_interpretation_history())
|
||||||
|
expect_equal(post_n - pre_n, nrow(log_seq)) # exactly one run's worth of new rows
|
||||||
|
sir_interpretation_history(clean = TRUE)
|
||||||
|
|
||||||
# 5. max_cores = 1 gives same results as default sequential
|
# 4. two sequential runs and two parallel runs yield identical results
|
||||||
sir_mc1 <- suppressMessages(as.sir(df_par, col_mo = "mo", info = FALSE, parallel = TRUE, max_cores = 1L))
|
sir_par2 <- suppressMessages(as.sir(df_par, col_mo = "mo", info = FALSE, parallel = TRUE))
|
||||||
expect_identical(sir_seq[["AMC"]], sir_mc1[["AMC"]])
|
expect_identical(sir_par[["AMC"]], sir_par2[["AMC"]])
|
||||||
expect_identical(sir_seq[["GEN"]], sir_mc1[["GEN"]])
|
expect_identical(sir_par[["GEN"]], sir_par2[["GEN"]])
|
||||||
|
|
||||||
# 6. max_cores = 2 and max_cores = 3 give same results as sequential
|
# 5. max_cores = 1 gives same results as default sequential
|
||||||
sir_mc2 <- suppressMessages(as.sir(df_par, col_mo = "mo", info = FALSE, parallel = TRUE, max_cores = 2L))
|
future::plan(future::multicore, workers = 1)
|
||||||
sir_mc3 <- suppressMessages(as.sir(df_par, col_mo = "mo", info = FALSE, parallel = TRUE, max_cores = 3L))
|
sir_mc1 <- suppressMessages(as.sir(df_par, col_mo = "mo", info = FALSE, parallel = TRUE))
|
||||||
expect_identical(sir_seq[["AMC"]], sir_mc2[["AMC"]])
|
expect_identical(sir_seq[["AMC"]], sir_mc1[["AMC"]])
|
||||||
expect_identical(sir_seq[["GEN"]], sir_mc3[["GEN"]])
|
expect_identical(sir_seq[["GEN"]], sir_mc1[["GEN"]])
|
||||||
|
|
||||||
# 7. single-column data frame falls back silently to sequential
|
# 6. max_cores = 2 and max_cores = 3 give same results as sequential
|
||||||
df_single <- df_par[, c("mo", "AMC")]
|
if (n_max_workers >= 3) {
|
||||||
sir_single_seq <- suppressMessages(as.sir(df_single, col_mo = "mo", info = FALSE))
|
future::plan(future::multicore, workers = 2)
|
||||||
sir_single_par <- suppressMessages(as.sir(df_single, col_mo = "mo", info = FALSE, parallel = TRUE))
|
sir_mc2 <- suppressMessages(as.sir(df_par, col_mo = "mo", info = FALSE, parallel = TRUE))
|
||||||
expect_identical(sir_single_seq[["AMC"]], sir_single_par[["AMC"]])
|
future::plan(future::multicore, workers = 3)
|
||||||
|
sir_mc3 <- suppressMessages(as.sir(df_par, col_mo = "mo", info = FALSE, parallel = TRUE))
|
||||||
|
expect_identical(sir_seq[["AMC"]], sir_mc2[["AMC"]])
|
||||||
|
expect_identical(sir_seq[["GEN"]], sir_mc3[["GEN"]])
|
||||||
|
}
|
||||||
|
|
||||||
# 9. row-batch mode (n_cols < n_cores): force row splitting via max_cores and
|
# 7. single-column data frame falls back silently to sequential
|
||||||
# verify identical output to sequential for a dataset with 2 AB columns so
|
df_single <- df_par[, c("mo", "AMC")]
|
||||||
# pieces_per_col = ceiling(max_cores / 2) >= 2 and row batching activates
|
future::plan(future::sequential)
|
||||||
df_wide <- data.frame(
|
sir_single_seq <- suppressMessages(as.sir(df_single, col_mo = "mo", info = FALSE))
|
||||||
mo = "B_ESCHR_COLI",
|
future::plan(future::multicore)
|
||||||
AMC = as.mic(sample(c("1", "2", "4", "8"), n_par, TRUE)),
|
sir_single_par <- suppressMessages(as.sir(df_single, col_mo = "mo", info = FALSE, parallel = TRUE))
|
||||||
GEN = as.mic(sample(c("1", "2", "4", "8"), n_par, TRUE)),
|
expect_identical(sir_single_seq[["AMC"]], sir_single_par[["AMC"]])
|
||||||
stringsAsFactors = FALSE
|
|
||||||
)
|
|
||||||
sir_wide_seq <- suppressMessages(as.sir(df_wide, col_mo = "mo", info = FALSE))
|
|
||||||
sir_wide_par <- suppressMessages(as.sir(df_wide,
|
|
||||||
col_mo = "mo", info = FALSE,
|
|
||||||
parallel = TRUE, max_cores = 8L
|
|
||||||
))
|
|
||||||
expect_identical(sir_wide_seq[["AMC"]], sir_wide_par[["AMC"]])
|
|
||||||
expect_identical(sir_wide_seq[["GEN"]], sir_wide_par[["GEN"]])
|
|
||||||
|
|
||||||
# 8. info = TRUE with parallel does not produce per-column worker messages
|
# 8. row-batch mode (n_cols < n_cores): force row splitting via max_cores and
|
||||||
# (messages should only appear in the main process, not duplicated from workers)
|
# verify identical output to sequential for a dataset with 2 AB columns so
|
||||||
msgs <- capture.output(
|
# pieces_per_col = ceiling(max_cores / 2) >= 2 and row batching activates
|
||||||
suppressWarnings(as.sir(df_par, col_mo = "mo", info = TRUE, parallel = TRUE)),
|
df_wide <- data.frame(
|
||||||
type = "message"
|
mo = "B_ESCHR_COLI",
|
||||||
)
|
AMC = as.mic(sample(c("1", "2", "4", "8"), n_par, TRUE)),
|
||||||
# each AB column name should appear at most once in all messages combined
|
GEN = as.mic(sample(c("1", "2", "4", "8"), n_par, TRUE)),
|
||||||
for (ab_nm in c("AMC", "GEN", "CIP", "PEN")) {
|
stringsAsFactors = FALSE
|
||||||
n_mentions <- sum(grepl(ab_nm, msgs, fixed = TRUE))
|
)
|
||||||
expect_lte(n_mentions, 1L)
|
future::plan(future::sequential)
|
||||||
|
sir_wide_seq <- suppressMessages(as.sir(df_wide, col_mo = "mo", info = FALSE))
|
||||||
|
future::plan(future::multicore)
|
||||||
|
sir_wide_par <- suppressMessages(as.sir(df_wide,
|
||||||
|
col_mo = "mo", info = FALSE,
|
||||||
|
parallel = TRUE, max_cores = 8L
|
||||||
|
))
|
||||||
|
expect_identical(sir_wide_seq[["AMC"]], sir_wide_par[["AMC"]])
|
||||||
|
expect_identical(sir_wide_seq[["GEN"]], sir_wide_par[["GEN"]])
|
||||||
|
|
||||||
|
# 8. info = TRUE with parallel does not produce per-column worker messages
|
||||||
|
# (messages should only appear in the main process, not duplicated from workers)
|
||||||
|
msgs <- capture.output(
|
||||||
|
suppressWarnings(as.sir(df_par, col_mo = "mo", info = TRUE, parallel = TRUE)),
|
||||||
|
type = "message"
|
||||||
|
)
|
||||||
|
# each AB column name should appear at most once in all messages combined
|
||||||
|
for (ab_nm in c("AMC", "GEN", "CIP", "PEN")) {
|
||||||
|
n_mentions <- sum(grepl(ab_nm, msgs, fixed = TRUE))
|
||||||
|
expect_lte(n_mentions, 1L)
|
||||||
|
}
|
||||||
|
future::plan(future::sequential)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user