File 3953-compiler-Update-property-tests-to-use-ct-property-fr.patch of Package erlang
From 3c1cad2076c26b6ba6bff3934564a50fc994dc11 Mon Sep 17 00:00:00 2001
From: Dan Gudmundsson <dgud@erlang.org>
Date: Mon, 2 Mar 2026 17:01:04 +0100
Subject: [PATCH 3/6] compiler: Update property tests to use ct property
framwork
Make the tests run with Quickcheck, the
`random_code_SUITE.erl` (compile_prop) requires
'proper_erlang_abstract_code' module to work, so that is skipped
if Quickcheck is used.
---
.../test/property_test/beam_types_prop.erl | 52 +++++++----------
.../test/property_test/compile_prop.erl | 58 ++++++++++++-------
lib/compiler/test/random_code_SUITE.erl | 21 ++++---
3 files changed, 72 insertions(+), 59 deletions(-)
diff --git a/lib/compiler/test/property_test/beam_types_prop.erl b/lib/compiler/test/property_test/beam_types_prop.erl
index eab0e2ca1e..41cc2b012b 100644
--- a/lib/compiler/test/property_test/beam_types_prop.erl
+++ b/lib/compiler/test/property_test/beam_types_prop.erl
@@ -24,19 +24,12 @@
-compile([export_all, nowarn_export_all]).
-%% This module only supports proper, as we don't have an eqc license to test
-%% with.
--proptest([proper]).
-
--ifdef(PROPER).
+-include_lib("common_test/include/ct_property_test.hrl").
-define(BEAM_TYPES_INTERNAL, true).
-include_lib("compiler/src/beam_types.hrl").
--include_lib("proper/include/proper.hrl").
--define(MOD_eqc,proper).
-
-import(lists, [duplicate/2,foldl/3]).
%% The default repetitions of 100 is a bit too low to reliably cover all type
@@ -204,12 +197,12 @@ nested_generators(Depth) ->
%% Proper's atom generator is far too wide, generating strings like 'û\2144Bò}'
%% which are both hard to read and fill up the atom table really fast.
readable_atom() ->
- ?LET(Atom, range($0, $~), list_to_atom([Atom])).
+ ?LET(Atom, ?CT_RANGE($0, $~), list_to_atom([Atom])).
%%
gen_atom() ->
- ?LET(Size, range(0, ?ATOM_SET_SIZE),
+ ?LET(Size, ?CT_RANGE(0, ?ATOM_SET_SIZE),
?LET(Set, duplicate(Size, readable_atom()),
case ordsets:from_list(Set) of
[_|_]=Vs -> #t_atom{elements=ordsets:from_list(Vs)};
@@ -217,21 +210,21 @@ gen_atom() ->
end)).
gen_bs_matchable() ->
- oneof([?LET(Unit, range(1, 16), #t_bs_matchable{tail_unit=Unit}),
- ?LET(Unit, range(1, 16), #t_bs_context{tail_unit=Unit}),
- ?LET({Unit, Appendable}, {range(1, 16), boolean()},
+ oneof([?LET(Unit, ?CT_RANGE(1, 16), #t_bs_matchable{tail_unit=Unit}),
+ ?LET(Unit, ?CT_RANGE(1, 16), #t_bs_context{tail_unit=Unit}),
+ ?LET({Unit, Appendable}, {?CT_RANGE(1, 16), bool()},
#t_bitstring{size_unit=Unit,appendable=Appendable})]).
gen_float() ->
- oneof([?LET({A, B}, {integer(), integer()},
+ oneof([?LET({A, B}, {int(), int()},
begin
Min = float(min(A, B)),
Max = float(max(A, B)),
#t_float{elements={Min,Max}}
end),
?LET({A, B, AExp, BExp},
- {integer(0, 1_000_000), integer(0, 10_00_000),
- integer(-300, 300), integer(-300, 300)},
+ {?CT_RANGE(0, 1_000_000), ?CT_RANGE(0, 10_00_000),
+ ?CT_RANGE(-300, 300), ?CT_RANGE(-300, 300)},
begin
F1 = A * math:pow(10, AExp),
F2 = B * math:pow(10, BExp),
@@ -242,16 +235,16 @@ gen_float() ->
#t_float{}]).
gen_fun(Depth) ->
- ?SHRINK(?LET({Type, Arity}, {type(Depth), oneof([any, range(1, 4)])},
+ ?SHRINK(?LET({Type, Arity}, {type(Depth), oneof([any, ?CT_RANGE(1, 4)])},
#t_fun{type=Type,arity=Arity}),
[#t_fun{}]).
gen_integer() ->
- oneof([?LET({A, B}, {integer(), integer()},
+ oneof([?LET({A, B}, {int(), int()},
#t_integer{elements={min(A,B), max(A,B)}}),
- ?LET(Min, integer(),
+ ?LET(Min, int(),
#t_integer{elements={Min, '+inf'}}),
- ?LET(Max, integer(),
+ ?LET(Max, int(),
#t_integer{elements={'-inf', Max}}),
#t_integer{}]).
@@ -269,11 +262,11 @@ gen_map(Depth) ->
[#t_map{}]).
gen_number() ->
- oneof([?LET({A, B}, {integer(), integer()},
+ oneof([?LET({A, B}, {int(), int()},
#t_number{elements={min(A,B), max(A,B)}}),
- ?LET(Min, integer(),
+ ?LET(Min, int(),
#t_number{elements={Min, '+inf'}}),
- ?LET(Max, integer(),
+ ?LET(Max, int(),
#t_number{elements={'-inf', Max}}),
#t_number{}]).
@@ -282,8 +275,8 @@ gen_tuple(Depth) ->
[#t_tuple{}]).
gen_tuple_record(Depth) ->
- ?LET({Start, Size}, {range(2, ?TUPLE_ELEMENT_LIMIT),
- range(1, ?TUPLE_ELEMENT_LIMIT * 2)},
+ ?LET({Start, Size}, {?CT_RANGE(2, ?TUPLE_ELEMENT_LIMIT),
+ ?CT_RANGE(1, ?TUPLE_ELEMENT_LIMIT * 2)},
?LET({Tag, Es0}, {readable_atom(),
gen_tuple_elements(Start, Size, Depth)},
begin
@@ -292,9 +285,9 @@ gen_tuple_record(Depth) ->
end)).
gen_tuple_plain(Depth) ->
- ?LET({Start, Size}, {range(1, ?TUPLE_ELEMENT_LIMIT),
- range(0, ?TUPLE_ELEMENT_LIMIT * 2)},
- ?LET({Exact, Es}, {boolean(), gen_tuple_elements(Start, Size, Depth)},
+ ?LET({Start, Size}, {?CT_RANGE(1, ?TUPLE_ELEMENT_LIMIT),
+ ?CT_RANGE(0, ?TUPLE_ELEMENT_LIMIT * 2)},
+ ?LET({Exact, Es}, {bool(), gen_tuple_elements(Start, Size, Depth)},
#t_tuple{exact=Exact,size=Size,elements=Es})).
gen_tuple_elements(Start, Size, Depth) ->
@@ -335,8 +328,7 @@ gen_union_wide(Depth) ->
%% Creates a union consisting solely of records
gen_union_record(Depth) ->
- ?LET(Size, range(2, ?TUPLE_SET_LIMIT),
+ ?LET(Size, ?CT_RANGE(2, ?TUPLE_SET_LIMIT),
?LET(Tuples, duplicate(Size, gen_tuple_record(Depth)),
foldl(fun join/2, none, Tuples))).
--endif.
diff --git a/lib/compiler/test/property_test/compile_prop.erl b/lib/compiler/test/property_test/compile_prop.erl
index 460fa5f363..e15a31307e 100644
--- a/lib/compiler/test/property_test/compile_prop.erl
+++ b/lib/compiler/test/property_test/compile_prop.erl
@@ -23,33 +23,43 @@
-module(compile_prop).
-compile([export_all, nowarn_export_all]).
-%% This module only supports proper, as we don't have an eqc license to test
-%% with.
+%% This module only supports proper, it requires
+%% the 'proper_erlang_abstract_code' functionality
--proptest([proper]).
-
--ifdef(PROPER).
+-include_lib("common_test/include/ct_property_test.hrl").
-define(BEAM_TYPES_INTERNAL, true).
-include_lib("compiler/src/beam_types.hrl").
--include_lib("proper/include/proper.hrl").
--define(MOD_eqc, proper).
-
-import(lists, [duplicate/2,foldl/3]).
-compile() ->
+-ifdef(PROPER).
+
+prop_compile() ->
%% {weight, {yes_multi_field_init, 0}}
Opts = [{weight, {yes_multi_field_init, 0}},
{resize,true}],
?FORALL(Abstr, proper_erlang_abstract_code:module(Opts),
- compile(Abstr)).
+ compile(noenv_forms, Abstr, compiler_variants())).
+
+-else.
+-ifdef(EQC).
-compile(Forms) ->
- compile(Forms, compiler_variants()).
+prop_compile() ->
+ Opts = [{macros, false}],
+ ?FORALL(String, eqc_erlang_program:module(eqc_generated_module, Opts),
+ begin
+ ok = file:write_file("eqc_generated_module.erl", String),
+ compile(noenv_file, "eqc_generated_module.erl", compiler_variants())
+ end).
-compile(Forms, [Opts|OptsL]) ->
- case spawn_compile(Forms, [return, binary | Opts]) of
+-endif.
+-endif.
+
+
+compile(Function, FileOrForms, [Opts|OptsL]) ->
+ AllOpts = [report_errors, return, binary, {feature,compr_assign,enable} | Opts],
+ case spawn_compile(Function, FileOrForms, AllOpts) of
{ok,_Mod,Bin,_EsWs} when is_binary(Bin) ->
%% Uncomment the following lines to print
%% the generated source code.
@@ -59,20 +69,26 @@ compile(Forms, [Opts|OptsL]) ->
%% Uncomment the following line to print the
%% generated abstract code.
%% io:format("<abstr>\n~p\n</abstr>\n", [Forms]),
- compile(Forms, OptsL);
+ compile(Function, FileOrForms, OptsL);
Err ->
io:format("compile: ~p\n", [Err]),
io:format("with options ~p\n", [Opts]),
- io:format("<S>\n~ts\n</S>\n",
- [[erl_pp:form(F) || F <- Forms]]),
+ case Function of
+ noenv_file ->
+ {ok, Str} = file:read_file(FileOrForms),
+ io:format("~s",[Str]);
+ noenv_forms ->
+ io:format("<S>\n~ts\n</S>\n",
+ [[erl_pp:form(F) || F <- FileOrForms]])
+ end,
false
end;
-compile(_Forms, []) ->
+compile(_, _FileOrForms, []) ->
true.
-spawn_compile(Forms, Options) ->
+spawn_compile(Compile, Forms, Options) ->
{Pid,Ref} = spawn_monitor(fun() ->
- exit(compile:noenv_forms(Forms, Options))
+ exit(compile:Compile(Forms, Options))
end),
receive
{'DOWN',Ref,process,Pid,Ret} ->
@@ -95,5 +111,3 @@ compiler_variants() ->
[no_copt,no_bool_opt,no_share_opt,no_bsm_opt,no_fun_opt,
no_ssa_opt,no_recv_opt,ssalint,clint0]
].
-
--endif.
diff --git a/lib/compiler/test/random_code_SUITE.erl b/lib/compiler/test/random_code_SUITE.erl
index 38bc86c5d4..1493865301 100644
--- a/lib/compiler/test/random_code_SUITE.erl
+++ b/lib/compiler/test/random_code_SUITE.erl
@@ -38,9 +38,11 @@ all() ->
init_per_suite(Config0) ->
case ct_property_test:init_per_suite(Config0) of
[_|_]=Config ->
- try proper_erlang_abstract_code:module() of
+ try proplists:get_value(property_test_tool, Config) of
+ Prop when Prop =:= proper; Prop =:= eqc ->
+ Config;
_ ->
- Config
+ {skip,"No proper_erlang_abstract_code module"}
catch
error:undef ->
{skip,"No proper_erlang_abstract_code module"}
@@ -52,7 +54,7 @@ init_per_suite(Config0) ->
end_per_suite(Config) ->
Config.
-compile(_Config) ->
+compile(Config) ->
NumTests = case os:getenv("ERL_RANDOM_CODE_NUMTESTS") of
false ->
?NUMTESTS;
@@ -60,11 +62,16 @@ compile(_Config) ->
list_to_integer(NumTests0)
end,
- %% Conservatively assume that we can run 10 tests each
+ %% Conservatively assume that we can run 5 tests each
%% second.
- TimeTrap = {seconds, (60 + (NumTests+9) div 10)},
+ TimeTrap = {seconds, (60 + (NumTests+4) div 5)},
ct:timetrap(TimeTrap),
io:format("~p tests\n", [NumTests]),
- true = proper:quickcheck(compile_prop:compile(),
- [quiet,{numtests,NumTests}]),
+ case proplists:get_value(property_test_tool, Config) of
+ proper ->
+ Opts = [quiet,{numtests,NumTests}],
+ true = proper:quickcheck(compile_prop:prop_compile(),Opts);
+ eqc -> %% Half the number of tests for eqc
+ [] = eqc:module({numtests,?NUMTESTS div 2}, compile_prop)
+ end,
ok.
--
2.51.0