Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions test/unit/test_derived_analyses.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using Test
using JSON3
using Sockets
using MetaManifold.Canonical
using MetaManifold.DerivedAnalyses
using MetaManifold.ExactSummaries
Expand All @@ -28,15 +29,19 @@ end
@testset "Derived-record I/O and storage limits fail explicitly" begin
DA = MetaManifold.DerivedAnalyses
mktempdir() do root
# Reading a directory raises an I/O error, independently of filesystem
# permissions (the test must also work when CI runs as root).
# `read` on a directory raises nothing in Julia: it returns no bytes. So
# a directory cannot stand in for an unreadable file. Opening a
# Unix-domain socket path fails for every user, root included, and so
# does not depend on filesystem permissions.
unreadable = joinpath(root, "not-a-file")
mkdir(unreadable)
server = Sockets.listen(unreadable)
error = try
DA._existing(unreadable, repeat("0", 64))
nothing
catch err
err
finally
close(server)
end
@test error isa DerivedAnalysisError
@test error.code == "conflict"
Expand Down
21 changes: 17 additions & 4 deletions test/unit/test_validated_statistics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -484,9 +484,16 @@ end
Dict("colFilters" => Dict("odd\"sample" => criterion))))
@test response.status == 200
result = JSON3.read(String(response.body))
@test collect(result.samples[1].features) == ["G"]
@test collect(result.samples[1].counts) == [2, 20, 200, "9007199254740993"]
@test result.samples[1].total == "9007199254741215"
# Only seq2 remains, so every sample has the one feature G with
# that row's own exact count. The count above 2^53 stays a string.
expected = Dict("feature" => 2, "__VALIDATED_FEATURE" => 20,
"__validated_feature_" => 200, "odd\"sample" => "9007199254740993")
@test Set(s.label for s in result.samples) == Set(keys(expected))
for sample in result.samples
@test collect(sample.features) == ["G"]
@test collect(sample.counts) == [expected[sample.label]]
@test sample.total == expected[sample.label]
end
loaded_response = _vs_get("/api/v1/studies/studyV/runs/run1/statistics/derived/$(result.analysis_id)")
@test loaded_response.status == 200
loaded = JSON3.read(String(loaded_response.body))
Expand All @@ -495,12 +502,18 @@ end
end
# Numeric count filters are deliberately refused before SQL construction:
# the shared min/max predicate would cast exact counts to Float64.
for criterion in (Dict("min" => 1), Dict("max" => 9007199254740993))
for criterion in (Dict("min" => 1), Dict("max" => 5))
quoted = _vs_post(path, merge(request,
Dict("colFilters" => Dict("odd\"sample" => criterion))))
@test quoted.status == 422
@test occursin("count-filter", String(quoted.body))
end
# A bound above 2^53 never reaches that guard. The request parser
# refuses the token first, because such a JSON number is not exact.
unsafe = _vs_post(path, merge(request,
Dict("colFilters" => Dict("odd\"sample" => Dict("max" => 9007199254740993)))))
@test unsafe.status == 400
@test occursin("unsafe integer", String(unsafe.body))
end
end

Expand Down