Commits

arkdro committed 019707e

add long running test, without divide yet

Comments (0)

Files changed (1)

erlang/test/num_SUITE.erl

 -compile(export_all).
 -include_lib("common_test/include/ct.hrl").
 
+-define(d_precision, 100).
+-define(d_precision_short, ?d_precision - 2).
+-define(d_context, [{precision, ?d_precision}]).
+-define(d_context_short, [{precision, ?d_precision_short}]).
 
 % -----------------------------------------------------------------------------
 % Function: suite() -> Info
 % -----------------------------------------------------------------------------
 suite() ->
     [
+     {require, length},
      {require, odeci_prog},
      {timetrap,{seconds,10}}
     ].
 % Reason = term()
 % -----------------------------------------------------------------------------
 init_per_suite(Config) ->
+    application:start(crypto), %% for random numbers
     Config.
 
 % -----------------------------------------------------------------------------
 % -----------------------------------------------------------------------------
 all() ->
     [
-        start
+     %% start
+     test1
     ].
 
 %%=============================================================================
     application:set_env(odeci, port_command, Fullname),
     ok = application:start(odeci).
 
+ops() ->
+    [
+     %% divide,
+     subtract,
+     add,
+     multiply
+     ].
+
+random_choice(List) ->
+    Len = length(List),
+    N = crypto:rand_uniform(1, Len + 1),
+    lists:nth(N, List).
+
+do_test_loop(Len) ->
+    Ops = ops(),
+    Ignore = ct:get_config(ignore_errors),
+    do_test_loop2(Len, Ops, Ignore).
+
+do_test_loop2(0, _Ops, _Ignore) ->
+    ok;
+do_test_loop2(Len, Ops, Ignore) ->
+    case do_one_operation(Ops) of
+        {true, _Op, _I1, _I2, _O1, _O2} ->
+            do_test_loop2(Len-1, Ops, Ignore);
+        {false, _Op, _I1, _I2, _O1, _O2} when Ignore == true ->
+            do_test_loop2(Len-1, Ops, Ignore);
+        {false, Op, I1, I2, O1, O2} ->
+            ct:pal("one op error, op=~p~n",
+                   "i1=~p~ni2=~p~n",
+                   "o1=~p~no2=~p~n",
+                   [Op, I1, I2, O1, O2])
+    end.
+
+-spec do_one_operation(list()) -> {ok | error, tuple(), tuple()}.
+
+do_one_operation(Ops) ->
+    Cur = random_choice(Ops),
+    D1 = gen_one_decimal(),
+    D2 = gen_one_decimal(),
+    {R1, R2} = do_op(Cur, D1, D2),
+    Verbose = ct:get_config(verbose, 0),
+    if Verbose > 2 ->
+            ct:pal("do_one_operation,~n"
+                   "cur op: ~p,~n"
+                   "d1=~p~nd2=~p,~n"
+                   "r1=~p~nr2=~p~n", [Cur, D1, D2, R1, R2]);
+       true ->
+            ok
+    end,
+    Res = compare(R1, R2),
+    {Res, Cur, D1, D2, R1, R2}.
+
+gen_one_decimal() ->
+    Sign = gen_sign(),
+    Exp = gen_exponent(),
+    Mant = gen_mantissa(),
+    {Sign, Mant, Exp}.
+
+gen_mantissa() ->
+    case ct:get_config(random_mantissa) of
+        true ->
+            Min = ct:get_config(mantissa_min),
+            Max = ct:get_config(mantissa_max),
+            crypto:rand_uniform(Min, Max + 1);
+        _ ->
+            ct:get_config(mantissa_min, 0)
+    end.
+
+gen_exponent() ->
+    case ct:get_config(random_exponent) of
+        true ->
+            Min = ct:get_config(exponent_min),
+            Max = ct:get_config(exponent_max),
+            crypto:rand_uniform(Min, Max + 1);
+        _ ->
+            ct:get_config(exponent_min, 0)
+    end.
+
+gen_sign() ->
+    case ct:get_config(random_sign) of
+        true ->
+            crypto:rand_uniform(0, 2);
+        _ ->
+            0
+    end.
+
+do_op(divide, D1, D2) ->
+    Res1 = c_server:divide(D1, D2),
+    Res2 = decimal:divide(D1, D2, ?d_context),
+    {Res1, Res2};
+do_op(subtract, D1, D2) ->
+    Res1 = c_server:subtract(D1, D2),
+    Res2 = decimal:subtract(D1, D2, ?d_context),
+    {Res1, Res2};
+do_op(add, D1, D2) ->
+    Res1 = c_server:add(D1, D2),
+    Res2 = decimal:add(D1, D2, ?d_context),
+    {Res1, Res2};
+do_op(multiply, D1, D2) ->
+    Res1 = c_server:multiply(D1, D2),
+    Res2 = decimal:multiply(D1, D2, ?d_context),
+    {Res1, Res2}.
+
+compare({ok, R1}, R1) ->
+    Verbose = ct:get_config(verbose, 0),
+    if Verbose > 3 ->
+            ct:pal("compare equal match~nr1=~p~n", [R1]);
+       true ->
+            ok
+    end,
+    true;
+compare({ok, R1}, R2) ->
+    Cmp_res_s = decimal:compare(R1, R2, ?d_context_short),
+    case decimal:compare(R1, R2, ?d_context) of
+        0 ->
+            Verbose = ct:get_config(verbose, 0),
+            if Verbose > 3 ->
+                    ct:pal("compare equal~nr1=~p~nr2=~p~n", [R1, R2]);
+               true ->
+                    ok
+            end,
+            true;
+        _ when Cmp_res_s == 0 ->
+            Verbose = ct:get_config(verbose, 0),
+            if Verbose > 3 ->
+                    ct:pal("compare almost equal~nr1=~p~nr2=~p~n", [R1, R2]);
+               true ->
+                    ok
+            end,
+            true;
+        _ ->
+            ct:pal("compare not equal~n~p~n~p~n", [R1, R2]),
+            false
+    end;
+compare(R1, R2) ->
+    ct:pal("compare different, not even close~n~p~n~p~n", [R1, R2]),
+    false.
+
 % -----------------------------------------------------------------------------
 % Function: TestCase(Config0) ->
 %               ok | exit() | {skip,Reason} | {comment,Comment} |
 start(Config) ->
     start_prog(Config).
 
+test1(Config) ->
+    start_prog(Config),
+    timer:sleep(100),
+    Len = ct:get_config(length, 1),
+    ct:timetrap(round(Len) * 5 + 5000),
+    do_test_loop(Len).