diff --git a/DESCRIPTION b/DESCRIPTION index b66417a4..a8afa544 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -98,5 +98,5 @@ VignetteBuilder: Encoding: UTF-8 LazyData: true Roxygen: list(markdown = TRUE) -RoxygenNote: 7.3.1 +RoxygenNote: 7.3.2 SystemRequirements: bbi (>= 3.0.2) diff --git a/R/aaa.R b/R/aaa.R index 63007c68..732ffe17 100644 --- a/R/aaa.R +++ b/R/aaa.R @@ -5,7 +5,7 @@ BBI_DEFAULT_PATH <- if (ON_WINDOWS) { "bbi" } -BBI_VALID_MODES <- c("local", "sge") +BBI_VALID_MODES <- c("local", "sge", "slurm") CACHE_ENV <- new.env(parent = emptyenv()) CACHE_ENV$bbi_exe_paths <- list() diff --git a/R/submit-model.R b/R/submit-model.R index 7311c7a9..a871b181 100644 --- a/R/submit-model.R +++ b/R/submit-model.R @@ -30,9 +30,9 @@ #' 4)`. Run [print_bbi_args()] to see valid arguments. Note that bbr does #' not support changing the output directory (including through the model or #' global YAML files). -#' @param .mode Either `"sge"`, the default, to submit model(s) to the grid or -#' `"local"` for local execution. This can be passed directly to this argument -#' or set globally with `options("bbr.bbi_exe_mode")`. +#' @param .mode Mode for model submission: "local", "sge", or "slurm". If +#' unspecified, the value is set to the value of the `bbr.bbi_exe_mode` +#' option. This option defaults to "sge" on Linux and "local" otherwise. #' @param ... args passed through to `bbi_exec()` #' @param .overwrite Logical to specify whether or not to overwrite existing #' model output from a previous run. If `NULL`, the default, will defer to @@ -356,6 +356,38 @@ check_mode_argument <- function(.mode) { stop(BBI_EXE_MODE_INVALID_ERR_MSG, call. = FALSE) } + if (isTRUE(getOption("bbr.DEV_skip_system_mode_checks"))) { + # ^ Allow dry-run tests to skip the system mode checks. + return(invisible(TRUE)) + } + + # All of the remaining checks depend on system details. + + if (identical(.mode, "slurm") && !test_bbi_version(.min_version = "3.4.0")) { + stop( + "Installed bbi version is ", bbi_version(), + ", but .mode='slurm' requires at least version 3.4.0" + ) + } + + if (identical(.mode, "sge")) { + qsub <- unname(Sys.which("qsub")) + if (identical(qsub, "")) { + stop(".mode='sge' but qsub is not available on system") + } + + # This guard is Metworx (or really ParallelCluster) specific. Slurm ships + # with a qsub shim. That leads to a confusing situation where 'bbi nonmem + # run sge ...' will not abort upfront, but the execution doesn't entirely + # match the expected behavior (especially under --parallel). + if (identical(qsub, "/opt/slurm/bin/qsub")) { + stop( + ".mode is 'sge' but qsub points to Slurm shim.\n", + "Instead set .mode to 'slurm' (requires bbi 3.4.0 or later)\n" + ) + } + } + return(invisible(TRUE)) } diff --git a/man/simulate.Rd b/man/simulate.Rd index b95b16ce..cf15870e 100644 --- a/man/simulate.Rd +++ b/man/simulate.Rd @@ -60,9 +60,9 @@ formatted like \code{list("nm_version" = "nm74gf_nmfe", "json" = T, "threads" = not support changing the output directory (including through the model or global YAML files).} -\item{.mode}{Either \code{"sge"}, the default, to submit model(s) to the grid or -\code{"local"} for local execution. This can be passed directly to this argument -or set globally with \code{options("bbr.bbi_exe_mode")}.} +\item{.mode}{Mode for model submission: "local", "sge", or "slurm". If +unspecified, the value is set to the value of the \code{bbr.bbi_exe_mode} +option. This option defaults to "sge" on Linux and "local" otherwise.} \item{...}{args passed through to \code{bbi_exec()}} diff --git a/man/submit_model.Rd b/man/submit_model.Rd index c9d753d1..65f9d114 100644 --- a/man/submit_model.Rd +++ b/man/submit_model.Rd @@ -60,9 +60,9 @@ formatted like \code{list("nm_version" = "nm74gf_nmfe", "json" = T, "threads" = not support changing the output directory (including through the model or global YAML files).} -\item{.mode}{Either \code{"sge"}, the default, to submit model(s) to the grid or -\code{"local"} for local execution. This can be passed directly to this argument -or set globally with \code{options("bbr.bbi_exe_mode")}.} +\item{.mode}{Mode for model submission: "local", "sge", or "slurm". If +unspecified, the value is set to the value of the \code{bbr.bbi_exe_mode} +option. This option defaults to "sge" on Linux and "local" otherwise.} \item{...}{args passed through to \code{bbi_exec()}} diff --git a/man/submit_models.Rd b/man/submit_models.Rd index 7b2d880a..2ac1937d 100644 --- a/man/submit_models.Rd +++ b/man/submit_models.Rd @@ -35,9 +35,9 @@ formatted like \code{list("nm_version" = "nm74gf_nmfe", "json" = T, "threads" = not support changing the output directory (including through the model or global YAML files).} -\item{.mode}{Either \code{"sge"}, the default, to submit model(s) to the grid or -\code{"local"} for local execution. This can be passed directly to this argument -or set globally with \code{options("bbr.bbi_exe_mode")}.} +\item{.mode}{Mode for model submission: "local", "sge", or "slurm". If +unspecified, the value is set to the value of the \code{bbr.bbi_exe_mode} +option. This option defaults to "sge" on Linux and "local" otherwise.} \item{...}{args passed through to \code{bbi_exec()}} diff --git a/tests/testthat/test-print.R b/tests/testthat/test-print.R index 85a815fa..1ca945c7 100644 --- a/tests/testthat/test-print.R +++ b/tests/testthat/test-print.R @@ -38,6 +38,8 @@ withr::with_options(list(bbr.bbi_exe_path = read_bbi_path()), { fs::dir_create(temp_dir) on.exit(fs::dir_delete(temp_dir)) + withr::local_options(list(bbr.DEV_skip_system_mode_checks = TRUE)) + readr::write_file("created_by: test-print", file.path(temp_dir, "bbi.yaml")) mods <- purrr::map(1:50, ~copy_model_from(MOD1, file.path("print-test", .x))) diff --git a/tests/testthat/test-submit-model.R b/tests/testthat/test-submit-model.R index 565cacd4..3624a2cc 100644 --- a/tests/testthat/test-submit-model.R +++ b/tests/testthat/test-submit-model.R @@ -1,117 +1,158 @@ -context("submit_model(.dry_run=T)") +context("submit_model(.dry_run=TRUE)") ################################### # testing single model submission ################################### - - model_dir <- ABS_MODEL_DIR mod_ctl_path <- file.path(model_dir, CTL_FILENAME) # create fake bbi.yaml readr::write_file("created_by: test-submit-model", file.path(model_dir, "bbi.yaml")) -on.exit({ fs::file_delete(file.path(model_dir, "bbi.yaml"))}) - -withr::with_options(list(bbr.bbi_exe_path = read_bbi_path()), { - default_mode <- getOption("bbr.bbi_exe_mode") - cmd_prefix <- paste("cd", model_dir, ";", - read_bbi_path(), "nonmem", "run", - default_mode) - test_that("submit_model(.dry_run=T) returns correct command string [BBR-SBMT-001]", - { - - # correctly parsing yaml - expect_identical( - submit_model(MOD1, .dry_run = T)[[PROC_CALL]], - as.character(glue("{cmd_prefix} {mod_ctl_path} --overwrite --threads=4 --parallel")) - ) - - # switch to local mode - expect_identical( - submit_model(MOD1, .mode = "local", .dry_run = T)[[PROC_CALL]], - as.character(glue("cd {model_dir} ; {read_bbi_path()} nonmem run local {mod_ctl_path} --overwrite --threads=4 --parallel")) - ) - - # over-riding yaml arg with passed args - expect_identical( - submit_model(MOD1, - .bbi_args=list( - "json" = T, - "threads" = 2, - "nm_version" = "nm74" - ), - .dry_run = T)[[PROC_CALL]], - as.character(glue("{cmd_prefix} {mod_ctl_path} --overwrite --threads=2 --json --nm_version=nm74 --parallel")) - ) - }) - - test_that("submit_model(.dry_run=T) with bbi_nonmem_model object parses correctly [BBR-SBMT-002]", - { - # correctly parsing yaml - expect_identical( - submit_model(MOD1, .dry_run = T)[[PROC_CALL]], - as.character(glue("{cmd_prefix} {mod_ctl_path} --overwrite --threads=4 --parallel")) - ) - - # over-riding yaml arg with passed arg - expect_identical( - submit_model(MOD1, list(threads=2), .dry_run = T)[[PROC_CALL]], - as.character(glue("{cmd_prefix} {mod_ctl_path} --overwrite --threads=2 --parallel")) - ) - }) - - test_that("submit_model() creates correct call for non-NULL .config_path [BBR-SBMT-003]", { - - temp_config <- tempfile(fileext = ".yaml") - readr::write_file("foo", temp_config) - temp_config <- normalizePath(temp_config) - on.exit(fs::file_delete(temp_config)) - - res <- submit_model(MOD1, .config_path = temp_config, .dry_run = TRUE) - expect_identical( - res[[PROC_CALL]], - as.character( - glue::glue( - "{cmd_prefix} {mod_ctl_path} --overwrite --threads=4 --parallel", - "--config={temp_config}", - .sep = " " - ) +on.exit(fs::file_delete(file.path(model_dir, "bbi.yaml"))) + +default_mode <- getOption("bbr.bbi_exe_mode") +cmd_prefix <- paste("cd", model_dir, ";", read_bbi_path(), "nonmem", "run") + +withr::local_options(list( + bbr.bbi_exe_path = read_bbi_path(), + bbr.DEV_skip_system_mode_checks = TRUE +)) + +test_that("submit_model(.dry_run=TRUE) returns correct command string", { + # correctly parsing yaml + expect_identical( + submit_model(MOD1, .dry_run = TRUE)[[PROC_CALL]], + as.character(glue("{cmd_prefix} {default_mode} {mod_ctl_path} --overwrite --threads=4 --parallel")) + ) + + # over-riding yaml arg with passed args + expect_identical( + submit_model(MOD1, + .bbi_args = list( + "json" = TRUE, + "threads" = 2, + "nm_version" = "nm74" + ), + .dry_run = TRUE + )[[PROC_CALL]], + as.character(glue("{cmd_prefix} {default_mode} {mod_ctl_path} --overwrite --threads=2 --json --nm_version=nm74 --parallel")) + ) +}) + +test_that("submit_model(.dry_run=TRUE) with bbi_nonmem_model object parses correctly", { + # correctly parsing yaml + expect_identical( + submit_model(MOD1, .dry_run = TRUE)[[PROC_CALL]], + as.character(glue("{cmd_prefix} {default_mode} {mod_ctl_path} --overwrite --threads=4 --parallel")) + ) + + # over-riding yaml arg with passed arg + expect_identical( + submit_model(MOD1, list(threads = 2), .dry_run = TRUE)[[PROC_CALL]], + as.character(glue("{cmd_prefix} {default_mode} {mod_ctl_path} --overwrite --threads=2 --parallel")) + ) +}) + +test_that("submit_model() creates correct call for non-NULL .config_path", { + temp_config <- tempfile(fileext = ".yaml") + readr::write_file("foo", temp_config) + temp_config <- normalizePath(temp_config) + on.exit(fs::file_delete(temp_config)) + + res <- submit_model(MOD1, .config_path = temp_config, .dry_run = TRUE) + expect_identical( + res[[PROC_CALL]], + as.character( + glue( + "{cmd_prefix} {default_mode} {mod_ctl_path} --overwrite --threads=4 --parallel", + "--config={temp_config}", + .sep = " " ) ) - }) + ) +}) - test_that("submit_model() throws an error if passed `output_dir` bbi arg [BBR-SBMT-004]", { - expect_error( - submit_model(MOD1, .bbi_args = list(output_dir = "foo")), - "is not a valid argument" - ) - }) +test_that("submit_model() throws an error if passed `output_dir` bbi arg", { + expect_error( + submit_model(MOD1, .bbi_args = list(output_dir = "foo")), + "is not a valid argument" + ) +}) - test_that("submit_model(.mode) inherits option [BBR-SBMT-005]", { - other_mode <- switch(default_mode, sge = "local", "sge") - withr::with_options(list(bbr.bbi_exe_mode = other_mode), { - expect_identical( - submit_model(MOD1, .dry_run = T)[[PROC_CALL]], - as.character(glue("cd {model_dir} ; {read_bbi_path()} nonmem run {other_mode} {mod_ctl_path} --overwrite --threads=4 --parallel")) - ) - }) - }) +test_that("submit_model() .mode argument overrides bbr.bbi_exe_mode default", { + other_mode <- if (identical(default_mode, "local")) "slurm" else "local" + expect_identical( + submit_model(MOD1, .mode = other_mode, .dry_run = TRUE)[[PROC_CALL]], + as.character(glue("{cmd_prefix} {other_mode} {mod_ctl_path} --overwrite --threads=4 --parallel")) + ) +}) - test_that("submit_model(.mode) errors when NULL [BBR-SBMT-006]", { - withr::with_options(list(bbr.bbi_exe_mode = NULL), { - expect_error( - submit_model(MOD1, .dry_run = T), - regexp = "Nothing was passed.+mode" - ) - }) +test_that("submit_model(.mode) inherits option", { + other_mode <- if (identical(default_mode, "local")) "slurm" else "local" + withr::with_options(list(bbr.bbi_exe_mode = other_mode), { + expect_identical( + submit_model(MOD1, .dry_run = TRUE)[[PROC_CALL]], + as.character(glue("{cmd_prefix} {other_mode} {mod_ctl_path} --overwrite --threads=4 --parallel")) + ) }) +}) - test_that("submit_model(.mode) errors when invalid [BBR-SBMT-007]", { +test_that("submit_model(.mode) errors when NULL", { + withr::with_options(list(bbr.bbi_exe_mode = NULL), { expect_error( - submit_model(MOD1, .dry_run = T, .mode = "naw"), - regexp = "Invalid value passed.+mode" + submit_model(MOD1, .dry_run = TRUE), + regexp = "Nothing was passed.+mode" ) }) }) +test_that("submit_model(.mode) errors when invalid", { + expect_error( + submit_model(MOD1, .dry_run = TRUE, .mode = "naw"), + regexp = "Invalid value passed.+mode" + ) +}) + +test_that("submit_model aborts if .mode='sge' is used with Slurm's qsub", { + skip_if_old_bbi("3.4.0") + + sbatch <- unname(Sys.which("sbatch")) + if (identical(sbatch, "") || identical(Sys.getenv("METWORX_VERSION"), "")) { + skip("not on Metworx with Slurm") + } + + withr::local_options(list(bbr.DEV_skip_system_mode_checks = FALSE)) + + expect_error( + submit_model(MOD1, .dry_run = TRUE, .mode = "sge"), + regexp = "Slurm shim" + ) +}) + +test_that("submit_model aborts if .mode='sge' and qsub is not available", { + if (!identical(unname(Sys.which("qsub")), "")) { + skip("qsub is available") + } + + withr::local_options(list(bbr.DEV_skip_system_mode_checks = FALSE)) + + expect_error( + submit_model(MOD1, .dry_run = TRUE, .mode = "sge"), + regexp = "qsub is not available" + ) +}) + +test_that("submit_model aborts if .mode='slurm' is used with incompatible bbi", { + if (test_bbi_version(read_bbi_path(), "3.4.0")) { + skip("installed bbi version is compatible with Slurm") + } + + withr::local_options(list(bbr.DEV_skip_system_mode_checks = FALSE)) + + expect_error( + submit_model(MOD1, .dry_run = TRUE, .mode = "slurm"), + regexp = "at least version 3.4.0", + fixed = TRUE + ) +}) diff --git a/tests/testthat/test-submit-models.R b/tests/testthat/test-submit-models.R index 045b401a..c7a9a4c1 100644 --- a/tests/testthat/test-submit-models.R +++ b/tests/testthat/test-submit-models.R @@ -1,199 +1,200 @@ -context("submit_models(.dry_run=T)") +context("submit_models(.dry_run=TRUE)") ##################################### # testing multiple model submission ##################################### -withr::with_options(list(bbr.bbi_exe_path = read_bbi_path()), { +withr::local_options(list( + bbr.bbi_exe_path = read_bbi_path(), + bbr.DEV_skip_system_mode_checks = TRUE +)) + +# create fake bbi.yaml +readr::write_file("created_by: test-submit-models", file.path(MODEL_DIR, "bbi.yaml")) +on.exit(fs::file_delete(file.path(MODEL_DIR, "bbi.yaml"))) + +model_dir <- ABS_MODEL_DIR +mod_ctl_path <- purrr::map_chr( + as.character(1:3), + ~ file.path(model_dir, fs::path_ext_set(., "ctl")) +) + +default_mode <- getOption("bbr.bbi_exe_mode") +cmd_prefix <- paste("cd", model_dir, ";", read_bbi_path(), "nonmem", "run") + +test_that("submit_models(.dry_run=TRUE) with list input simple", { + # copy to two new models + mod2 <- copy_model_from(MOD1, 2) + mod3 <- copy_model_from(MOD1, 3) + on.exit(cleanup()) + + .mods <- list(MOD1, mod2, mod3) + + # submit models + proc_list <- submit_models(.mods, .dry_run = TRUE) + expect_true(all(purrr::map_lgl(proc_list, function(.proc) { + "bbi_process" %in% class(.proc) + }))) + + # check that there is only one distinct arg set + expect_equal(length(proc_list), 1) + + # check call + expect_identical( + proc_list[[1]][[PROC_CALL]], + as.character(glue("{cmd_prefix} {default_mode} {paste(mod_ctl_path, collapse = ' ')} --overwrite --parallel --threads=4")) + ) +}) + +test_that("submit_models(.dry_run=TRUE) with list input, 2 arg sets", { + # copy to two new models + mod2 <- copy_model_from(MOD1, 2) %>% add_bbi_args(list(threads = 3)) + mod3 <- copy_model_from(MOD1, 3) %>% add_bbi_args(list(clean_lvl = 2)) + on.exit(cleanup()) + + .mods <- list(MOD1, mod2, mod3) + + # submit and test that passed .bbi_args override args in object + proc_list <- submit_models(.mods, .dry_run = TRUE, .bbi_args = list(threads = 1)) + expect_true(all(purrr::map_lgl(proc_list, function(.proc) { + "bbi_process" %in% class(.proc) + }))) + + # check that there are two distinct arg sets + expect_equal(length(proc_list), 2) + + # check each call + expect_identical( + proc_list[[1]][[PROC_CALL]], + as.character( + glue( + "{cmd_prefix} {default_mode} {mod_ctl_path[1]} {mod_ctl_path[2]} --overwrite --threads=1" + ) + ) + ) + expect_identical( + proc_list[[2]][[PROC_CALL]], + as.character( + glue("{cmd_prefix} {default_mode} {mod_ctl_path[3]} --clean_lvl=2 --overwrite --threads=1") + ) + ) +}) - # create fake bbi.yaml - readr::write_file("created_by: test-submit-models", file.path(MODEL_DIR, "bbi.yaml")) - on.exit({ fs::file_delete(file.path(MODEL_DIR, "bbi.yaml")) }) +test_that("submit_models() works for models in different directories", { + new_dir <- file.path(ABS_MODEL_DIR, "level2") + fs::dir_create(new_dir) - model_dir <- ABS_MODEL_DIR - mod_ctl_path <- purrr::map_chr( - as.character(1:3), - ~ file.path(model_dir, fs::path_ext_set(., "ctl")) + # create fake bbi.yaml + readr::write_file("created_by: test-submit-models", file.path(new_dir, "bbi.yaml")) + on.exit(fs::file_delete(file.path(new_dir, "bbi.yaml"))) + on.exit(cleanup()) + + # TODO: use test helper functions, e.g., create_all_models(), once the + # model_directory option is deprecated + mod2 <- copy_model_from( + MOD1, + file.path(new_dir, MOD_ID), + "created by test-submit-models.R" ) + proc_list <- submit_models(list(MOD1, mod2), .dry_run = TRUE) - default_mode <- getOption("bbr.bbi_exe_mode") - cmd_prefix <- paste("cd", model_dir, ";", - read_bbi_path(), "nonmem", "run", - default_mode) - - test_that("submit_models(.dry_run=T) with list input simple [BBR-SBMT-008]", - { - # copy to two new models - mod2 <- copy_model_from(MOD1, 2) - mod3 <- copy_model_from(MOD1, 3) - on.exit({ cleanup() }) - - .mods <- list(MOD1, mod2, mod3) - - # submit models - proc_list <- submit_models(.mods, .dry_run = T) - expect_true(all(purrr::map_lgl(proc_list, function(.proc) { "bbi_process" %in% class(.proc) }))) - - # check that there is only one distinct arg set - expect_equal(length(proc_list), 1) - - # check call - expect_identical( - proc_list[[1]][[PROC_CALL]], - as.character(glue("{cmd_prefix} {paste(mod_ctl_path, collapse = ' ')} --overwrite --parallel --threads=4")) - ) - }) - - test_that("submit_models(.dry_run=T) with list input, 2 arg sets [BBR-SBMT-010]", - { - # copy to two new models - mod2 <- copy_model_from(MOD1, 2) %>% add_bbi_args(list(threads = 3)) - mod3 <- copy_model_from(MOD1, 3) %>% add_bbi_args(list(clean_lvl = 2)) - on.exit({ cleanup() }) - - .mods <- list(MOD1, mod2, mod3) - - # submit and test that passed .bbi_args override args in object - proc_list <- submit_models(.mods, .dry_run = T, .bbi_args = list(threads = 1)) - expect_true(all(purrr::map_lgl(proc_list, function(.proc) { "bbi_process" %in% class(.proc) }))) - - # check that there are two distinct arg sets - expect_equal(length(proc_list), 2) - - # check each call - expect_identical( - proc_list[[1]][[PROC_CALL]], - as.character( - glue( - "{cmd_prefix} {mod_ctl_path[1]} {mod_ctl_path[2]} --overwrite --threads=1" - ) - ) - ) - expect_identical( - proc_list[[2]][[PROC_CALL]], - as.character( - glue("{cmd_prefix} {mod_ctl_path[3]} --clean_lvl=2 --overwrite --threads=1")) - ) - }) - - test_that("submit_models() works for models in different directories [BBR-SBMT-011]", { - new_dir <- file.path(ABS_MODEL_DIR, "level2") - fs::dir_create(new_dir) - - # create fake bbi.yaml - readr::write_file("created_by: test-submit-models", file.path(new_dir, "bbi.yaml")) - on.exit({ fs::file_delete(file.path(new_dir, "bbi.yaml")) }) - on.exit(cleanup()) - - # TODO: use test helper functions, e.g., create_all_models(), once the - # model_directory option is deprecated - mod2 <- copy_model_from( - MOD1, - file.path(new_dir, MOD_ID), - "created by test-submit-models.R" - ) - proc_list <- submit_models(list(MOD1, mod2), .dry_run = TRUE) + expect_equal(length(proc_list), 2L) +}) - expect_equal(length(proc_list), 2L) - }) +test_that("submit_models(.dry_run=TRUE) errors with bad input", { + # copy to two new models + mod2 <- copy_model_from(MOD1, 2) + mod3 <- copy_model_from(MOD1, 3) + on.exit(cleanup()) - test_that("submit_models(.dry_run=T) errors with bad input [BBR-SBMT-012]", - { - # copy to two new models - mod2 <- copy_model_from(MOD1, 2) - mod3 <- copy_model_from(MOD1, 3) - on.exit({ cleanup() }) - - # testing when one isn't a model - fake <- list(naw = 1) - .mods <- list(MOD1, mod2, mod3, fake) - - expect_error( - submit_models(.mods, .dry_run = T), - regexp = "must contain only model objects" - ) - - # testing two different kinds of models - class(fake) <- c(BBI_BASE_MODEL_CLASS, class(fake)) - fake[[YAML_MOD_TYPE]] <- "fake" - .mods <- list(MOD1, mod2, mod3, fake) - - expect_error( - submit_models(.mods, .dry_run = T), - regexp = "must contain all the same type of models" - ) - }) - - test_that("submit_models() works with non-NULL .config_path [BBR-SBMT-013]", { - temp_config <- tempfile(fileext = ".yaml") - readr::write_file("foo", temp_config) - temp_config <- normalizePath(temp_config) - on.exit(fs::file_delete(temp_config)) - - res <- submit_models( - list(MOD1), - .config_path = temp_config, - .dry_run = TRUE - ) + # testing when one isn't a model + fake <- list(naw = 1) + .mods <- list(MOD1, mod2, mod3, fake) - expect_identical( - res[[1L]][[PROC_CALL]], - as.character( - glue::glue( - "{cmd_prefix} {mod_ctl_path[[1L]]} --overwrite --parallel --threads=4", - "--config={temp_config}", - .sep = " " - ) - ) - ) - }) + expect_error( + submit_models(.mods, .dry_run = TRUE), + regexp = "must contain only model objects" + ) - test_that("submit_models() works if .bbi_args is empty [BBR-SBMT-014]", { - # set existing arguments to NULL via `.bbi_args` - res <- submit_models( - list(MOD1), - .bbi_args = list(overwrite = NULL, threads = NULL, parallel = TRUE), - .dry_run = TRUE - ) + # testing two different kinds of models + class(fake) <- c(BBI_BASE_MODEL_CLASS, class(fake)) + fake[[YAML_MOD_TYPE]] <- "fake" + .mods <- list(MOD1, mod2, mod3, fake) - expect_identical( - res[[1L]][[PROC_CALL]], - as.character( - glue::glue("{cmd_prefix} {mod_ctl_path[[1L]]} --parallel") + expect_error( + submit_models(.mods, .dry_run = TRUE), + regexp = "must contain all the same type of models" + ) +}) + +test_that("submit_models() works with non-NULL .config_path", { + temp_config <- tempfile(fileext = ".yaml") + readr::write_file("foo", temp_config) + temp_config <- normalizePath(temp_config) + on.exit(fs::file_delete(temp_config)) + + res <- submit_models( + list(MOD1), + .config_path = temp_config, + .dry_run = TRUE + ) + + expect_identical( + res[[1L]][[PROC_CALL]], + as.character( + glue( + "{cmd_prefix} {default_mode} {mod_ctl_path[[1L]]} --overwrite --parallel --threads=4", + "--config={temp_config}", + .sep = " " ) ) + ) +}) + +test_that("submit_models() works if .bbi_args is empty", { + # set existing arguments to NULL via `.bbi_args` + res <- submit_models( + list(MOD1), + .bbi_args = list(overwrite = NULL, threads = NULL, parallel = TRUE), + .dry_run = TRUE + ) - # now the case where the YAML file does not contain any CLI arguments - temp_mod_path <- create_temp_model() - mod <- read_model(temp_mod_path) - mod <- replace_all_bbi_args(mod, NULL) - - # create fake bbi.yaml - readr::write_file("created_by: test-submit-models", file.path(dirname(temp_mod_path), "bbi.yaml")) - on.exit({ fs::file_delete(file.path(dirname(temp_mod_path), "bbi.yaml")) }) + expect_identical( + res[[1L]][[PROC_CALL]], + as.character( + glue("{cmd_prefix} {default_mode} {mod_ctl_path[[1L]]} --parallel") + ) + ) - res <- submit_models(list(mod), .dry_run = TRUE) + # now the case where the YAML file does not contain any CLI arguments + temp_mod_path <- create_temp_model() + mod <- read_model(temp_mod_path) + mod <- replace_all_bbi_args(mod, NULL) - expect_identical( - res[[1L]][[PROC_CALL]], - as.character( - glue::glue( - "cd {dirname(temp_mod_path)} ;", - "{read_bbi_path()} nonmem run {default_mode} {fs::path_ext_set(temp_mod_path, 'ctl')}", - .sep = " " - ) + # create fake bbi.yaml + readr::write_file("created_by: test-submit-models", file.path(dirname(temp_mod_path), "bbi.yaml")) + on.exit(fs::file_delete(file.path(dirname(temp_mod_path), "bbi.yaml"))) + + res <- submit_models(list(mod), .dry_run = TRUE) + + expect_identical( + res[[1L]][[PROC_CALL]], + as.character( + glue( + "cd {dirname(temp_mod_path)} ;", + "{read_bbi_path()} nonmem run {default_mode} {fs::path_ext_set(temp_mod_path, 'ctl')}", + .sep = " " ) ) - }) + ) +}) - test_that("submit_models(.mode) inherits option [BBR-SBMT-015]", { - other_mode <- switch(default_mode, sge = "local", "sge") - withr::with_options(list(bbr.bbi_exe_mode = other_mode), { - expect_identical( - submit_models(list(MOD1), .dry_run = T)[[1]][[PROC_CALL]], - as.character(glue("cd {model_dir} ; {read_bbi_path()} nonmem run {other_mode} {ABS_CTL_PATH} --overwrite --parallel --threads=4")) - ) - }) +test_that("submit_models(.mode) inherits option", { + other_mode <- if (identical(default_mode, "local")) "slurm" else "local" + withr::with_options(list(bbr.bbi_exe_mode = other_mode), { + expect_identical( + submit_models(list(MOD1), .dry_run = TRUE)[[1]][[PROC_CALL]], + as.character(glue("{cmd_prefix} {other_mode} {ABS_CTL_PATH} --overwrite --parallel --threads=4")) + ) }) -}) # closing withr::with_options - +})