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

openSUSE Build Service is sponsored by