Nothing
# Tests for share() - zero-copy shared objects
test_that("share returns an ALTREP-backed shared vector for atomic inputs", {
x <- 1:100
shared <- share(x)
expect_true(is_shared_vector(shared))
expect_s3_class(shared, "shard_shared_vector")
info <- shared_info(shared)
expect_true(info$size > 0)
expect_true(!is.null(info$path))
})
test_that("share returns a shard_shared handle for non-shareable types", {
x <- letters
shared <- share(x)
expect_s3_class(shared, "shard_shared")
expect_true(shared$size > 0)
expect_true(!is.null(shared$path))
close(shared)
})
test_that("share and local round-trip preserves data", {
# Integer vector
x <- 1:100
shared <- share(x)
recovered <- materialize(shared)
expect_identical(x, recovered)
# Numeric vector
x <- rnorm(50)
shared <- share(x)
recovered <- materialize(shared)
expect_equal(x, recovered)
# Character vector
x <- letters
shared <- share(x)
recovered <- fetch(shared)
expect_identical(x, recovered)
close(shared)
# Logical vector
x <- c(TRUE, FALSE, TRUE, NA)
shared <- share(x)
recovered <- materialize(shared)
expect_identical(x, recovered)
})
test_that("share preserves matrix structure", {
mat <- matrix(1:20, nrow = 4, ncol = 5)
shared <- share(mat)
info <- shared_info(shared)
expect_equal(info$class_info$type, "matrix")
expect_equal(info$class_info$dim, c(4L, 5L))
recovered <- materialize(shared)
expect_identical(mat, recovered)
})
test_that("share preserves array structure", {
arr <- array(1:24, dim = c(2, 3, 4))
shared <- share(arr)
info <- shared_info(shared)
expect_equal(info$class_info$type, "array")
expect_equal(info$class_info$dim, c(2L, 3L, 4L))
recovered <- materialize(shared)
expect_identical(arr, recovered)
})
test_that("share preserves data.frame structure", {
df <- data.frame(
a = 1:5,
b = letters[1:5],
c = c(TRUE, FALSE, TRUE, FALSE, TRUE),
stringsAsFactors = FALSE
)
shared <- share(df)
expect_equal(shared$class_info$type, "data.frame")
expect_equal(shared$class_info$nrow, 5)
expect_equal(shared$class_info$ncol, 3)
recovered <- fetch(shared)
expect_identical(df, recovered)
close(shared)
})
test_that("share preserves list structure", {
lst <- list(
a = 1:5,
b = "hello",
c = list(nested = TRUE)
)
shared <- share(lst)
expect_equal(shared$class_info$type, "list")
expect_equal(shared$class_info$length, 3)
recovered <- fetch(shared)
expect_identical(lst, recovered)
close(shared)
})
test_that("share creates read-only segment by default", {
x <- 1:10
shared <- share(x)
info <- shared_info(shared)
expect_true(info$readonly)
})
test_that("share with readonly=FALSE creates writable segment", {
x <- 1:10
shared <- share(x, readonly = FALSE)
info <- shared_info(shared)
expect_false(info$readonly)
})
test_that("materialize is equivalent to fetch", {
x <- letters
shared <- share(x)
via_fetch <- fetch(shared)
via_materialize <- materialize(shared)
expect_identical(via_fetch, via_materialize)
close(shared)
})
test_that("materialize.default returns input unchanged", {
x <- 1:10
expect_identical(materialize(x), x)
y <- list(a = 1, b = 2)
expect_identical(materialize(y), y)
})
test_that("is_shared correctly identifies shared objects", {
x <- 1:10
shared <- share(x)
expect_true(is_shared(shared))
expect_false(is_shared(x))
expect_false(is_shared(NULL))
expect_false(is_shared(list()))
})
test_that("shared_info returns complete information", {
x <- matrix(1:20, nrow = 4)
shared <- share(x)
info <- shared_info(shared)
expect_true(is.list(info))
expect_true(!is.null(info$path))
expect_true(!is.null(info$backing))
expect_true(!is.null(info$size))
expect_true(!is.null(info$readonly))
expect_true(!is.null(info$class_info))
expect_true(!is.null(info$segment_info))
})
test_that("print.shard_shared works", {
x <- letters
shared <- share(x)
expect_output(print(shared), "shard_shared")
expect_output(print(shared), "Size:")
close(shared)
})
test_that("share handles large objects", {
# 1 million elements
x <- rnorm(1e6)
shared <- share(x)
info <- shared_info(shared)
expect_true(info$size >= 8e6) # At least 8 bytes per double
recovered <- materialize(shared)
expect_equal(x, recovered)
})
test_that("share_open can reopen existing shared segment", {
x <- letters
shared1 <- share(x)
path <- shared1$path
backing <- shared1$backing
size <- shared1$size
skip_if(is.null(path), "Path is NULL")
# Open the same segment
shared2 <- share_open(path, backing = backing, size = size)
# Read from reopened segment
recovered <- fetch(shared2)
expect_identical(x, recovered)
# Close in order (shared2 doesn't unlink)
close(shared2)
close(shared1)
})
test_that("share respects backing type", {
x <- letters
# Test mmap backing
shared_mmap <- share(x, backing = "mmap")
expect_equal(shared_mmap$backing, "mmap")
close(shared_mmap)
# Test auto backing
shared_auto <- share(x, backing = "auto")
expect_s3_class(shared_auto, "shard_shared")
close(shared_auto)
})
test_that("close releases resources", {
x <- letters
shared <- share(x)
path <- shared$path
# Close should work without error
expect_silent(close(shared))
# Segment should be gone (file-backed)
if (!is.null(path) && shared$backing == "mmap") {
expect_false(file.exists(path))
}
})
test_that("share handles empty vectors", {
x <- integer(0)
shared <- share(x)
recovered <- materialize(shared)
expect_identical(x, recovered)
})
test_that("share handles zero-length vectors of all types", {
# Double
x <- double(0)
shared <- share(x)
recovered <- materialize(shared)
expect_identical(x, recovered)
# Logical
x <- logical(0)
shared <- share(x)
recovered <- materialize(shared)
expect_identical(x, recovered)
# Character
x <- character(0)
shared <- share(x)
recovered <- fetch(shared)
expect_identical(x, recovered)
close(shared)
# Raw
x <- raw(0)
shared <- share(x)
recovered <- materialize(shared)
expect_identical(x, recovered)
})
test_that("share handles single-element vectors", {
# Single integer
x <- 1L
shared <- share(x)
recovered <- materialize(shared)
expect_identical(x, recovered)
# Single double
x <- 3.14
shared <- share(x)
recovered <- materialize(shared)
expect_equal(x, recovered)
# Single character
x <- "hello"
shared <- share(x)
recovered <- fetch(shared)
expect_identical(x, recovered)
close(shared)
# Single logical
x <- TRUE
shared <- share(x)
recovered <- materialize(shared)
expect_identical(x, recovered)
# Single NA
x <- NA
shared <- share(x)
recovered <- materialize(shared)
expect_identical(x, recovered)
})
test_that("share handles single-element matrix and array", {
# 1x1 matrix
mat <- matrix(42, nrow = 1, ncol = 1)
shared <- share(mat)
recovered <- materialize(shared)
expect_identical(mat, recovered)
# 1x1x1 array
arr <- array(42, dim = c(1, 1, 1))
shared <- share(arr)
recovered <- materialize(shared)
expect_identical(arr, recovered)
})
test_that("share handles empty data.frame", {
# Zero-row data.frame
df <- data.frame(a = integer(0), b = character(0), stringsAsFactors = FALSE)
shared <- share(df)
recovered <- fetch(shared)
expect_identical(df, recovered)
close(shared)
# Zero-column data.frame
df <- data.frame()
shared <- share(df)
recovered <- fetch(shared)
expect_identical(df, recovered)
close(shared)
})
test_that("share handles empty list", {
lst <- list()
shared <- share(lst)
recovered <- fetch(shared)
expect_identical(lst, recovered)
close(shared)
})
test_that("share handles NULL elements in lists", {
lst <- list(a = 1, b = NULL, c = 3)
shared <- share(lst)
recovered <- fetch(shared)
expect_identical(lst, recovered)
close(shared)
})
test_that("share handles complex objects", {
# Factor
f <- factor(c("a", "b", "a", "c"))
shared <- share(f)
recovered <- materialize(shared)
expect_identical(f, recovered)
# POSIXct
dt <- as.POSIXct("2024-01-01 12:00:00")
shared <- share(dt)
recovered <- materialize(shared)
expect_equal(dt, recovered)
# Formula (environment-sensitive)
# Skip this as formulas capture environments
})
# Tests for input validation of non-serializable objects
test_that("share rejects functions with clear error message", {
fn <- function(x) x + 1
expect_error(
share(fn),
"Cannot share functions"
)
expect_error(
share(fn),
"closures"
)
})
test_that("share rejects functions nested in lists", {
lst <- list(a = 1, fn = function(x) x)
expect_error(
share(lst),
"Cannot share functions"
)
expect_error(
share(lst),
"x\\$fn" # Shows the path to the problem
)
})
test_that("share rejects external pointers with clear error message", {
# Create a simple external pointer for testing
# We can use file() to get a connection which has an external pointer
skip_if_not(exists(".Call"))
# Actually creating an external pointer requires C code, so we'll test
# the error message pattern by checking a list containing one
# For now, verify the error message format for functions (same pattern)
expect_error(
share(function(x) x),
"Extract the data you need"
)
})
test_that("share rejects environments with external pointers", {
# Create an environment with a function (which will trigger the validation)
env <- new.env()
env$fn <- function(x) x
expect_error(
share(env),
"Cannot share functions"
)
expect_error(
share(env),
"x\\$fn"
)
})
test_that("share accepts environments without problematic content", {
env <- new.env()
env$a <- 1:10
env$b <- "hello"
shared <- share(env)
recovered <- fetch(shared)
expect_equal(recovered$a, 1:10)
expect_equal(recovered$b, "hello")
close(shared)
})
test_that("share error message shows path to nested problems", {
# Deeply nested function
lst <- list(
level1 = list(
level2 = list(
fn = function(x) x
)
)
)
expect_error(
share(lst),
"x\\$level1\\$level2\\$fn"
)
})
test_that("share error message shows index for unnamed list elements", {
lst <- list(1, 2, function(x) x)
expect_error(
share(lst),
"x\\[\\[3\\]\\]"
)
})
# Tests for deep sharing of S4 objects
# Define S4 classes for testing
# Use "ANY" type for slots that will hold reconstructed shared data
setClass("TestS4DeepMatrix",
slots = c(
data = "ANY",
name = "character"
)
)
setClass("TestS4DeepList",
slots = c(
items = "ANY",
label = "character"
)
)
setClass("TestS4DeepEnv",
slots = c(
data = "ANY",
env = "environment"
)
)
setClass("TestS4DeepNested",
slots = c(
inner = "ANY",
value = "numeric"
)
)
test_that("share with deep=TRUE processes S4 object slots", {
# Create a large matrix that will be shared
big_mat <- matrix(rnorm(1e7), nrow = 1000) # ~80MB
obj <- new("TestS4DeepMatrix", data = big_mat, name = "test")
# Share with deep=TRUE
shared <- share(obj, deep = TRUE, min_bytes = 1e6)
# Should return a shard_deep_shared object
expect_s3_class(shared, "shard_deep_shared")
# Fetch should reconstruct the original
recovered <- fetch(shared)
expect_true(isS4(recovered))
expect_s4_class(recovered, "TestS4DeepMatrix")
expect_equal(slot(recovered, "data"), big_mat)
expect_equal(slot(recovered, "name"), "test")
close(shared)
})
test_that("share with deep=TRUE recursively shares S4 list slots", {
big_vec <- rnorm(1e7) # ~80MB
obj <- new("TestS4DeepList",
items = list(big = big_vec, small = 1:10),
label = "test"
)
shared <- share(obj, deep = TRUE, min_bytes = 1e6)
expect_s3_class(shared, "shard_deep_shared")
# Summary should show shared nodes
expect_true(shared$summary$shared_count > 0)
# Fetch should reconstruct
recovered <- fetch(shared)
expect_s4_class(recovered, "TestS4DeepList")
expect_equal(slot(recovered, "items")$big, big_vec)
expect_equal(slot(recovered, "items")$small, 1:10)
close(shared)
})
test_that("share with deep=TRUE and mode='balanced' skips S4 environment slots", {
big_mat <- matrix(rnorm(1e6), nrow = 100)
env <- new.env()
env$foo <- "bar"
obj <- new("TestS4DeepEnv", data = big_mat, env = env)
# Should not error with mode='balanced' (default)
shared <- share(obj, deep = TRUE, min_bytes = 1e5, mode = "balanced")
expect_s3_class(shared, "shard_deep_shared")
# Fetch should preserve the environment
recovered <- fetch(shared)
expect_true(is.environment(slot(recovered, "env")))
close(shared)
})
test_that("share with deep=TRUE and mode='strict' errors on S4 environment slots", {
big_mat <- matrix(rnorm(1e6), nrow = 100)
env <- new.env()
obj <- new("TestS4DeepEnv", data = big_mat, env = env)
expect_error(
share(obj, deep = TRUE, min_bytes = 1e3, mode = "strict"),
"contains environment"
)
})
test_that("share with deep=TRUE uses @slot path notation for S4", {
setClass("TestS4WithFunc",
slots = c(
fn = "function"
)
)
obj <- new("TestS4WithFunc", fn = function(x) x)
# When validating S4 with function slot, should show @slot notation
expect_error(
share(obj),
"@fn"
)
removeClass("TestS4WithFunc")
})
test_that("share with deep=TRUE handles nested S4 objects", {
inner_mat <- matrix(rnorm(1e7), nrow = 1000)
inner <- new("TestS4DeepMatrix", data = inner_mat, name = "inner")
outer <- new("TestS4DeepNested", inner = inner, value = 42)
shared <- share(outer, deep = TRUE, min_bytes = 1e6)
expect_s3_class(shared, "shard_deep_shared")
recovered <- fetch(shared)
expect_s4_class(recovered, "TestS4DeepNested")
expect_s4_class(slot(recovered, "inner"), "TestS4DeepMatrix")
expect_equal(slot(slot(recovered, "inner"), "data"), inner_mat)
expect_equal(slot(recovered, "value"), 42)
close(shared)
})
test_that("share with deep=TRUE preserves S4 class after fetch", {
big_mat <- matrix(rnorm(1e7), nrow = 1000)
obj <- new("TestS4DeepMatrix", data = big_mat, name = "preserved")
shared <- share(obj, deep = TRUE, min_bytes = 1e6)
recovered <- fetch(shared)
expect_identical(class(recovered), class(obj))
expect_s4_class(recovered, "TestS4DeepMatrix")
close(shared)
})
# Clean up test classes
removeClass("TestS4DeepMatrix")
removeClass("TestS4DeepList")
removeClass("TestS4DeepEnv")
removeClass("TestS4DeepNested")
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.