Skip to content

Commit

Permalink
Merge pull request scylladb#317 from illia-li/il/add/marshal/map_tests
Browse files Browse the repository at this point in the history
Add `map` marshal tests
  • Loading branch information
dkropachev authored Oct 22, 2024
2 parents 32250de + d947f10 commit c826ec4
Show file tree
Hide file tree
Showing 6 changed files with 546 additions and 1 deletion.
21 changes: 21 additions & 0 deletions internal/tests/serialization/mod/custom.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ type (
MapInt16C map[Int16]Int16
MapInt16CR map[Int16]*Int16

MapInt32 map[int32]int32
MapInt32R map[int32]*int32
MapInt32C map[Int32]Int32
MapInt32CR map[Int32]*Int32

MapUDT map[string]interface{}
)

Expand Down Expand Up @@ -158,6 +163,14 @@ func customType(i interface{}) interface{} {
return MapInt16C(v)
case map[Int16]*Int16:
return MapInt16CR(v)
case map[int32]int32:
return MapInt32(v)
case map[int32]*int32:
return MapInt32R(v)
case map[Int32]Int32:
return MapInt32C(v)
case map[Int32]*Int32:
return MapInt32CR(v)
case map[string]interface{}:
return MapUDT(v)
case []interface{}:
Expand Down Expand Up @@ -245,6 +258,14 @@ func intoCustomR(i interface{}) interface{} {
return (*MapInt16C)(v)
case *map[Int16]*Int16:
return (*MapInt16CR)(v)
case *map[int32]int32:
return (*MapInt32)(v)
case *map[int32]*int32:
return (*MapInt32R)(v)
case *map[Int32]Int32:
return (*MapInt32C)(v)
case *map[Int32]*Int32:
return (*MapInt32CR)(v)
case *map[string]interface{}:
return (*MapUDT)(v)
case *[]interface{}:
Expand Down
2 changes: 1 addition & 1 deletion internal/tests/serialization/utils_str.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const printLimit = 100
func stringValue(in interface{}) string {
valStr := stringVal(in)
if len(valStr) > printLimit {
valStr = valStr[:printLimit]
return fmt.Sprintf("(%T)", in)
}
return fmt.Sprintf("(%T)(%s)", in, valStr)
}
Expand Down
191 changes: 191 additions & 0 deletions tests/serialization/marshal_20_map_v2_corrupt_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
package serialization_test

import (
"fmt"
"math"
"testing"

"github.com/gocql/gocql"
"github.com/gocql/gocql/internal/tests/serialization"
"github.com/gocql/gocql/internal/tests/serialization/mod"
)

func TestMarshalMapV2Corrupt(t *testing.T) {
elem := gocql.NewNativeType(2, gocql.TypeSmallInt, "")
tType := gocql.NewCollectionType(gocql.NewNativeType(2, gocql.TypeMap, ""), elem, elem)

//unmarshal data than bigger the normal data, does not return error.
brokenBigData := serialization.GetTypes(mod.Values{
make(map[int16]int16), make(map[int16]*int16),
make(map[mod.Int16]mod.Int16), make(map[mod.Int16]*mod.Int16),
}.AddVariants(mod.All...)...)

refInt32 := func(v int32) *int32 { return &v }
refModInt32 := func(v mod.Int32) *mod.Int32 { return &v }

marshal := func(i interface{}) ([]byte, error) { return gocql.Marshal(tType, i) }
unmarshal := func(bytes []byte, i interface{}) error {
return gocql.Unmarshal(tType, bytes, i)
}

val := int32(math.MaxInt16 + 1)
valc := mod.Int32(val)
serialization.NegativeMarshalSet{
Values: mod.Values{
map[int32]int32{val: val}, map[int32]int32{val: 0}, map[int32]int32{0: val},
map[int32]*int32{val: refInt32(val)}, map[int32]*int32{val: refInt32(0)}, map[int32]*int32{0: refInt32(val)},
map[mod.Int32]mod.Int32{valc: valc}, map[mod.Int32]mod.Int32{valc: 0}, map[mod.Int32]mod.Int32{0: valc},
map[mod.Int32]*mod.Int32{valc: refModInt32(valc)}, map[mod.Int32]*mod.Int32{valc: refModInt32(0)}, map[mod.Int32]*mod.Int32{0: refModInt32(valc)},
}.AddVariants(mod.All...),
}.Run("big_vals", t, marshal)

serialization.NegativeUnmarshalSet{
Data: []byte("\x00\x01\x00\x02\xff\xff\x00\x02\xff\xff\x01"),
Values: mod.Values{
make(map[int16]int16), make(map[int16]*int16),
make(map[mod.Int16]mod.Int16), make(map[mod.Int16]*mod.Int16),
}.AddVariants(mod.All...),
BrokenTypes: brokenBigData,
}.Run("big_data_elem1+", t, unmarshal)

serialization.NegativeUnmarshalSet{
Data: []byte("\x00\x01\x00\x00\x00\x00\xff"),
Values: mod.Values{
make(map[int16]int16), make(map[int16]*int16),
make(map[mod.Int16]mod.Int16), make(map[mod.Int16]*mod.Int16),
}.AddVariants(mod.All...),
BrokenTypes: brokenBigData,
}.Run("big_data_zeroElem1+", t, unmarshal)

serialization.NegativeUnmarshalSet{
Data: []byte("\x00\x00\x01"),
Values: mod.Values{
make(map[int16]int16), make(map[int16]*int16),
make(map[mod.Int16]mod.Int16), make(map[mod.Int16]*mod.Int16),
}.AddVariants(mod.All...),
BrokenTypes: brokenBigData,
}.Run("big_data_elems0+", t, unmarshal)

serialization.NegativeUnmarshalSet{
Data: []byte("\x00\x01\x00\x02\xff\xff\x00\x02\xff"),
Values: mod.Values{
make(map[int16]int16), make(map[int16]*int16),
make(map[mod.Int16]mod.Int16), make(map[mod.Int16]*mod.Int16),
}.AddVariants(mod.All...),
}.Run("small_data_val_value-", t, unmarshal)

serialization.NegativeUnmarshalSet{
Data: []byte("\x00\x01\x00\x02\xff\xff\x00\x02"),
Values: mod.Values{
make(map[int16]int16), make(map[int16]*int16),
make(map[mod.Int16]mod.Int16), make(map[mod.Int16]*mod.Int16),
}.AddVariants(mod.All...),
}.Run("small_data_val_len", t, unmarshal)

serialization.NegativeUnmarshalSet{
Data: []byte("\x00\x01\x00\x02\xff\xff\x00"),
Values: mod.Values{
make(map[int16]int16), make(map[int16]*int16),
make(map[mod.Int16]mod.Int16), make(map[mod.Int16]*mod.Int16),
}.AddVariants(mod.All...),
}.Run("small_data_val_len-", t, unmarshal)

serialization.NegativeUnmarshalSet{
Data: []byte("\x00\x01\x00\x02\xff\xff"),
Values: mod.Values{
make(map[int16]int16), make(map[int16]*int16),
make(map[mod.Int16]mod.Int16), make(map[mod.Int16]*mod.Int16),
}.AddVariants(mod.All...),
}.Run("small_data_val-", t, unmarshal)

serialization.NegativeUnmarshalSet{
Data: []byte("\x00\x01\x00\x02\xff"),
Values: mod.Values{
make(map[int16]int16), make(map[int16]*int16),
make(map[mod.Int16]mod.Int16), make(map[mod.Int16]*mod.Int16),
}.AddVariants(mod.All...),
}.Run("small_data_key_value-", t, unmarshal)

serialization.NegativeUnmarshalSet{
Data: []byte("\x00\x01\x00\x02"),
Values: mod.Values{
make(map[int16]int16), make(map[int16]*int16),
make(map[mod.Int16]mod.Int16), make(map[mod.Int16]*mod.Int16),
}.AddVariants(mod.All...),
}.Run("small_data_key_len", t, unmarshal)

serialization.NegativeUnmarshalSet{
Data: []byte("\x00\x01\x00"),
Values: mod.Values{
make(map[int16]int16), make(map[int16]*int16),
make(map[mod.Int16]mod.Int16), make(map[mod.Int16]*mod.Int16),
}.AddVariants(mod.All...),
}.Run("small_data_key_len-", t, unmarshal)

serialization.NegativeUnmarshalSet{
Data: []byte("\x00\x01"),
Values: mod.Values{
make(map[int16]int16), make(map[int16]*int16),
make(map[mod.Int16]mod.Int16), make(map[mod.Int16]*mod.Int16),
}.AddVariants(mod.All...),
}.Run("small_data_pair-", t, unmarshal)

serialization.NegativeUnmarshalSet{
Data: []byte("\x00"),
Values: mod.Values{
make(map[int16]int16), make(map[int16]*int16),
make(map[mod.Int16]mod.Int16), make(map[mod.Int16]*mod.Int16),
}.AddVariants(mod.All...),
}.Run("small_data_elems-", t, unmarshal)
}

func TestMarshalMapV2CorruptMax(t *testing.T) {
t.Parallel()
elem := gocql.NewNativeType(2, gocql.TypeSmallInt, "")
tType := gocql.NewCollectionType(gocql.NewNativeType(2, gocql.TypeMap, ""), elem, elem)

elems := math.MaxUint16 + 1
values := []func() interface{}{
func() interface{} {
out := make(map[int32]int32, elems)
for i := 0; i < elems; i++ {
out[int32(i)] = int32(1)
}
return out
},
func() interface{} {
out := make(map[int32]*int32, elems)
for i := 0; i < elems; i++ {
tmp := int32(1)
out[int32(i)] = &tmp
}
return out
},
func() interface{} {
out := make(map[mod.Int32]mod.Int32, elems)
for i := 0; i < elems; i++ {
out[mod.Int32(i)] = mod.Int32(1)
}
return out
},
func() interface{} {
out := make(map[mod.Int32]*mod.Int32, elems)
for i := 0; i < elems; i++ {
tmp := mod.Int32(1)
out[mod.Int32(i)] = &tmp
}
return out
},
}

marshal := func(i interface{}) ([]byte, error) { return gocql.Marshal(tType, i) }

for _, v := range values {
value := v()
name := fmt.Sprintf("%T", value)

serialization.NegativeMarshalSet{
Values: mod.Values{value}.AddVariants(mod.All...),
}.Run(name, t, marshal)
}
}
130 changes: 130 additions & 0 deletions tests/serialization/marshal_20_map_v2_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package serialization_test

import (
"fmt"
"math"
"testing"

"github.com/gocql/gocql"
"github.com/gocql/gocql/internal/tests/serialization"
"github.com/gocql/gocql/internal/tests/serialization/mod"
)

func TestMarshalMapV2(t *testing.T) {
elem := gocql.NewNativeType(2, gocql.TypeSmallInt, "")
tType := gocql.NewCollectionType(gocql.NewNativeType(2, gocql.TypeMap, ""), elem, elem)

refInt16 := func(v int16) *int16 { return &v }
refModInt16 := func(v mod.Int16) *mod.Int16 { return &v }

marshal := func(i interface{}) ([]byte, error) { return gocql.Marshal(tType, i) }
unmarshal := func(bytes []byte, i interface{}) error {
return gocql.Unmarshal(tType, bytes, i)
}

serialization.PositiveSet{
Data: nil,
Values: mod.Values{
(map[int16]int16)(nil), (map[int16]*int16)(nil),
(map[mod.Int16]mod.Int16)(nil), (map[mod.Int16]*mod.Int16)(nil),
(*map[int16]int16)(nil), (*map[int16]*int16)(nil),
(*map[mod.Int16]mod.Int16)(nil), (*map[mod.Int16]*mod.Int16)(nil),
}.AddVariants(mod.CustomType),
}.Run("[nil]nullable", t, marshal, unmarshal)

serialization.PositiveSet{
Data: []byte("\x00\x00"),
Values: mod.Values{
make(map[int16]int16), make(map[int16]*int16),
make(map[mod.Int16]mod.Int16), make(map[mod.Int16]*mod.Int16),
}.AddVariants(mod.All...),
}.Run("zero elems", t, marshal, unmarshal)

serialization.PositiveSet{
Data: []byte("\x00\x01\x00\x00\x00\x00"),
Values: mod.Values{
map[int16]int16{0: 0}, map[int16]*int16{0: refInt16(0)},
map[mod.Int16]mod.Int16{0: 0}, map[mod.Int16]*mod.Int16{0: refModInt16(0)},
}.AddVariants(mod.All...),
}.Run("[]{zero elem}unmarshal", t, nil, unmarshal)

serialization.PositiveSet{
Data: []byte("\x00\x01\x00\x02\x00\x00\x00\x02\x00\x00"),
Values: mod.Values{
map[int16]int16{0: 0}, map[int16]*int16{0: refInt16(0)},
map[mod.Int16]mod.Int16{0: 0}, map[mod.Int16]*mod.Int16{0: refModInt16(0)},
}.AddVariants(mod.All...),
}.Run("[]{0:0}", t, marshal, unmarshal)

serialization.PositiveSet{
Data: []byte("\x00\x01\x00\x02\x7f\xff\x00\x02\x7f\xff"),
Values: mod.Values{
map[int16]int16{32767: 32767}, map[int16]*int16{32767: refInt16(32767)},
map[mod.Int16]mod.Int16{32767: 32767}, map[mod.Int16]*mod.Int16{32767: refModInt16(32767)},
}.AddVariants(mod.All...),
}.Run("[]{max:max}", t, marshal, unmarshal)
}

func TestMarshalMapV2Max(t *testing.T) {
t.Parallel()
elem := gocql.NewNativeType(2, gocql.TypeSmallInt, "")
tType := gocql.NewCollectionType(gocql.NewNativeType(2, gocql.TypeMap, ""), elem, elem)

elems := math.MaxUint16

data := make([]byte, 0, elems*4+2)
data = append(data, 255, 255)
uintData := func(v uint) (byte, byte) {
return byte(v >> 8), byte(v)
}
for v := 0; v < elems; v++ {
b1, b2 := uintData(uint(v))
data = append(data, 0, 2, b1, b2, 0, 2, 0, 1)
}

values := []func() interface{}{
func() interface{} {
out := make(map[int16]int16, elems)
for i := 0; i < elems; i++ {
out[int16(i)] = int16(1)
}
return out
},
func() interface{} {
out := make(map[int16]*int16, elems)
for i := 0; i < elems; i++ {
tmp := int16(1)
out[int16(i)] = &tmp
}
return out
},
func() interface{} {
out := make(map[mod.Int16]mod.Int16, elems)
for i := 0; i < elems; i++ {
out[mod.Int16(i)] = mod.Int16(1)
}
return out
},
func() interface{} {
out := make(map[mod.Int16]*mod.Int16, elems)
for i := 0; i < elems; i++ {
tmp := mod.Int16(1)
out[mod.Int16(i)] = &tmp
}
return out
},
}
unmarshal := func(bytes []byte, i interface{}) error {
return gocql.Unmarshal(tType, bytes, i)
}

for _, v := range values {
value := v()
name := fmt.Sprintf("%T", value)

serialization.PositiveSet{
Data: data,
Values: mod.Values{value}.AddVariants(mod.All...),
}.Run(name, t, nil, unmarshal)
}
}
Loading

0 comments on commit c826ec4

Please sign in to comment.