[#77] protogen: Initial implementation

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
This commit is contained in:
Evgenii Stratonikov 2024-04-25 15:13:10 +03:00
parent a28ceb251a
commit adb7c602d7
115 changed files with 36376 additions and 20397 deletions

View file

@ -6,6 +6,7 @@ import (
"testing"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/util/proto/test"
generated "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/util/proto/test/custom"
"github.com/stretchr/testify/require"
goproto "google.golang.org/protobuf/proto"
)
@ -24,39 +25,43 @@ func nonZero[T protoInt]() T {
func TestStableMarshalSingle(t *testing.T) {
t.Run("empty", func(t *testing.T) {
input := &test.Primitives{}
input := &generated.Primitives{}
require.Zero(t, input.StableSize())
r := input.StableMarshal(nil)
r := input.MarshalProtobuf(nil)
require.Empty(t, r)
})
marshalCases := []struct {
name string
input *test.Primitives
input *generated.Primitives
}{
{name: "bytes", input: &test.Primitives{FieldA: []byte{1, 2, 3}}},
{name: "string", input: &test.Primitives{FieldB: "123"}},
{name: "bool", input: &test.Primitives{FieldC: true}},
{name: "int32", input: &test.Primitives{FieldD: nonZero[int32]()}},
{name: "uint32", input: &test.Primitives{FieldE: nonZero[uint32]()}},
{name: "int64", input: &test.Primitives{FieldF: nonZero[int64]()}},
{name: "uint64", input: &test.Primitives{FieldG: nonZero[uint64]()}},
{name: "uint64", input: &test.Primitives{FieldI: nonZero[uint64]()}},
{name: "float64", input: &test.Primitives{FieldJ: math.Float64frombits(12345677890)}},
{name: "fixed32", input: &test.Primitives{FieldK: nonZero[uint32]()}},
{name: "enum, positive", input: &test.Primitives{FieldH: test.Primitives_POSITIVE}},
{name: "enum, negative", input: &test.Primitives{FieldH: test.Primitives_NEGATIVE}},
{name: "bytes", input: &generated.Primitives{FieldA: []byte{1, 2, 3}}},
{name: "string", input: &generated.Primitives{FieldB: "123"}},
{name: "bool", input: &generated.Primitives{FieldC: true}},
{name: "int32", input: &generated.Primitives{FieldD: -10}},
{name: "uint32", input: &generated.Primitives{FieldE: nonZero[uint32]()}},
{name: "int64", input: &generated.Primitives{FieldF: nonZero[int64]()}},
{name: "uint64", input: &generated.Primitives{FieldG: nonZero[uint64]()}},
{name: "uint64", input: &generated.Primitives{FieldI: nonZero[uint64]()}},
{name: "float64", input: &generated.Primitives{FieldJ: math.Float64frombits(12345677890)}},
{name: "fixed32", input: &generated.Primitives{FieldK: nonZero[uint32]()}},
{name: "enum, positive", input: &generated.Primitives{FieldH: generated.Primitives_POSITIVE}},
{name: "enum, negative", input: &generated.Primitives{FieldH: generated.Primitives_NEGATIVE}},
}
for _, tc := range marshalCases {
t.Run(tc.name, func(t *testing.T) {
r := tc.input.StableMarshal(nil)
r := tc.input.MarshalProtobuf(nil)
require.Equal(t, len(r), tc.input.StableSize())
require.NotEmpty(t, r)
var actual test.Primitives
require.NoError(t, goproto.Unmarshal(r, &actual))
var actualFrostfs generated.Primitives
require.NoError(t, actualFrostfs.UnmarshalProtobuf(r))
require.Equal(t, tc.input, &actualFrostfs)
// Compare each field directly, because proto-generated code has private fields.
require.Equal(t, tc.input.FieldA, actual.FieldA)
require.Equal(t, tc.input.FieldB, actual.FieldB)
@ -68,7 +73,7 @@ func TestStableMarshalSingle(t *testing.T) {
require.Equal(t, tc.input.FieldI, actual.FieldI)
require.Equal(t, tc.input.FieldJ, actual.FieldJ)
require.Equal(t, tc.input.FieldK, actual.FieldK)
require.Equal(t, tc.input.FieldH, actual.FieldH)
require.EqualValues(t, tc.input.FieldH, actual.FieldH)
})
}
}
@ -91,51 +96,53 @@ func TestStableMarshalRep(t *testing.T) {
t.Run("empty", func(t *testing.T) {
marshalCases := []struct {
name string
input *test.RepPrimitives
input *generated.RepPrimitives
}{
{name: "default", input: &test.RepPrimitives{}},
{name: "bytes", input: &test.RepPrimitives{FieldA: [][]byte{}}},
{name: "string", input: &test.RepPrimitives{FieldB: []string{}}},
{name: "int32", input: &test.RepPrimitives{FieldC: []int32{}}},
{name: "uint32", input: &test.RepPrimitives{FieldD: []uint32{}}},
{name: "int64", input: &test.RepPrimitives{FieldE: []int64{}}},
{name: "uint64", input: &test.RepPrimitives{FieldF: []uint64{}}},
{name: "uint64", input: &test.RepPrimitives{FieldFu: []uint64{}}},
{name: "default", input: &generated.RepPrimitives{}},
{name: "bytes", input: &generated.RepPrimitives{FieldA: [][]byte{}}},
{name: "string", input: &generated.RepPrimitives{FieldB: []string{}}},
{name: "int32", input: &generated.RepPrimitives{FieldC: []int32{}}},
{name: "uint32", input: &generated.RepPrimitives{FieldD: []uint32{}}},
{name: "int64", input: &generated.RepPrimitives{FieldE: []int64{}}},
{name: "uint64", input: &generated.RepPrimitives{FieldF: []uint64{}}},
{name: "uint64", input: &generated.RepPrimitives{FieldFu: []uint64{}}},
}
for _, tc := range marshalCases {
require.Zero(t, tc.input.StableSize())
t.Run(tc.name, func(t *testing.T) {
require.Zero(t, tc.input.StableSize())
r := tc.input.StableMarshal(nil)
require.Empty(t, r)
r := tc.input.MarshalProtobuf(nil)
require.Empty(t, r)
})
}
})
marshalCases := []struct {
name string
input *test.RepPrimitives
input *generated.RepPrimitives
}{
{name: "bytes", input: &test.RepPrimitives{FieldA: [][]byte{{1, 2, 3}}}},
{name: "string", input: &test.RepPrimitives{FieldB: []string{"123"}}},
{name: "int32", input: &test.RepPrimitives{FieldC: randIntSlice[int32](1, true)}},
{name: "int32", input: &test.RepPrimitives{FieldC: randIntSlice[int32](2, true)}},
{name: "int32", input: &test.RepPrimitives{FieldC: randIntSlice[int32](2, false)}},
{name: "uint32", input: &test.RepPrimitives{FieldD: randIntSlice[uint32](1, true)}},
{name: "uint32", input: &test.RepPrimitives{FieldD: randIntSlice[uint32](2, true)}},
{name: "uint32", input: &test.RepPrimitives{FieldD: randIntSlice[uint32](2, false)}},
{name: "int64", input: &test.RepPrimitives{FieldE: randIntSlice[int64](1, true)}},
{name: "int64", input: &test.RepPrimitives{FieldE: randIntSlice[int64](2, true)}},
{name: "int64", input: &test.RepPrimitives{FieldE: randIntSlice[int64](2, false)}},
{name: "uint64", input: &test.RepPrimitives{FieldF: randIntSlice[uint64](1, true)}},
{name: "uint64", input: &test.RepPrimitives{FieldF: randIntSlice[uint64](2, true)}},
{name: "uint64", input: &test.RepPrimitives{FieldF: randIntSlice[uint64](2, false)}},
{name: "uint64", input: &test.RepPrimitives{FieldFu: randIntSlice[uint64](1, true)}},
{name: "uint64", input: &test.RepPrimitives{FieldFu: randIntSlice[uint64](2, true)}},
{name: "uint64", input: &test.RepPrimitives{FieldFu: randIntSlice[uint64](2, false)}},
{name: "bytes", input: &generated.RepPrimitives{FieldA: [][]byte{{1, 2, 3}}}},
{name: "string", input: &generated.RepPrimitives{FieldB: []string{"123"}}},
{name: "int32", input: &generated.RepPrimitives{FieldC: randIntSlice[int32](1, true)}},
{name: "int32", input: &generated.RepPrimitives{FieldC: randIntSlice[int32](2, true)}},
{name: "int32", input: &generated.RepPrimitives{FieldC: randIntSlice[int32](2, false)}},
{name: "uint32", input: &generated.RepPrimitives{FieldD: randIntSlice[uint32](1, true)}},
{name: "uint32", input: &generated.RepPrimitives{FieldD: randIntSlice[uint32](2, true)}},
{name: "uint32", input: &generated.RepPrimitives{FieldD: randIntSlice[uint32](2, false)}},
{name: "int64", input: &generated.RepPrimitives{FieldE: randIntSlice[int64](1, true)}},
{name: "int64", input: &generated.RepPrimitives{FieldE: randIntSlice[int64](2, true)}},
{name: "int64", input: &generated.RepPrimitives{FieldE: randIntSlice[int64](2, false)}},
{name: "uint64", input: &generated.RepPrimitives{FieldF: randIntSlice[uint64](1, true)}},
{name: "uint64", input: &generated.RepPrimitives{FieldF: randIntSlice[uint64](2, true)}},
{name: "uint64", input: &generated.RepPrimitives{FieldF: randIntSlice[uint64](2, false)}},
{name: "uint64", input: &generated.RepPrimitives{FieldFu: randIntSlice[uint64](1, true)}},
{name: "uint64", input: &generated.RepPrimitives{FieldFu: randIntSlice[uint64](2, true)}},
{name: "uint64", input: &generated.RepPrimitives{FieldFu: randIntSlice[uint64](2, false)}},
}
for _, tc := range marshalCases {
t.Run(tc.name, func(t *testing.T) {
r := tc.input.StableMarshal(nil)
r := tc.input.MarshalProtobuf(nil)
require.Equal(t, len(r), tc.input.StableSize())
require.NotEmpty(t, r)