@ -95,6 +95,12 @@ func TestHash(t *testing.T) {
{ in : tuple { scalars { F64 : float64 ( math . NaN ( ) ) } , scalars { F64 : float64 ( math . NaN ( ) ) } } , wantEq : true } ,
{ in : tuple { scalars { F64 : float64 ( math . NaN ( ) ) } , scalars { F64 : float64 ( math . NaN ( ) ) } } , wantEq : true } ,
{ in : tuple { scalars { C64 : 32 + 32i } , scalars { C64 : complex ( math . Nextafter32 ( 32 , 0 ) , 32 ) } } , wantEq : false } ,
{ in : tuple { scalars { C64 : 32 + 32i } , scalars { C64 : complex ( math . Nextafter32 ( 32 , 0 ) , 32 ) } } , wantEq : false } ,
{ in : tuple { scalars { C128 : 64 + 64i } , scalars { C128 : complex ( math . Nextafter ( 64 , 0 ) , 64 ) } } , wantEq : false } ,
{ in : tuple { scalars { C128 : 64 + 64i } , scalars { C128 : complex ( math . Nextafter ( 64 , 0 ) , 64 ) } } , wantEq : false } ,
{ in : tuple { [ ] int ( nil ) , [ ] int ( nil ) } , wantEq : true } ,
{ in : tuple { [ ] int { } , [ ] int ( nil ) } , wantEq : false } ,
{ in : tuple { [ ] int { } , [ ] int { } } , wantEq : true } ,
{ in : tuple { [ ] string ( nil ) , [ ] string ( nil ) } , wantEq : true } ,
{ in : tuple { [ ] string { } , [ ] string ( nil ) } , wantEq : false } ,
{ in : tuple { [ ] string { } , [ ] string { } } , wantEq : true } ,
{ in : tuple { [ ] appendBytes { { } , { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 } } , [ ] appendBytes { { } , { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 } } } , wantEq : true } ,
{ in : tuple { [ ] appendBytes { { } , { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 } } , [ ] appendBytes { { } , { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 } } } , wantEq : true } ,
{ in : tuple { [ ] appendBytes { { } , { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 } } , [ ] appendBytes { { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 } , { } } } , wantEq : false } ,
{ in : tuple { [ ] appendBytes { { } , { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 } } , [ ] appendBytes { { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 } , { } } } , wantEq : false } ,
{ in : tuple { iface { MyBool ( true ) } , iface { MyBool ( true ) } } , wantEq : true } ,
{ in : tuple { iface { MyBool ( true ) } , iface { MyBool ( true ) } } , wantEq : true } ,
@ -413,13 +419,13 @@ func TestGetTypeHasher(t *testing.T) {
{
{
name : "string_slice" ,
name : "string_slice" ,
val : [ ] string { "foo" , "bar" } ,
val : [ ] string { "foo" , "bar" } ,
out : "\x0 2\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00foo\x03\x00\x00\x00\x00\x00\x00\x00bar",
out : "\x0 1\x0 2\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00foo\x03\x00\x00\x00\x00\x00\x00\x00bar",
} ,
} ,
{
{
name : "int_slice" ,
name : "int_slice" ,
val : [ ] int { 1 , 0 , - 1 } ,
val : [ ] int { 1 , 0 , - 1 } ,
out : "\x0 3\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff",
out : "\x0 1\x0 3\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff",
out32 : "\x0 3\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff",
out32 : "\x0 1\x0 3\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff",
} ,
} ,
{
{
name : "struct" ,
name : "struct" ,
@ -454,8 +460,8 @@ func TestGetTypeHasher(t *testing.T) {
{
{
name : "packet_filter" ,
name : "packet_filter" ,
val : filterRules ,
val : filterRules ,
out : "\x0 4\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00*\v\x00\x00\x00\x00\x00\x00\x0010.1.3.4/32\v\x00\x00\x00\x00\x00\x00\x0010.0.0.0/24\x03\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x001.2.3.4/32\x01 \x00\x00\x00\x00\x00\x00\x00\x01\x00\x02\x00\x04\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x01\x02\x03\x04 \x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00foo\x01\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00foooooooooo\x00\x00\x00\x00\x00\x00\x00\x00 \x01\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00baaaaaarrrrr\x00\x01\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00foooooooooo\x00\x00\x00\x00\x00\x00\x00\x00 \x01\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00baaaaaarrrrr\x00\x01\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00foooooooooo\x00\x00\x00\x00\x00\x00\x00\x00 \x01\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00baaaaaarrrrr\x00\x01\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00",
out : "\x0 1\x0 4\x00\x00\x00\x00\x00\x00\x00\x01 \x03\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00*\v\x00\x00\x00\x00\x00\x00\x0010.1.3.4/32\v\x00\x00\x00\x00\x00\x00\x0010.0.0.0/24\x01\x0 3\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x01\x01\x0 0\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x001.2.3.4/32\x01 \x00\x00\x00\x00\x00\x00\x00\x01\x00\x02\x00\x01\x0 4\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x01\x01\x0 0\x00\x00\x00\x00\x00\x00\x01\x01\x0 0\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x01\x02\x03\x04 \x00\x01\x01\x0 0\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00foo\x01\x01\x0 0\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00foooooooooo\x00\x01 \x01\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00baaaaaarrrrr\x00\x01\x00\x02\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00foooooooooo\x00\x01 \x01\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00baaaaaarrrrr\x00\x01\x00\x02\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00foooooooooo\x00\x01 \x01\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00baaaaaarrrrr\x00\x01\x00\x02\x00\x00\x00",
out32 : "\x0 4\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00*\v\x00\x00\x00\x00\x00\x00\x0010.1.3.4/32\v\x00\x00\x00\x00\x00\x00\x0010.0.0.0/24\x03\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x001.2.3.4/32\x01 \x00\x00\x00\x01\x00\x02\x00\x04\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x01\x02\x03\x04 \x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00foo\x01\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00foooooooooo\x00\x00\x00\x00\x00\x00\x00\x00 \x01\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00baaaaaarrrrr\x00\x01\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00foooooooooo\x00\x00\x00\x00\x00\x00\x00\x00 \x01\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00baaaaaarrrrr\x00\x01\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00foooooooooo\x00\x00\x00\x00\x00\x00\x00\x00 \x01\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00baaaaaarrrrr\x00\x01\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00",
out32 : "\x0 1\x0 4\x00\x00\x00\x00\x00\x00\x00\x01 \x03\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00*\v\x00\x00\x00\x00\x00\x00\x0010.1.3.4/32\v\x00\x00\x00\x00\x00\x00\x0010.0.0.0/24\x01\x0 3\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x01 \x01\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x001.2.3.4/32\x01 \x00\x00\x00\x01\x00\x02\x00\x01\x0 4\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x01\x01\x0 0\x00\x00\x00\x00\x00\x00\x01\x01\x0 0\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x01\x02\x03\x04 \x00\x01\x01\x0 0\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00foo\x01\x01\x0 0\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00foooooooooo\x00\x01 \x01\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00baaaaaarrrrr\x00\x01\x00\x02\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00foooooooooo\x00\x01 \x01\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00baaaaaarrrrr\x00\x01\x00\x02\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00foooooooooo\x00\x01 \x01\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00baaaaaarrrrr\x00\x01\x00\x02\x00\x00\x00",
} ,
} ,
{
{
name : "netip.Addr" ,
name : "netip.Addr" ,
@ -569,7 +575,7 @@ func TestGetTypeHasher(t *testing.T) {
{
{
name : "tailcfg.Node" ,
name : "tailcfg.Node" ,
val : & tailcfg . Node { } ,
val : & tailcfg . Node { } ,
out : "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 " + u64 ( uint64 ( time . Time { } . Unix ( ) ) ) + u64 ( 0 ) + u32 ( 0 ) + u32 ( 0 ) + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + u64 ( uint64 ( time . Time { } . Unix ( ) ) ) + u32 ( 0 ) + u32 ( 0 ) + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
out : "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\tn\x88\xf1\xff\xff\xff \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\tn\x88\xf1\xff\xff\xff \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
} ,
} ,
}
}
for _ , tt := range tests {
for _ , tt := range tests {
@ -594,6 +600,44 @@ func TestGetTypeHasher(t *testing.T) {
}
}
}
}
func TestSliceCycle ( t * testing . T ) {
type S [ ] S
c := qt . New ( t )
a := make ( S , 1 ) // cylic graph of 1 node
a [ 0 ] = a
b := make ( S , 1 ) // cylic graph of 1 node
b [ 0 ] = b
ha := Hash ( & a )
hb := Hash ( & b )
c . Assert ( ha , qt . Equals , hb )
c1 := make ( S , 1 ) // cyclic graph of 2 nodes
c2 := make ( S , 1 ) // cyclic graph of 2 nodes
c1 [ 0 ] = c2
c2 [ 0 ] = c1
hc1 := Hash ( & c1 )
hc2 := Hash ( & c2 )
c . Assert ( hc1 , qt . Equals , hc2 )
c . Assert ( ha , qt . Not ( qt . Equals ) , hc1 )
c . Assert ( hb , qt . Not ( qt . Equals ) , hc2 )
c3 := make ( S , 1 ) // graph of 1 node pointing to cyclic graph of 2 nodes
c3 [ 0 ] = c1
hc3 := Hash ( & c3 )
c . Assert ( hc1 , qt . Not ( qt . Equals ) , hc3 )
c4 := make ( S , 2 ) // cyclic graph of 3 nodes
c5 := make ( S , 2 ) // cyclic graph of 3 nodes
c4 [ 0 ] = nil
c4 [ 1 ] = c4
c5 [ 0 ] = c5
c5 [ 1 ] = nil
hc4 := Hash ( & c4 )
hc5 := Hash ( & c5 )
c . Assert ( hc4 , qt . Not ( qt . Equals ) , hc5 ) // cycle occurs through different indexes
}
func TestMapCycle ( t * testing . T ) {
func TestMapCycle ( t * testing . T ) {
type M map [ string ] M
type M map [ string ] M
c := qt . New ( t )
c := qt . New ( t )
@ -620,6 +664,16 @@ func TestMapCycle(t *testing.T) {
c3 [ "child" ] = c1
c3 [ "child" ] = c1
hc3 := Hash ( & c3 )
hc3 := Hash ( & c3 )
c . Assert ( hc1 , qt . Not ( qt . Equals ) , hc3 )
c . Assert ( hc1 , qt . Not ( qt . Equals ) , hc3 )
c4 := make ( M ) // cyclic graph of 3 nodes
c5 := make ( M ) // cyclic graph of 3 nodes
c4 [ "0" ] = nil
c4 [ "1" ] = c4
c5 [ "0" ] = c5
c5 [ "1" ] = nil
hc4 := Hash ( & c4 )
hc5 := Hash ( & c5 )
c . Assert ( hc4 , qt . Not ( qt . Equals ) , hc5 ) // cycle occurs through different keys
}
}
func TestPointerCycle ( t * testing . T ) {
func TestPointerCycle ( t * testing . T ) {