test: make assembly proptests waste less memory
This commit is contained in:
parent
8e6f960c09
commit
788e76ed2d
|
@ -28,11 +28,11 @@ prop_coverage() ->
|
||||||
{filesize_t(), segsizes_t()},
|
{filesize_t(), segsizes_t()},
|
||||||
?FORALL(
|
?FORALL(
|
||||||
Fragments,
|
Fragments,
|
||||||
noshrink(fragments_t(Filesize, Segsizes)),
|
noshrink(segments_t(Filesize, Segsizes)),
|
||||||
?TIMEOUT(
|
?TIMEOUT(
|
||||||
?COVERAGE_TIMEOUT,
|
?COVERAGE_TIMEOUT,
|
||||||
begin
|
begin
|
||||||
ASM1 = append_fragments(mk_assembly(Filesize), Fragments),
|
ASM1 = append_segments(mk_assembly(Filesize), Fragments),
|
||||||
{Time, ASM2} = timer:tc(emqx_ft_assembly, update, [ASM1]),
|
{Time, ASM2} = timer:tc(emqx_ft_assembly, update, [ASM1]),
|
||||||
measure(
|
measure(
|
||||||
#{"Fragments" => length(Fragments), "Time" => Time},
|
#{"Fragments" => length(Fragments), "Time" => Time},
|
||||||
|
@ -58,11 +58,11 @@ prop_coverage_likely_incomplete() ->
|
||||||
{filesize_t(), segsizes_t(), filesize_t()},
|
{filesize_t(), segsizes_t(), filesize_t()},
|
||||||
?FORALL(
|
?FORALL(
|
||||||
Fragments,
|
Fragments,
|
||||||
noshrink(fragments_t(Filesize, Segsizes, Hole)),
|
noshrink(segments_t(Filesize, Segsizes, Hole)),
|
||||||
?TIMEOUT(
|
?TIMEOUT(
|
||||||
?COVERAGE_TIMEOUT,
|
?COVERAGE_TIMEOUT,
|
||||||
begin
|
begin
|
||||||
ASM1 = append_fragments(mk_assembly(Filesize), Fragments),
|
ASM1 = append_segments(mk_assembly(Filesize), Fragments),
|
||||||
{Time, ASM2} = timer:tc(emqx_ft_assembly, update, [ASM1]),
|
{Time, ASM2} = timer:tc(emqx_ft_assembly, update, [ASM1]),
|
||||||
measure(
|
measure(
|
||||||
#{"Fragments" => length(Fragments), "Time" => Time},
|
#{"Fragments" => length(Fragments), "Time" => Time},
|
||||||
|
@ -85,17 +85,19 @@ prop_coverage_complete() ->
|
||||||
{Filesize, Segsizes},
|
{Filesize, Segsizes},
|
||||||
{filesize_t(), ?SUCHTHAT([BaseSegsize | _], segsizes_t(), BaseSegsize > 0)},
|
{filesize_t(), ?SUCHTHAT([BaseSegsize | _], segsizes_t(), BaseSegsize > 0)},
|
||||||
?FORALL(
|
?FORALL(
|
||||||
{Fragments, MaxCoverage},
|
{Fragments, RemoteNode},
|
||||||
noshrink({fragments_t(Filesize, Segsizes), coverage_t(Filesize, Segsizes)}),
|
noshrink({segments_t(Filesize, Segsizes), remote_node_t()}),
|
||||||
begin
|
begin
|
||||||
% Ensure that we have complete coverage
|
% Ensure that we have complete coverage
|
||||||
ASM1 = append_fragments(mk_assembly(Filesize), Fragments ++ MaxCoverage),
|
ASM1 = mk_assembly(Filesize),
|
||||||
{Time, ASM2} = timer:tc(emqx_ft_assembly, update, [ASM1]),
|
ASM2 = append_coverage(ASM1, RemoteNode, Filesize, Segsizes),
|
||||||
|
ASM3 = append_segments(ASM2, Fragments),
|
||||||
|
{Time, ASM4} = timer:tc(emqx_ft_assembly, update, [ASM3]),
|
||||||
measure(
|
measure(
|
||||||
#{"CoverageMax" => length(MaxCoverage), "Time" => Time},
|
#{"CoverageMax" => nsegs(Filesize, Segsizes), "Time" => Time},
|
||||||
case emqx_ft_assembly:status(ASM2) of
|
case emqx_ft_assembly:status(ASM4) of
|
||||||
complete ->
|
complete ->
|
||||||
Coverage = emqx_ft_assembly:coverage(ASM2),
|
Coverage = emqx_ft_assembly:coverage(ASM4),
|
||||||
measure(
|
measure(
|
||||||
#{"Coverage" => length(Coverage)},
|
#{"Coverage" => length(Coverage)},
|
||||||
is_coverage_complete(Coverage)
|
is_coverage_complete(Coverage)
|
||||||
|
@ -127,15 +129,26 @@ is_coverage_complete(
|
||||||
mk_assembly(Filesize) ->
|
mk_assembly(Filesize) ->
|
||||||
emqx_ft_assembly:append(emqx_ft_assembly:new(Filesize), node(), mk_filemeta(Filesize)).
|
emqx_ft_assembly:append(emqx_ft_assembly:new(Filesize), node(), mk_filemeta(Filesize)).
|
||||||
|
|
||||||
append_fragments(ASMIn, Fragments) ->
|
append_segments(ASMIn, Fragments) ->
|
||||||
lists:foldl(
|
lists:foldl(
|
||||||
fun({Node, Frag}, ASM) ->
|
fun({Node, {Offset, Size}}, ASM) ->
|
||||||
emqx_ft_assembly:append(ASM, Node, Frag)
|
emqx_ft_assembly:append(ASM, Node, mk_segment(Offset, Size))
|
||||||
end,
|
end,
|
||||||
ASMIn,
|
ASMIn,
|
||||||
Fragments
|
Fragments
|
||||||
).
|
).
|
||||||
|
|
||||||
|
append_coverage(ASM, Node, Filesize, Segsizes = [BaseSegsize | _]) ->
|
||||||
|
append_coverage(ASM, Node, Filesize, BaseSegsize, 0, nsegs(Filesize, Segsizes)).
|
||||||
|
|
||||||
|
append_coverage(ASM, Node, Filesize, Segsize, I, NSegs) when I < NSegs ->
|
||||||
|
Offset = I * Segsize,
|
||||||
|
Size = min(Segsize, Filesize - Offset),
|
||||||
|
ASMNext = emqx_ft_assembly:append(ASM, Node, mk_segment(Offset, Size)),
|
||||||
|
append_coverage(ASMNext, Node, Filesize, Segsize, I + 1, NSegs);
|
||||||
|
append_coverage(ASM, _Node, _Filesize, _Segsize, _, _NSegs) ->
|
||||||
|
ASM.
|
||||||
|
|
||||||
mk_filemeta(Filesize) ->
|
mk_filemeta(Filesize) ->
|
||||||
#{
|
#{
|
||||||
path => "MANIFEST.json",
|
path => "MANIFEST.json",
|
||||||
|
@ -148,39 +161,33 @@ mk_segment(Offset, Size) ->
|
||||||
fragment => {segment, #{offset => Offset, size => Size}}
|
fragment => {segment, #{offset => Offset, size => Size}}
|
||||||
}.
|
}.
|
||||||
|
|
||||||
fragments_t(Filesize, Segsizes = [BaseSegsize | _]) ->
|
nsegs(Filesize, [BaseSegsize | _]) ->
|
||||||
NSegs = Filesize / max(1, BaseSegsize),
|
Filesize div max(1, BaseSegsize) + 1.
|
||||||
scaled(1 + NSegs, list({node_t(), fragment_t(Filesize, Segsizes)})).
|
|
||||||
|
|
||||||
fragments_t(Filesize, Segsizes = [BaseSegsize | _], Hole) ->
|
segments_t(Filesize, Segsizes) ->
|
||||||
NSegs = Filesize / max(1, BaseSegsize),
|
scaled(nsegs(Filesize, Segsizes), list({node_t(), segment_t(Filesize, Segsizes)})).
|
||||||
scaled(1 + NSegs, list({node_t(), fragment_t(Filesize, Segsizes, Hole)})).
|
|
||||||
|
|
||||||
fragment_t(Filesize, Segsizes, Hole) ->
|
segments_t(Filesize, Segsizes, Hole) ->
|
||||||
|
scaled(nsegs(Filesize, Segsizes), list({node_t(), segment_t(Filesize, Segsizes, Hole)})).
|
||||||
|
|
||||||
|
segment_t(Filesize, Segsizes, Hole) ->
|
||||||
?SUCHTHATMAYBE(
|
?SUCHTHATMAYBE(
|
||||||
#{fragment := {segment, #{offset := Offset, size := Size}}},
|
{Offset, Size},
|
||||||
fragment_t(Filesize, Segsizes),
|
segment_t(Filesize, Segsizes),
|
||||||
(Hole rem Filesize) =< Offset orelse (Hole rem Filesize) > (Offset + Size)
|
(Hole rem Filesize) =< Offset orelse (Hole rem Filesize) > (Offset + Size)
|
||||||
).
|
).
|
||||||
|
|
||||||
fragment_t(Filesize, Segsizes) ->
|
segment_t(Filesize, Segsizes) ->
|
||||||
?LET(
|
?LET(
|
||||||
Segsize,
|
Segsize,
|
||||||
oneof(Segsizes),
|
oneof(Segsizes),
|
||||||
?LET(
|
?LET(
|
||||||
Index,
|
Index,
|
||||||
range(0, Filesize div max(1, Segsize)),
|
range(0, Filesize div max(1, Segsize)),
|
||||||
mk_segment(Index * Segsize, min(Segsize, Filesize - (Index * Segsize)))
|
{Index * Segsize, min(Segsize, Filesize - (Index * Segsize))}
|
||||||
)
|
)
|
||||||
).
|
).
|
||||||
|
|
||||||
coverage_t(Filesize, [Segsize | _]) ->
|
|
||||||
NSegs = Filesize div max(1, Segsize),
|
|
||||||
[
|
|
||||||
{remote_node_t(), mk_segment(I * Segsize, min(Segsize, Filesize - (I * Segsize)))}
|
|
||||||
|| I <- lists:seq(0, NSegs)
|
|
||||||
].
|
|
||||||
|
|
||||||
filesize_t() ->
|
filesize_t() ->
|
||||||
scaled(4000, non_neg_integer()).
|
scaled(4000, non_neg_integer()).
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue