diff options
Diffstat (limited to 'lib/stdlib/test/ets_SUITE.erl')
-rw-r--r-- | lib/stdlib/test/ets_SUITE.erl | 129 |
1 files changed, 65 insertions, 64 deletions
diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl index 954d19a46f..dc17e5d33c 100644 --- a/lib/stdlib/test/ets_SUITE.erl +++ b/lib/stdlib/test/ets_SUITE.erl @@ -74,6 +74,7 @@ -export([bad_table/1, types/1]). -export([otp_9932/1]). -export([otp_9423/1]). +-export([otp_10182/1]). -export([init_per_testcase/2, end_per_testcase/2]). %% Convenience for manual testing @@ -146,6 +147,7 @@ all() -> exit_many_large_table_owner, exit_many_tables_owner, exit_many_many_tables_owner, write_concurrency, heir, give_away, setopts, bad_table, types, + otp_10182, otp_9932, otp_9423]. @@ -715,30 +717,17 @@ adjust_xmem([T1,T2,T3,T4], {A0,B0,C0,D0} = _Mem0) -> TabDiff = ?TAB_STRUCT_SZ, Mem1 = {A0+TabDiff, B0+TabDiff, C0+TabDiff, D0+TabDiff}, - Mem2 = case {erlang:system_info({wordsize,internal}),erlang:system_info({wordsize,external})} of - %% Halfword, corrections for regular pointers occupying two internal words. - {4,8} -> - {A1,B1,C1,D1} = Mem1, - {A1+4*ets:info(T1, size)+?DB_TREE_STACK_NEED, - B1+3*ets:info(T2, size)+?DB_HASH_SIZEOF_EXTSEG, - C1+3*ets:info(T3, size)+?DB_HASH_SIZEOF_EXTSEG, - D1+3*ets:info(T4, size)+?DB_HASH_SIZEOF_EXTSEG}; - _ -> - Mem1 - end, - - %% Adjust for hybrid and shared heaps: - %% Each record is one word smaller. - %%Mem2 = case erlang:system_info(heap_type) of - %% private -> - %% Mem1; - %% _ -> - %% {A1,B1,C1,D1} = Mem1, - %% {A1-ets:info(T1, size),B1-ets:info(T2, size), - %% C1-ets:info(T3, size),D1-ets:info(T4, size)} - %% end, - %%{Mem2,{ets:info(T1,stats),ets:info(T2,stats),ets:info(T3,stats),ets:info(T4,stats)}}. - Mem2. + case {erlang:system_info({wordsize,internal}),erlang:system_info({wordsize,external})} of + %% Halfword, corrections for regular pointers occupying two internal words. + {4,8} -> + {A1,B1,C1,D1} = Mem1, + {A1+4*ets:info(T1, size)+?DB_TREE_STACK_NEED, + B1+3*ets:info(T2, size)+?DB_HASH_SIZEOF_EXTSEG, + C1+3*ets:info(T3, size)+?DB_HASH_SIZEOF_EXTSEG, + D1+3*ets:info(T4, size)+?DB_HASH_SIZEOF_EXTSEG}; + _ -> + Mem1 + end. t_whitebox(doc) -> ["Diverse whitebox testes"]; @@ -1037,6 +1026,8 @@ t_test_ms(Config) when is_list(Config) -> [{{'$1','$2'},[{'<','$1','$2'}],['$$']}]), ?line {ok,false} = ets:test_ms({a,b}, [{{'$1','$2'},[{'>','$1','$2'}],['$$']}]), + Tpl = {a,gb_sets:new()}, + ?line {ok,Tpl} = ets:test_ms(Tpl, [{{'_','_'}, [], ['$_']}]), % OTP-10190 ?line {error,[{error,String}]} = ets:test_ms({a,b}, [{{'$1','$2'}, [{'flurp','$1','$2'}], @@ -2179,20 +2170,29 @@ heir_do(Opts) -> ?line undefined = ets:info(foo), %% When heir dies and pid reused before founder dies - NextPidIx = erts_debug:get_internal_state(next_pid), - {Founder4,MrefF4} = my_spawn_monitor(fun()->heir_founder(Master,"The dying heir",Opts)end), - {Heir4,MrefH4} = my_spawn_monitor(fun()->heir_heir(Founder4)end), - Founder4 ! {go, Heir4}, - ?line {'DOWN', MrefH4, process, Heir4, normal} = receive_any(), - erts_debug:set_internal_state(next_pid, NextPidIx), - {Heir4,MrefH4_B} = spawn_monitor_with_pid(Heir4, - fun()-> ?line die_please = receive_any() end), - Founder4 ! die_please, - ?line {'DOWN', MrefF4, process, Founder4, normal} = receive_any(), - Heir4 ! die_please, - ?line {'DOWN', MrefH4_B, process, Heir4, normal} = receive_any(), - ?line undefined = ets:info(foo), - + repeat_while(fun() -> + NextPidIx = erts_debug:get_internal_state(next_pid), + {Founder4,MrefF4} = my_spawn_monitor(fun()->heir_founder(Master,"The dying heir",Opts)end), + {Heir4,MrefH4} = my_spawn_monitor(fun()->heir_heir(Founder4)end), + Founder4 ! {go, Heir4}, + ?line {'DOWN', MrefH4, process, Heir4, normal} = receive_any(), + erts_debug:set_internal_state(next_pid, NextPidIx), + DoppelGanger = spawn_monitor_with_pid(Heir4, + fun()-> ?line die_please = receive_any() end), + Founder4 ! die_please, + ?line {'DOWN', MrefF4, process, Founder4, normal} = receive_any(), + case DoppelGanger of + {Heir4,MrefH4_B} -> + Heir4 ! die_please, + ?line {'DOWN', MrefH4_B, process, Heir4, normal} = receive_any(), + ?line undefined = ets:info(foo), + false; + failed -> + io:format("Failed to spawn process with pid ~p\n", [Heir4]), + true % try again + end + end), + ?line verify_etsmem(EtsMem). heir_founder(Master, HeirData, Opts) -> @@ -4217,21 +4217,13 @@ heavy_lookup_element(Config) when is_list(Config) -> repeat_for_opts(heavy_lookup_element_do). heavy_lookup_element_do(Opts) -> - ?line EtsMem = etsmem(), - ?line Tab = ets_new(foobar_table, [set, protected, {keypos, 2} | Opts]), - ?line ok = fill_tab2(Tab, 0, 7000), - case os:type() of - vxworks -> - ?line ?t:do_times(5, ?MODULE, do_lookup_element, - [Tab, 6999, 1]); - % lookup ALL elements 5 times. - _ -> - ?line ?t:do_times(50, ?MODULE, do_lookup_element, - [Tab, 6999, 1]) - % lookup ALL elements 50 times. - end, - ?line true = ets:delete(Tab), - ?line verify_etsmem(EtsMem). + EtsMem = etsmem(), + Tab = ets_new(foobar_table, [set, protected, {keypos, 2} | Opts]), + ok = fill_tab2(Tab, 0, 7000), + % lookup ALL elements 50 times + ?t:do_times(50, ?MODULE, do_lookup_element, [Tab, 6999, 1]), + true = ets:delete(Tab), + verify_etsmem(EtsMem). do_lookup_element(_Tab, 0, _) -> ok; do_lookup_element(Tab, N, M) -> @@ -5483,6 +5475,20 @@ otp_9423(Config) when is_list(Config) -> Skipped -> Skipped end. + +%% Corrupted binary in compressed table +otp_10182(Config) when is_list(Config) -> + Bin = <<"aHR0cDovL2hvb3RzdWl0ZS5jb20vYy9wcm8tYWRyb2xsLWFi">>, + Key = {test, Bin}, + Value = base64:decode(Bin), + In = {Key,Value}, + Db = ets:new(undefined, [set, protected, {read_concurrency, true}, compressed]), + ets:insert(Db, In), + [Out] = ets:lookup(Db, Key), + io:format("In : ~p\nOut: ~p\n", [In,Out]), + ets:delete(Db), + In = Out. + @@ -5790,25 +5796,20 @@ receive_any_spinning(Loops, N, Tries) when N>0 -> spawn_monitor_with_pid(Pid, Fun) when is_pid(Pid) -> - spawn_monitor_with_pid(Pid, Fun, 1, 10). + spawn_monitor_with_pid(Pid, Fun, 10). -spawn_monitor_with_pid(Pid, Fun, N, M) when N > M*10 -> - spawn_monitor_with_pid(Pid, Fun, N, M*10); -spawn_monitor_with_pid(Pid, Fun, N, M) -> - ?line false = is_process_alive(Pid), +spawn_monitor_with_pid(_, _, 0) -> + failed; +spawn_monitor_with_pid(Pid, Fun, N) -> case my_spawn(fun()-> case self() of Pid -> Fun(); _ -> die end end) of - Pid -> + Pid -> {Pid, erlang:monitor(process, Pid)}; Other -> - case N rem M of - 0 -> io:format("Failed ~p times to get pid ~p (current = ~p)\n",[N,Pid,Other]); - _ -> ok - end, - spawn_monitor_with_pid(Pid,Fun,N+1,M) + spawn_monitor_with_pid(Pid,Fun,N-1) end. |