Nothing
.gc_stress_enabled <- function() {
# Never run on CRAN even if the opt-in env var is somehow set on a CRAN
# machine: `NOT_CRAN` is conventionally "true" only in interactive / CI
# contexts, so treating a missing / non-"true" value as "this is CRAN"
# gives belt-and-suspenders protection alongside the skip_on_cran() call
# inside `.skip_if_no_gc_stress()`.
if(!identical(Sys.getenv("NOT_CRAN"), "true")) return(FALSE)
gc_stress <- tolower(Sys.getenv("IMMUTABLES_GC_STRESS", unset = "0"))
gc_stress %in% c("1", "true", "yes", "on")
}
.skip_if_no_gc_stress <- function() {
testthat::skip_on_cran()
if(!isTRUE(.gc_cpp_run$enabled)) {
testthat::skip("Set IMMUTABLES_GC_STRESS=1 to run GC torture regression.")
}
}
.run_gc_stress_suite <- function() {
if(!.gc_stress_enabled()) {
return(list(enabled = FALSE, setup_error = NULL, results = list()))
}
results <- list()
setup_error <- NULL
tryCatch({
old_cpp <- getOption("immutables.use_cpp")
options(immutables.use_cpp = FALSE)
on.exit({
if(is.null(old_cpp)) {
options(immutables.use_cpp = NULL)
} else {
options(immutables.use_cpp = old_cpp)
}
}, add = TRUE)
base_plain <- as_flexseq(as.list(1:8))
ms <- attr(base_plain, "monoids", exact = TRUE)
base_names <- paste0("k", seq_len(8))
x_oms <- as_ordered_sequence(list("aa", "bb", "c", "ddd"), keys = c(2, 2, 1, 3))
ms_oms <- attr(x_oms, "monoids", exact = TRUE)
key_type_oms <- attr(x_oms, "oms_key_type", exact = TRUE)
x_ivx <- as_interval_index(list("a", "b", "c"), start = c(1, 2, 2), end = c(3, 2, 4), default_query_bounds = "[]")
q_num <- priority_queue("a", "b", "c", priorities = c(2, 1, 3))
q_date <- priority_queue(
"d1", "d2", "d3",
priorities = as.Date(c("2020-01-03", "2020-01-01", "2020-01-02"))
)
x_ord_num <- as_ordered_sequence(list("aa", "bb", "cc"), keys = c(2, 1, 2))
x_ord_date <- as_ordered_sequence(
list("aa", "bb", "cc"),
keys = as.Date(c("2020-01-02", "2020-01-01", "2020-01-02"))
)
options(immutables.use_cpp = TRUE)
old_torture <- gctorture2(1, inhibit_release = FALSE)
on.exit(gctorture2(old_torture, inhibit_release = FALSE), add = TRUE)
step <- function(label, expr) {
results[[label]] <<- tryCatch(
{
force(expr)
NULL
},
error = function(e) conditionMessage(e)
)
invisible(NULL)
}
t <- NULL
step("ft_cpp_tree_from", t <- .ft_cpp_tree_from(as.list(1:8), ms))
step("ft_cpp_tree_from_prepared", .ft_cpp_tree_from_prepared(as.list(1:8), base_names, ms))
step("ft_cpp_tree_from_sorted", .ft_cpp_tree_from_sorted(as.list(1:8), ms))
if(is.null(results[["ft_cpp_tree_from"]])) {
step("ft_cpp_add_right", t <- .ft_cpp_add_right(t, 9, ms))
step("ft_cpp_add_left", t <- .ft_cpp_add_left(t, 0, ms))
} else {
results[["ft_cpp_add_right"]] <- "skipped because ft_cpp_tree_from failed"
results[["ft_cpp_add_left"]] <- "skipped because ft_cpp_tree_from failed"
}
step("ft_cpp_concat", .ft_cpp_concat(base_plain, base_plain, ms))
step("ft_cpp_locate", .ft_cpp_locate(base_plain, function(v) v >= 4, ms, ".size", 0))
step("ft_cpp_split_tree", .ft_cpp_split_tree(base_plain, function(v) v >= 4, ms, ".size", 0))
step("ft_cpp_oms_insert", .ft_cpp_oms_insert(x_oms, list(value = "new", key = 2), ms_oms, key_type_oms))
step("insert", insert(x_oms, "newer", key = 2))
step("insert_interval_index", insert(x_ivx, "newer", start = 2, end = 5))
step("peek_point_interval_index", peek_all_point(x_ivx, 2))
step("pop_point_interval_index", pop_all_point(x_ivx, 2))
step("peek_overlaps_interval_index", peek_all_overlaps(x_ivx, 2, 3))
step("peek_containing_interval_index", peek_all_containing(x_ivx, 2, 3))
step("peek_within_interval_index", peek_all_within(x_ivx, 2, 3))
step("pq_numeric_peek_min_max", {
invisible(peek_min(q_num))
invisible(peek_max(q_num))
})
step("pq_numeric_pop_min_insert", {
p1 <- pop_min(q_num)
q2 <- insert(p1$remaining, "x", priority = 1)
invisible(peek_min(q2))
invisible(peek_max(q2))
})
step("pq_date_peek_pop_insert", {
invisible(peek_min(q_date))
invisible(peek_max(q_date))
p1 <- pop_min(q_date)
q2 <- insert(p1$remaining, "d4", priority = as.Date("2020-01-05"))
invisible(peek_min(q2))
invisible(peek_max(q2))
})
step("ordered_bounds_numeric", {
invisible(lower_bound(x_ord_num, 2))
invisible(upper_bound(x_ord_num, 2))
})
step("ordered_bounds_date", {
k <- as.Date("2020-01-02")
invisible(lower_bound(x_ord_date, k))
invisible(upper_bound(x_ord_date, k))
})
}, error = function(e) {
setup_error <<- conditionMessage(e)
})
list(enabled = TRUE, setup_error = setup_error, results = results)
}
.gc_cpp_run <- .run_gc_stress_suite()
.expect_step_ok <- function(label) {
.skip_if_no_gc_stress()
if(!is.null(.gc_cpp_run$setup_error)) {
testthat::fail(sprintf("GC stress suite setup failed: %s", .gc_cpp_run$setup_error))
}
err <- .gc_cpp_run$results[[label]]
if(is.null(err)) {
testthat::succeed()
} else {
testthat::fail(sprintf("%s failed: %s", label, err))
}
}
testthat::test_that("C++ tree builders survive GC torture", {
.expect_step_ok("ft_cpp_tree_from")
.expect_step_ok("ft_cpp_tree_from_prepared")
.expect_step_ok("ft_cpp_tree_from_sorted")
})
testthat::test_that("C++ core tree ops survive GC torture", {
.expect_step_ok("ft_cpp_add_right")
.expect_step_ok("ft_cpp_add_left")
.expect_step_ok("ft_cpp_concat")
.expect_step_ok("ft_cpp_locate")
.expect_step_ok("ft_cpp_split_tree")
})
testthat::test_that("C++ OMS primitives survive GC torture", {
.expect_step_ok("ft_cpp_oms_insert")
})
testthat::test_that("OMS public APIs survive GC torture", {
.expect_step_ok("insert")
})
testthat::test_that("interval_index public APIs survive GC torture", {
.expect_step_ok("insert_interval_index")
.expect_step_ok("peek_point_interval_index")
.expect_step_ok("pop_point_interval_index")
.expect_step_ok("peek_overlaps_interval_index")
.expect_step_ok("peek_containing_interval_index")
.expect_step_ok("peek_within_interval_index")
})
testthat::test_that("priority_queue public APIs survive GC torture", {
.expect_step_ok("pq_numeric_peek_min_max")
.expect_step_ok("pq_numeric_pop_min_insert")
.expect_step_ok("pq_date_peek_pop_insert")
})
testthat::test_that("ordered bounds survive GC torture", {
.expect_step_ok("ordered_bounds_numeric")
.expect_step_ok("ordered_bounds_date")
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.