summaryrefslogtreecommitdiff
path: root/erts/emulator/test/bs_construct_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/test/bs_construct_SUITE.erl')
-rw-r--r--erts/emulator/test/bs_construct_SUITE.erl115
1 files changed, 110 insertions, 5 deletions
diff --git a/erts/emulator/test/bs_construct_SUITE.erl b/erts/emulator/test/bs_construct_SUITE.erl
index 81107c5644..5f3cea1bcb 100644
--- a/erts/emulator/test/bs_construct_SUITE.erl
+++ b/erts/emulator/test/bs_construct_SUITE.erl
@@ -28,7 +28,7 @@
huge_float_field/1, system_limit/1, badarg/1,
copy_writable_binary/1, kostis/1, dynamic/1, bs_add/1,
otp_7422/1, zero_width/1, bad_append/1, bs_append_overflow/1,
- reductions/1, fp16/1]).
+ reductions/1, fp16/1, error_info/1]).
-include_lib("common_test/include/ct.hrl").
@@ -41,7 +41,7 @@ all() ->
in_guard, mem_leak, coerce_to_float, bjorn, append_empty_is_same,
huge_float_field, system_limit, badarg,
copy_writable_binary, kostis, dynamic, bs_add, otp_7422, zero_width,
- bad_append, bs_append_overflow, reductions, fp16].
+ bad_append, bs_append_overflow, reductions, fp16, error_info].
init_per_suite(Config) ->
Config.
@@ -935,9 +935,6 @@ reds_at_least(N, Fun) ->
Diff ->
ct:fail({expected,N,got,Diff})
end.
-
-id(I) -> I.
-
memsize() ->
application:ensure_all_started(os_mon),
{Tot,_Used,_} = memsup:get_memory_data(),
@@ -984,3 +981,111 @@ fp16(_Config) ->
?FP16(16#4000, 2),
?FP16(16#4000, 2.0),
ok.
+
+-define(ERROR_INFO(Expr),
+ fun() ->
+ try Expr of
+ _ ->
+ error(should_fail)
+ catch
+ error:Reason:Stk ->
+ error_info_verify(Reason, Stk, ??Expr)
+ end
+ end()).
+
+error_info(_Config) ->
+ Atom = id(atom),
+ NegativeSize = id(-1),
+ HugeNegativeSize = id(-1 bsl 64),
+ Binary = id(<<"abc">>),
+ HugeBig = id(1 bsl 1500),
+
+ {badarg, {1,binary,type}} = ?ERROR_INFO(<<Atom/binary, Binary/binary>>),
+ {badarg, {2,binary,type}} = ?ERROR_INFO(<<Binary/binary, Atom/binary>>),
+ {badarg, {3,binary,type}} = ?ERROR_INFO(<<1:32, Binary/binary, Atom/binary>>),
+ {badarg, {4,binary,type}} = ?ERROR_INFO(<<1:32, "xyz", Binary/binary, Atom/binary>>),
+
+ {badarg, {1,integer,type}} = ?ERROR_INFO(<<Atom:32>>),
+ {badarg, {1,integer,size}} = ?ERROR_INFO(<<42:Atom>>),
+ {badarg, {1,integer,negative_size}} = ?ERROR_INFO(<<42:NegativeSize>>),
+ {badarg, {1,integer,negative_size}} = ?ERROR_INFO(<<42:HugeNegativeSize>>),
+ {system_limit, {1,integer,size}} = ?ERROR_INFO(<<42:(1 bsl 58)/unit:255>>),
+ {system_limit, {1,integer,size}} = ?ERROR_INFO(<<42:(1 bsl 60)/unit:8>>),
+ {system_limit, {1,integer,size}} = ?ERROR_INFO(<<42:(1 bsl 64)>>),
+
+ {badarg, {1,binary,type}} = ?ERROR_INFO(<<Atom:10/binary>>),
+ {badarg, {1,binary,size}} = ?ERROR_INFO(<<Binary:Atom/binary>>),
+ {badarg, {1,binary,negative_size}} = ?ERROR_INFO(<<Binary:NegativeSize/binary>>),
+ {badarg, {1,binary,negative_size}} = ?ERROR_INFO(<<Binary:HugeNegativeSize/binary>>),
+ {system_limit, {1,binary,size}} = ?ERROR_INFO(<<Binary:(1 bsl 64)/binary>>),
+ {badarg, {1,binary,short}} = ?ERROR_INFO(<<Binary:10/binary>>),
+ {badarg, {1,binary,type}} = ?ERROR_INFO(<<Atom/binary>>),
+
+ {badarg, {1,float,type}} = ?ERROR_INFO(<<Atom:64/float>>),
+ {badarg, {1,float,size}} = ?ERROR_INFO(<<Atom:Atom/float>>),
+ {badarg, {1,float,negative_size}} = ?ERROR_INFO(<<42.0:NegativeSize/float>>),
+ {badarg, {1,float,negative_size}} = ?ERROR_INFO(<<42.0:HugeNegativeSize/float>>),
+ {badarg, {1,float,invalid}} = ?ERROR_INFO(<<42.0:(id(1))/float>>),
+ {badarg, {1,float,no_float}} = ?ERROR_INFO(<<HugeBig:(id(64))/float>>),
+ {badarg, {1,float,no_float}} = ?ERROR_INFO(<<HugeBig:64/float>>),
+ {system_limit, {1,float,size}} = ?ERROR_INFO(<<42.0:(id(1 bsl 64))/float>>),
+
+ {badarg, {1,utf8,type}} = ?ERROR_INFO(<<Atom/utf8>>),
+ {badarg, {1,utf16,type}} = ?ERROR_INFO(<<Atom/utf16>>),
+ {badarg, {1,utf32,type}} = ?ERROR_INFO(<<Atom/utf32>>),
+
+ Bin = id(<<>>),
+ Float = id(42.0),
+
+ %% Attempt constructing a binary with total size 1^64 + 32.
+
+ {system_limit, {1,integer,size}} = ?ERROR_INFO(<<0:((1 bsl 59)-1)/unit:32,0:64>>),
+ {system_limit, {1,integer,size}} = ?ERROR_INFO(<<0:((1 bsl 59)-1)/unit:32,(id(0)):64>>),
+ {system_limit, {1,integer,size}} = ?ERROR_INFO(<<0:(id((1 bsl 59)-1))/unit:32,0:64>>),
+ {system_limit, {1,integer,size}} = ?ERROR_INFO(<<0:(id((1 bsl 59)-1))/unit:32,(id(0)):64>>),
+
+ {system_limit, {1,binary,size}} = ?ERROR_INFO(<<Bin:((1 bsl 59)-1)/binary-unit:32,0:64>>),
+ {system_limit, {1,binary,size}} = ?ERROR_INFO(<<Bin:((1 bsl 59)-1)/binary-unit:32,(id(0)):64>>),
+ {system_limit, {1,binary,size}} = ?ERROR_INFO(<<Bin:(id((1 bsl 59)-1))/binary-unit:32,0:64>>),
+ {system_limit, {1,binary,size}} = ?ERROR_INFO(<<Bin:(id((1 bsl 59)-1))/binary-unit:32,(id(0)):64>>),
+
+ {system_limit, {1,float,size}} = ?ERROR_INFO(<<Float:((1 bsl 59)-1)/float-unit:32,0:64>>),
+ {system_limit, {1,float,size}} = ?ERROR_INFO(<<Float:((1 bsl 59)-1)/float-unit:32,(id(0)):64>>),
+ {system_limit, {1,float,size}} = ?ERROR_INFO(<<Float:(id((1 bsl 59)-1))/float-unit:32,0:64>>),
+ {system_limit, {1,float,size}} = ?ERROR_INFO(<<Float:(id((1 bsl 59)-1))/float-unit:32,(id(0)):64>>),
+
+ %% Test a size exceeding 1^64, where the sign bit (bit 63) is not set.
+ 0 = ((((1 bsl 59)-1) * 33) bsr 63) band 1, %Assertion: The sign bit is not set.
+
+ {system_limit, {1,integer,size}} = ?ERROR_INFO(<<0:((1 bsl 59)-1)/unit:33>>),
+ {system_limit, {1,integer,size}} = ?ERROR_INFO(<<0:((1 bsl 59)-1)/unit:33>>),
+ {system_limit, {1,integer,size}} = ?ERROR_INFO(<<0:(id((1 bsl 59)-1))/unit:33>>),
+ {system_limit, {1,integer,size}} = ?ERROR_INFO(<<0:(id((1 bsl 59)-1))/unit:33>>),
+
+ {system_limit, {1,binary,size}} = ?ERROR_INFO(<<Bin:((1 bsl 59)-1)/binary-unit:33>>),
+ {system_limit, {1,binary,size}} = ?ERROR_INFO(<<Bin:((1 bsl 59)-1)/binary-unit:33>>),
+ {system_limit, {1,binary,size}} = ?ERROR_INFO(<<Bin:(id((1 bsl 59)-1))/binary-unit:33>>),
+ {system_limit, {1,binary,size}} = ?ERROR_INFO(<<Bin:(id((1 bsl 59)-1))/binary-unit:33>>),
+
+ {system_limit, {1,float,size}} = ?ERROR_INFO(<<Float:((1 bsl 59)-1)/float-unit:33>>),
+ {system_limit, {1,float,size}} = ?ERROR_INFO(<<Float:((1 bsl 59)-1)/float-unit:33>>),
+ {system_limit, {1,float,size}} = ?ERROR_INFO(<<Float:(id((1 bsl 59)-1))/float-unit:33>>),
+ {system_limit, {1,float,size}} = ?ERROR_INFO(<<Float:(id((1 bsl 59)-1))/float-unit:33>>),
+
+ ok.
+
+error_info_verify(Reason, Stk, Expr) ->
+ [{?MODULE, _, _, Info}|_] = Stk,
+ {error_info, ErrorInfo} = lists:keyfind(error_info, 1, Info),
+ #{cause := Cause, module := Module, function := Function} = ErrorInfo,
+ Result = Module:Function(Reason, Stk),
+ #{general := String} = Result,
+ true = is_binary(String),
+ io:format("~ts: ~ts\n", [Expr,String]),
+ {Reason, Cause}.
+
+%%%
+%%% Common utilities.
+%%%
+
+id(I) -> I.