Revamp (#235)
Gajumaru Bytecode Tests / tests (push) Successful in -3m34s

Add Gitea tests
Rename
Remove oracle references
Package for zx

Reviewed-on: #235
Reviewed-by: dimitar.p.ivanov <dimitarivanov@qpq.swiss>
Co-authored-by: Craig Everett <zxq9@zxq9.com>
Co-committed-by: Craig Everett <zxq9@zxq9.com>
This commit was merged in pull request #235.
This commit is contained in:
2025-01-22 21:12:54 +09:00
committed by Craig Everett
parent b47b2fe23c
commit 1cdcb9150b
54 changed files with 564 additions and 524 deletions
@@ -1,14 +1,14 @@
%%% @author Thomas Arts
%%% @doc Allow to run QuickCheck tests as eunit tests
%%% `rebar3 as eqc eunit --cover`
%%% or `rebar3 as eqc eunit --module=aeb_fate_code`
%%% or `rebar3 as eqc eunit --module=gmb_fate_code`
%%% Note that for obtainign cover file, one needs `rebar3 as eqc cover
%%%
%%%
%%% @end
%%% Created : 13 Dec 2018 by Thomas Arts <thomas@SpaceGrey.lan>
-module(aeb_fate_code_tests).
-module(gmb_fate_code_tests).
-include_lib("eunit/include/eunit.hrl").
@@ -20,8 +20,8 @@
quickcheck_test_() ->
{setup, fun() -> eqc:start() end,
[ ?EQC_EUNIT(aefate_code_eqc, prop_opcodes, 200),
?EQC_EUNIT(aefate_code_eqc, prop_serializes, 3000),
?EQC_EUNIT(aefate_code_eqc, prop_fail_serializes, 3000),
?EQC_EUNIT(aefate_code_eqc, prop_fuzz, 3000)
[ ?EQC_EUNIT(gmfate_code_eqc, prop_opcodes, 200),
?EQC_EUNIT(gmfate_code_eqc, prop_serializes, 3000),
?EQC_EUNIT(gmfate_code_eqc, prop_fail_serializes, 3000),
?EQC_EUNIT(gmfate_code_eqc, prop_fuzz, 3000)
]}.
@@ -1,14 +1,14 @@
%%% @author Thomas Arts
%%% @doc Allow to run QuickCheck tests as eunit tests
%%% `rebar3 as eqc eunit --cover`
%%% or `rebar3 as eqc eunit --module=aeb_fate_data`
%%% or `rebar3 as eqc eunit --module=gmb_fate_data`
%%% Note that for obtainign cover file, one needs `rebar3 as eqc cover
%%%
%%%
%%% @end
%%% Created : 13 Dec 2018 by Thomas Arts <thomas@SpaceGrey.lan>
-module(aeb_fate_data_tests).
-module(gmb_fate_data_tests).
-include_lib("eunit/include/eunit.hrl").
@@ -20,8 +20,8 @@
quickcheck_test_() ->
{setup, fun() -> eqc:start() end,
[ ?EQC_EUNIT(aefate_eqc, prop_roundtrip, 500),
?EQC_EUNIT(aefate_eqc, prop_format_scan, 2000),
?EQC_EUNIT(aefate_eqc, prop_order, 2000),
?EQC_EUNIT(aefate_eqc, prop_fuzz, 2000)
[ ?EQC_EUNIT(gmfate_eqc, prop_roundtrip, 500),
?EQC_EUNIT(gmfate_eqc, prop_format_scan, 2000),
?EQC_EUNIT(gmfate_eqc, prop_order, 2000),
?EQC_EUNIT(gmfate_eqc, prop_fuzz, 2000)
]}.
@@ -1,14 +1,14 @@
%%% @author Thomas Arts
%%% @doc Allow to run QuickCheck tests as eunit tests
%%% `rebar3 as eqc eunit --cover`
%%% or `rebar3 as eqc eunit --module=aeb_fate_encoding`
%%% or `rebar3 as eqc eunit --module=gmb_fate_encoding`
%%% Note that for obtaining cover file, one needs `rebar3 as eqc cover
%%%
%%%
%%% @end
%%% Created : 13 Dec 2018 by Thomas Arts
-module(aeb_fate_encoding_tests).
-module(gmb_fate_encoding_tests).
-include_lib("eunit/include/eunit.hrl").
@@ -20,8 +20,8 @@
quickcheck_test_() ->
{setup, fun() -> eqc:start() end,
[ ?EQC_EUNIT(aefate_type_eqc, prop_roundtrip, 1000),
?EQC_EUNIT(aefate_eqc, prop_serializes, 1000),
?EQC_EUNIT(aefate_eqc, prop_no_maps_in_keys, 1000),
?EQC_EUNIT(aefate_eqc, prop_idempotent, 1000)
[ ?EQC_EUNIT(gmfate_type_eqc, prop_roundtrip, 1000),
?EQC_EUNIT(gmfate_eqc, prop_serializes, 1000),
?EQC_EUNIT(gmfate_eqc, prop_no_maps_in_keys, 1000),
?EQC_EUNIT(gmfate_eqc, prop_idempotent, 1000)
]}.
@@ -16,7 +16,7 @@
%%% @end
%%% Created : 13 Dec 2018 by Thomas Arts <thomas@SpaceGrey.lan>
-module(aefate_code_eqc).
-module(gmfate_code_eqc).
-include_lib("eqc/include/eqc.hrl").
@@ -28,10 +28,10 @@ prop_serializes() ->
in_parallel(
?FORALL(FateCode, fate_code(0),
begin
{T0, Binary} = timer:tc(fun() -> aeb_fate_code:serialize(FateCode) end),
{T0, Binary} = timer:tc(fun() -> gmb_fate_code:serialize(FateCode) end),
?WHENFAIL(eqc:format("serialized:\n ~120p~n", [Binary]),
begin
{T1, Decoded} = timer:tc(fun() -> aeb_fate_code:deserialize(Binary) end),
{T1, Decoded} = timer:tc(fun() -> gmb_fate_code:deserialize(Binary) end),
measure(binary_size, size(Binary),
measure(serialize, T0 / 1000,
measure(deserialize, T1 / 1000,
@@ -44,20 +44,20 @@ prop_serializes() ->
prop_fail_serializes() ->
conjunction([{Failure, eqc:counterexample(
?FORALL(FateCode, fate_code(Failure),
?FORALL(Binary, catch aeb_fate_code:serialize(FateCode),
?FORALL(Binary, catch gmb_fate_code:serialize(FateCode),
is_binary(Binary))))
=/= true} || Failure <- [1, 2, 3, 4, 5] ]).
prop_fuzz() ->
in_parallel(
?FORALL(Binary, ?LET(FateCode, fate_code(0), aeb_fate_code:serialize(FateCode)),
?FORALL(Binary, ?LET(FateCode, fate_code(0), gmb_fate_code:serialize(FateCode)),
?FORALL(FuzzedBin, fuzz(Binary),
try aeb_fate_code:deserialize(FuzzedBin) of
try gmb_fate_code:deserialize(FuzzedBin) of
Code ->
?WHENFAIL(eqc:format("Code:\n ~p\n", [Code]),
begin
Bin1 = aeb_fate_code:serialize(Code),
Code1 = aeb_fate_code:deserialize(Bin1),
Bin1 = gmb_fate_code:serialize(Code),
Code1 = gmb_fate_code:deserialize(Bin1),
?WHENFAIL(eqc:format("Reserialized\n ~120p\n", [Bin1]),
equals(Code, Code1))
end)
@@ -66,10 +66,10 @@ prop_fuzz() ->
prop_opcodes() ->
?FORALL(Opcode, choose(0, 16#ff),
try M = aeb_fate_opcodes:mnemonic(Opcode),
try M = gmb_fate_opcodes:mnemonic(Opcode),
?WHENFAIL(eqc:format("opcode ~p -> ~p", [Opcode, M]),
conjunction([{valid, lists:member(Opcode, valid_opcodes())},
{eq, equals(aeb_fate_opcodes:m_to_op(M), Opcode)}]))
{eq, equals(gmb_fate_opcodes:m_to_op(M), Opcode)}]))
catch
_:_ ->
not lists:member(Opcode, valid_opcodes())
@@ -77,7 +77,7 @@ prop_opcodes() ->
valid_opcodes() ->
[ Op || #{opcode := Op} <- aeb_fate_generate_ops:get_ops() ].
[ Op || #{opcode := Op} <- gmb_fate_generate_ops:get_ops() ].
fate_code(Failure) ->
@@ -86,13 +86,13 @@ fate_code(Failure) ->
{non_empty(map(if Failure == 1 -> binary(1);
true -> binary(4) end,
{sublist(lists:sort([private, payable])), %% deserialize sorts them
{list(aefate_type_eqc:fate_type(Size div 3)), aefate_type_eqc:fate_type(Size div 3)}, bbs_code(Failure)})),
{list(gmfate_type_eqc:fate_type(Size div 3)), gmfate_type_eqc:fate_type(Size div 3)}, bbs_code(Failure)})),
small_map(small_fate_data_key(5), small_fate_data(4)),
small_map(small_fate_data_key(5), small_fate_data(4))},
aeb_fate_code:update_annotations(
aeb_fate_code:update_symbols(
aeb_fate_code:update_functions(
aeb_fate_code:new(), FMap), SMap), AMap))).
gmb_fate_code:update_annotations(
gmb_fate_code:update_symbols(
gmb_fate_code:update_functions(
gmb_fate_code:new(), FMap), SMap), AMap))).
short_list(Max, Gen) ->
?LET(N, choose(0, Max), eqc_gen:list(N, Gen)).
@@ -108,7 +108,7 @@ bbs_code(Failure) ->
lists:zip(lists:seq(0, length(BBs)-1), BBs)))}]).
bb_code(Failure) ->
EndBB = [ Op || Op <- valid_opcodes(), aeb_fate_opcodes:end_bb(Op) ],
EndBB = [ Op || Op <- valid_opcodes(), gmb_fate_opcodes:end_bb(Op) ],
NonEndBB = valid_opcodes() -- EndBB,
frequency(
[{if Failure == 3 -> 5; true -> 0 end, ?LET(Ops, non_empty(short_list(6, elements(NonEndBB))), bblock(Failure, Ops))},
@@ -118,8 +118,8 @@ bb_code(Failure) ->
bblock(Failure, Ops) ->
[ begin
Mnemonic = aeb_fate_opcodes:mnemonic(Op),
Arity = aeb_fate_opcodes:args(Op),
Mnemonic = gmb_fate_opcodes:mnemonic(Op),
Arity = gmb_fate_opcodes:args(Op),
case Arity of
0 -> Mnemonic;
_ -> list_to_tuple([Mnemonic |
@@ -143,7 +143,7 @@ fuzz(Binary) ->
prop_small() ->
?FORALL(Value, small_fate_data(4),
begin
Bin = aeb_fate_encoding:serialize(Value),
Bin = gmb_fate_encoding:serialize(Value),
Size = byte_size(Bin),
measure(size, Size,
?WHENFAIL(eqc:format("Size: ~p\n", [Size]),
@@ -151,9 +151,9 @@ prop_small() ->
end).
prop_small_type() ->
?FORALL(Type, ?SIZED(Size, aefate_type_eqc:fate_type(Size div 3)),
?FORALL(Type, ?SIZED(Size, gmfate_type_eqc:fate_type(Size div 3)),
begin
Bin = iolist_to_binary(aeb_fate_encoding:serialize_type(Type)),
Bin = iolist_to_binary(gmb_fate_encoding:serialize_type(Type)),
Size = byte_size(Bin),
measure(size, Size,
?WHENFAIL(eqc:format("Size: ~p\n", [Size]),
@@ -161,7 +161,7 @@ prop_small_type() ->
end).
small_fate_data(N) ->
?SIZED(Size, resize(Size div N, aefate_eqc:fate_data())).
?SIZED(Size, resize(Size div N, gmfate_eqc:fate_data())).
small_fate_data_key(N) ->
?SIZED(Size, ?LET(Data, aefate_eqc:fate_data(Size div N, []), eqc_symbolic:eval(Data))).
?SIZED(Size, ?LET(Data, gmfate_eqc:fate_data(Size div N, []), eqc_symbolic:eval(Data))).
@@ -7,10 +7,10 @@
%%% @end
%%% Created : 13 Dec 2018 by Thomas Arts <thomas@SpaceGrey.lan>
-module(aefate_eqc).
-module(gmfate_eqc).
-include_lib("eqc/include/eqc.hrl").
-include("../include/aeb_fate_data.hrl").
-include("../include/gmb_fate_data.hrl").
-compile([export_all, nowarn_export_all]).
@@ -18,17 +18,17 @@ prop_roundtrip() ->
?FORALL(FateData, fate_data(),
measure(bytes, size(term_to_binary(FateData)),
begin
Serialized = aeb_fate_encoding:serialize(FateData),
Serialized = gmb_fate_encoding:serialize(FateData),
?WHENFAIL(eqc:format("Serialized ~p to ~p~n", [FateData, Serialized]),
equals(aeb_fate_encoding:deserialize(Serialized), FateData))
equals(gmb_fate_encoding:deserialize(Serialized), FateData))
end)).
prop_format_scan() ->
?FORALL(FateData, fate_data([variant, map]),
?WHENFAIL(eqc:format("Trying to format ~p failed~n", [FateData]),
begin
String = aeb_fate_data:format(FateData),
{ok, _Scanned, _} = aeb_fate_asm_scan:scan(unicode:characters_to_list(String)),
String = gmb_fate_data:format(FateData),
{ok, _Scanned, _} = gmb_fate_asm_scan:scan(unicode:characters_to_list(String)),
true
end)).
@@ -36,8 +36,8 @@ prop_serializes() ->
?FORALL({Data, Garbage}, {fate_data(), binary()},
?WHENFAIL(eqc:format("Trying to serialize/deserialize ~p failed~n", [Data]),
begin
Binary = <<(aeb_fate_encoding:serialize(Data))/binary, Garbage/binary>>,
{FateData, Rest} = aeb_fate_encoding:deserialize_one(Binary),
Binary = <<(gmb_fate_encoding:serialize(Data))/binary, Garbage/binary>>,
{FateData, Rest} = gmb_fate_encoding:deserialize_one(Binary),
measure(binary_size, size(Binary),
conjunction([{equal, equals(Data, FateData)},
{rest, equals(Garbage, Rest)},
@@ -48,7 +48,7 @@ prop_no_maps_in_keys() ->
?FORALL(FateData, fate_bad_map(), %% may contain a map in its keys
begin
HasMapInKeys = lists:any(fun(K) -> has_map(K) end, maps:keys(FateData)),
try aeb_fate_encoding:serialize(FateData),
try gmb_fate_encoding:serialize(FateData),
?WHENFAIL(eqc:format("Should not serialize, contains a map in key\n", []),
not HasMapInKeys)
catch error:Reason ->
@@ -58,11 +58,11 @@ prop_no_maps_in_keys() ->
prop_fuzz() ->
in_parallel(
?FORALL(Binary, ?LET(FateData, ?SIZED(Size, resize(Size div 4, fate_data())), aeb_fate_encoding:serialize(FateData)),
?FORALL(Binary, ?LET(FateData, ?SIZED(Size, resize(Size div 4, fate_data())), gmb_fate_encoding:serialize(FateData)),
?FORALL(InjectedBin, injection(Binary),
try Org = aeb_fate_encoding:deserialize(InjectedBin),
NewBin = aeb_fate_encoding:serialize(Org),
NewOrg = aeb_fate_encoding:deserialize(NewBin),
try Org = gmb_fate_encoding:deserialize(InjectedBin),
NewBin = gmb_fate_encoding:serialize(Org),
NewOrg = gmb_fate_encoding:deserialize(NewBin),
measure(success, 1,
?WHENFAIL(eqc:format("Deserialize ~p gives\n~p\nSerializes to ~p\n", [InjectedBin, Org, NewOrg]),
equals(NewBin, InjectedBin)))
@@ -77,20 +77,20 @@ prop_order() ->
%% Use lt to take minimum
Min = lt_min(Items),
Max = lt_max(Items),
conjunction([ {minimum, is_empty([ {Min, '>', I} || I<-Items, aeb_fate_data:lt(I, Min)])},
{maximum, is_empty([ {Max, '<', I} || I<-Items, aeb_fate_data:lt(Max, I)])},
{asym, aeb_fate_data:lt(Min, Max) orelse Min == Max}])
conjunction([ {minimum, is_empty([ {Min, '>', I} || I<-Items, gmb_fate_data:lt(I, Min)])},
{maximum, is_empty([ {Max, '<', I} || I<-Items, gmb_fate_data:lt(Max, I)])},
{asym, gmb_fate_data:lt(Min, Max) orelse Min == Max}])
end).
lt_min([X, Y | Rest]) ->
case aeb_fate_data:lt(X, Y) of
case gmb_fate_data:lt(X, Y) of
true -> lt_min([X | Rest]);
false -> lt_min([Y| Rest])
end;
lt_min([X]) -> X.
lt_max([X, Y | Rest]) ->
case aeb_fate_data:lt(X, Y) of
case gmb_fate_data:lt(X, Y) of
true -> lt_max([Y | Rest]);
false -> lt_max([X| Rest])
end;
@@ -98,8 +98,8 @@ lt_max([X]) -> X.
prop_idempotent() ->
?FORALL(Items, list({fate_data_key(), fate_data()}),
equals(aeb_fate_encoding:sort(Items),
aeb_fate_encoding:sort(aeb_fate_encoding:sort(Items)))).
equals(gmb_fate_encoding:sort(Items),
gmb_fate_encoding:sort(gmb_fate_encoding:sort(Items)))).
@@ -131,20 +131,20 @@ fate_data(Size, Options) ->
|| lists:member(map, Options)])).
fate_integer() -> ?LET(X, oneof([int(), largeint()]), return(aeb_fate_data:make_integer(X))).
fate_bits() -> ?LET(X, oneof([int(), largeint()]), return(aeb_fate_data:make_bits(X))).
fate_boolean() -> ?LET(X, elements([true, false]), return(aeb_fate_data:make_boolean(X))).
fate_nil() -> aeb_fate_data:make_list([]).
fate_unit() -> aeb_fate_data:make_unit().
fate_integer() -> ?LET(X, oneof([int(), largeint()]), return(gmb_fate_data:make_integer(X))).
fate_bits() -> ?LET(X, oneof([int(), largeint()]), return(gmb_fate_data:make_bits(X))).
fate_boolean() -> ?LET(X, elements([true, false]), return(gmb_fate_data:make_boolean(X))).
fate_nil() -> gmb_fate_data:make_list([]).
fate_unit() -> gmb_fate_data:make_unit().
fate_string() -> ?LET(X, frequency([{10, non_quote_string()}, {2, list(non_quote_string())},
{1, ?LET(N, choose(64-3, 64+3), vector(N, $a))}]),
return(aeb_fate_data:make_string(X))).
fate_address() -> ?LET(X, binary(256 div 8), return(aeb_fate_data:make_address(X))).
fate_bytes() -> ?LET(X, non_empty(binary()), return(aeb_fate_data:make_bytes(X))).
fate_contract() -> ?LET(X, binary(256 div 8), return(aeb_fate_data:make_contract(X))).
fate_oracle() -> ?LET(X, binary(256 div 8), return(aeb_fate_data:make_oracle(X))).
fate_oracle_q() -> ?LET(X, binary(256 div 8), return(aeb_fate_data:make_oracle_query(X))).
fate_channel() -> ?LET(X, binary(256 div 8), return(aeb_fate_data:make_channel(X))).
return(gmb_fate_data:make_string(X))).
fate_address() -> ?LET(X, binary(256 div 8), return(gmb_fate_data:make_address(X))).
fate_bytes() -> ?LET(X, non_empty(binary()), return(gmb_fate_data:make_bytes(X))).
fate_contract() -> ?LET(X, binary(256 div 8), return(gmb_fate_data:make_contract(X))).
fate_oracle() -> ?LET(X, binary(256 div 8), return(gmb_fate_data:make_oracle(X))).
fate_oracle_q() -> ?LET(X, binary(256 div 8), return(gmb_fate_data:make_oracle_query(X))).
fate_channel() -> ?LET(X, binary(256 div 8), return(gmb_fate_data:make_channel(X))).
fate_values(Size, N, Options) ->
eqc_gen:list(N, fate_data(Size div max(1, N), Options)).
@@ -153,34 +153,34 @@ fate_values(Size, N, Options) ->
fate_tuple(Size, Options) ->
?LET(N, choose(0, 6),
?LETSHRINK(Elements, fate_values(Size, N, Options),
return(aeb_fate_data:make_tuple(list_to_tuple(Elements))))).
return(gmb_fate_data:make_tuple(list_to_tuple(Elements))))).
fate_variant(Size, Options) ->
?LET({L1, L2, {tuple, Args}}, {list(choose(0, 255)), list(choose(0,255)), fate_tuple(Size, Options)},
return(aeb_fate_data:make_variant(L1 ++ [tuple_size(Args)] ++ L2,
return(gmb_fate_data:make_variant(L1 ++ [tuple_size(Args)] ++ L2,
length(L1), Args))).
fate_list(Size, Options) ->
?LET(N, frequency([{20, choose(0, 6)}, {1, choose(64 - 3, 64 + 3)}]),
?LETSHRINK(Vs, fate_values(Size, N, Options),
return(aeb_fate_data:make_list(Vs)))).
return(gmb_fate_data:make_list(Vs)))).
fate_map(Size, Options) ->
?LET(N, choose(0, 6),
?LETSHRINK(Values, fate_values(Size, N, Options),
?LET(Keys, vector(length(Values), fate_data(Size div max(1, N * 2), Options -- [map, store_map])),
return(aeb_fate_data:make_map(maps:from_list(lists:zip(Keys, Values))))))).
return(gmb_fate_data:make_map(maps:from_list(lists:zip(Keys, Values))))))).
fate_store_map() ->
%% only #{} is allowed as cache in serialization
?LET(X, oneof([int(), largeint()]),
return(aeb_fate_data:make_store_map(abs(X)))).
return(gmb_fate_data:make_store_map(abs(X)))).
fate_bad_map() ->
?LET(N, choose(0, 6),
?LET(Values, vector(N, ?SIZED(Size, resize(Size div 8, fate_data()))),
?LET(Keys, vector(N, ?SIZED(Size, resize(Size div 4, fate_data()))),
return(aeb_fate_data:make_map(maps:from_list(lists:zip(Keys, Values))))))).
return(gmb_fate_data:make_map(maps:from_list(lists:zip(Keys, Values))))))).
non_quote_string() ->
?SUCHTHAT(S, utf8(), [ quote || <<34>> <= S ] == []).
@@ -5,7 +5,7 @@
%%% @end
%%% Created : 13 Dec 2018 by Thomas Arts <thomas@SpaceGrey.lan>
-module(aefate_type_eqc).
-module(gmfate_type_eqc).
-include_lib("eqc/include/eqc.hrl").
@@ -18,11 +18,11 @@ prop_roundtrip() ->
?FORALL(FateType, fate_type(),
collect(kind(FateType),
begin
Serialized = aeb_fate_encoding:serialize_type(FateType),
Serialized = gmb_fate_encoding:serialize_type(FateType),
BinSerialized = list_to_binary(Serialized),
?WHENFAIL(eqc:format("Serialized ~p to ~p (~p)~n", [FateType, Serialized, BinSerialized]),
begin
{Type, <<>>} = aeb_fate_encoding:deserialize_type(BinSerialized),
{Type, <<>>} = gmb_fate_encoding:deserialize_type(BinSerialized),
equals(Type, FateType)
end)
end)).