|
2 | 2 |
|
3 | 3 | skip_on_cran() |
4 | 4 |
|
| 5 | +local_empty_compiler_probe_cache <- function(envir = parent.frame()) { |
| 6 | + cache <- get0( |
| 7 | + "quickr_compiler_probe_cache", |
| 8 | + envir = asNamespace("quickr"), |
| 9 | + inherits = FALSE |
| 10 | + ) |
| 11 | + if (is.null(cache)) { |
| 12 | + return(invisible(NULL)) |
| 13 | + } |
| 14 | + |
| 15 | + old <- as.list.environment(cache, all.names = TRUE) |
| 16 | + withr::defer( |
| 17 | + { |
| 18 | + entries <- ls(envir = cache, all.names = TRUE) |
| 19 | + if (length(entries)) { |
| 20 | + rm(list = entries, envir = cache) |
| 21 | + } |
| 22 | + list2env(old, envir = cache) |
| 23 | + }, |
| 24 | + envir = envir |
| 25 | + ) |
| 26 | + |
| 27 | + entries <- ls(envir = cache, all.names = TRUE) |
| 28 | + if (length(entries)) { |
| 29 | + rm(list = entries, envir = cache) |
| 30 | + } |
| 31 | + invisible(NULL) |
| 32 | +} |
| 33 | + |
5 | 34 | test_that("quickr_r_cmd_config_value captures only stdout", { |
6 | 35 | expect_identical( |
7 | 36 | deparse(formals(quickr:::quickr_r_cmd_config_value)$system2), |
@@ -49,6 +78,28 @@ test_that("quickr_r_cmd_config_value returns empty on command failure", { |
49 | 78 | ) |
50 | 79 | }) |
51 | 80 |
|
| 81 | +test_that("R CMD config probe distinguishes empty values from errors", { |
| 82 | + empty_value <- function(...) character() |
| 83 | + expect_identical( |
| 84 | + quickr:::quickr_r_cmd_config_probe( |
| 85 | + "CC", |
| 86 | + r_cmd = "R", |
| 87 | + system2 = empty_value |
| 88 | + ), |
| 89 | + list(value = "", ok = TRUE) |
| 90 | + ) |
| 91 | + |
| 92 | + error_value <- function(...) "ERROR: no information for variable 'CC'" |
| 93 | + expect_identical( |
| 94 | + quickr:::quickr_r_cmd_config_probe( |
| 95 | + "CC", |
| 96 | + r_cmd = "R", |
| 97 | + system2 = error_value |
| 98 | + ), |
| 99 | + list(value = "", ok = FALSE) |
| 100 | + ) |
| 101 | +}) |
| 102 | + |
52 | 103 | test_that("quickr_flang_path prefers flang-new", { |
53 | 104 | which_stub <- function(x) { |
54 | 105 | if (x == "flang-new") { |
@@ -459,3 +510,67 @@ test_that("compile cleans existing build directories and reports failures", { |
459 | 510 | expect_true(dir.exists(build_dir)) |
460 | 511 | expect_false(file.exists(file.path(build_dir, "stale.txt"))) |
461 | 512 | }) |
| 513 | + |
| 514 | +test_that("quick reuses successful R CMD config probes", { |
| 515 | + local_empty_compiler_probe_cache() |
| 516 | + withr::local_options(quickr.fortran_compiler = "gfortran") |
| 517 | + |
| 518 | + probe <- quickr_r_cmd_config_probe |
| 519 | + events <- list() |
| 520 | + local_mocked_bindings( |
| 521 | + quickr_r_cmd_config_probe = function(name, ...) { |
| 522 | + result <- probe(name, ...) |
| 523 | + events[[length(events) + 1L]] <<- list(name = name, ok = result$ok) |
| 524 | + result |
| 525 | + }, |
| 526 | + .package = "quickr" |
| 527 | + ) |
| 528 | + |
| 529 | + fn <- function(x) { |
| 530 | + declare(type(x = double(1))) |
| 531 | + x + 1 |
| 532 | + } |
| 533 | + |
| 534 | + expect_quick_identical(fn, 1) |
| 535 | + first_events <- events |
| 536 | + expect_quick_identical(fn, 3) |
| 537 | + |
| 538 | + successful <- unique(vapply( |
| 539 | + first_events[vapply(first_events, `[[`, logical(1), "ok")], |
| 540 | + `[[`, |
| 541 | + character(1), |
| 542 | + "name" |
| 543 | + )) |
| 544 | + later <- events[seq_along(events) > length(first_events)] |
| 545 | + later_names <- vapply(later, `[[`, character(1), "name") |
| 546 | + expect_length(intersect(successful, later_names), 0L) |
| 547 | +}) |
| 548 | + |
| 549 | +test_that("quick retries failed R CMD config probes", { |
| 550 | + local_empty_compiler_probe_cache() |
| 551 | + withr::local_options(quickr.fortran_compiler = "gfortran") |
| 552 | + |
| 553 | + probe <- quickr_r_cmd_config_probe |
| 554 | + blas_calls <- 0L |
| 555 | + local_mocked_bindings( |
| 556 | + quickr_r_cmd_config_probe = function(name, ...) { |
| 557 | + if (identical(name, "BLAS_LIBS")) { |
| 558 | + blas_calls <<- blas_calls + 1L |
| 559 | + if (blas_calls == 1L) { |
| 560 | + return(list(value = "", ok = FALSE)) |
| 561 | + } |
| 562 | + } |
| 563 | + probe(name, ...) |
| 564 | + }, |
| 565 | + .package = "quickr" |
| 566 | + ) |
| 567 | + |
| 568 | + fn <- function(x) { |
| 569 | + declare(type(x = double(1))) |
| 570 | + x + 1 |
| 571 | + } |
| 572 | + |
| 573 | + expect_quick_identical(fn, 1) |
| 574 | + expect_quick_identical(fn, 3) |
| 575 | + expect_identical(blas_calls, 2L) |
| 576 | +}) |
0 commit comments