Re: Maps equality failure / Maps merge failure

Björn-Egil Dahlberg <[email protected]>
Newsgroups gmane.comp.lang.erlang.bugs
Message-ID <[email protected]>
On 2015-03-24 15:16, Jesper Louis Andersen wrote:
> Hi OTP team (and other readers),

Hi Jesper!

Awesome! Thank you for reporting this and thank you for your quickcheck 
model. =D

term_to_binary binary_to_term problem has already been spotted and a fix 
is on it's way.

We will look into the others now.

// Björn-Egil

>
> Over the weekend, I've been building up a QuickCheck model of 
> Erlang/OTP maps(). This is to be able to properly test the HAMT maps 
> of the up-and-coming 18.0 release for correctness, but I'm testing on 
> 17.4.1 as well. The following problem occurs for release 17.4.1. (for 
> the curious, 18.0 currently segfaults on these tests):
>
> Erlang/OTP 17 [erts-6.3.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] 
> [async-threads:10] [kernel-poll:false]
>
> Eshell V6.3.1  (abort with ^G)
> 1> Map = #{0 => 0,2147483648 => 0}.
> #{0 => 0,2147483648 => 0}
> 2> Bin = term_to_binary(M).
> * 1: variable 'M' is unbound
> 3> Bin = term_to_binary(Map).
> <<131,116,0,0,0,2,97,0,97,0,110,4,0,0,0,0,128,97,0>>
> 4> Map2 = binary_to_term(Bin).
> #{2147483648 => 0,0 => 0}
> 5> Map =:= Map2.
> false
>
> (copied verbatim, including my error in 2>)
>
> The problem is that if I convert the map to a binary and then back 
> again, the two maps are not equal. Furthermore, they print differently:
>
> 6> Map.
> #{0 => 0,2147483648 => 0}
> 7> Map2.
> #{2147483648 => 0,0 => 0}
> 8>
>
> The value 2147483648 seems important and it is 2^31. However, the 
> problem also occurs at 2^31 + 1. Only testing with "small" integers 
> poses no problem at all. I have yet to test against floating point 
> numbers and this requires some additional attention to detail as they 
> have fun equality rules :)
>
> A second problem occurs in merges, which may be related or may not be 
> related. In the second problem, we are merging maps
>
> [#{-2147483649 => 0,
>    0 => 0,
>    97 => 0,
>    false => 0,
>    flower => 0,
>    #Fun<eqc_gen.133.121384563> => 0,
>    #Fun<eqc_gen.133.121384563> => 0,
>    <<>> => 0},
>  #{0 => 1}]
>
> where the #Fun's are generated functions of 0 and 2 parameters 
> respectively. Lets see how to create such a map (one might note that 
> direct creation through #{ ... } syntax would make the keys which are 
> functions illegal, but I am an experiened Erlang programmer and have a 
> way around such petty limitations :P)
>
> 9> F1 = fun(_, _) -> 0 end,
> 9> F2 = fun(_, _) -> 1 end.
>
> This defines two functions:
>
> 11> maps:from_list(
> 11> [{-2147483649, 0},
> 11>    {0,0}, {97, 0}, {false, 0}, {flower, 0}, {F1, 0}, {F2, 0}, 
> {<<>>, 0}]).
> #{-2147483649 => 0,
>   0 => 0,
>   97 => 0,
>   false => 0,
>   flower => 0,
>   #Fun<erl_eval.12.90072148> => 0,
>   #Fun<erl_eval.12.90072148> => 0,
>   <<>> => 0}
>
> Remarkably, this is well-defined, now lets merge:
>
> 12> maps:merge(v(11), #{0 => 1}).
> #{0 => 1,
>   -2147483649 => 0,
>   0 => 0,
>   97 => 0,
>   false => 0,
>   flower => 0,
>   #Fun<erl_eval.12.90072148> => 0,
>   #Fun<erl_eval.12.90072148> => 0,
>   <<>> => 0}
> 13>
>
> The resulting map now has to '0' keys! Rejoice!
>
> The model I am using is the following:
>
> https://github.com/jlouis/maps_eqc/tree/ac7748ce81781ae6c1ad7b4ed07ca5cd935c125d
>
> (maps_iso_eqc are simple stateless tests, whereas maps_eqc is a more 
> complicated stateful test which also verifies properties about copying 
> maps between processes and that maps are persistent data structures).
>
> To run:
>
> make:all([load]).
> eqc:module({testing_budget, 20}, maps_iso_eqc).
>
> Two test runs of mine:
>
> https://gist.github.com/jlouis/39de114e0a447af983a5
>
> Note the latter merge test which managed to shrink over 1200 times!
>
>
> -- 
> J.
>
>
> _______________________________________________
> erlang-bugs mailing list
> [email protected]
> http://erlang.org/mailman/listinfo/erlang-bugs

_______________________________________________
erlang-bugs mailing list
[email protected]
http://erlang.org/mailman/listinfo/erlang-bugs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.