1 package integration_test
2
3 import (
4 "bytes"
5 "fmt"
6 "testing"
7
8 "github.com/golang/protobuf/descriptor"
9 "github.com/grpc-ecosystem/grpc-gateway/examples/internal/proto/examplepb"
10 "github.com/grpc-ecosystem/grpc-gateway/runtime"
11 "google.golang.org/genproto/protobuf/field_mask"
12 )
13
14 func fieldMasksEqual(fm1, fm2 *field_mask.FieldMask) bool {
15 if fm1 == nil && fm2 == nil {
16 return true
17 }
18 if fm1 == nil || fm2 == nil {
19 return false
20 }
21 if len(fm1.GetPaths()) != len(fm2.GetPaths()) {
22 return false
23 }
24
25 paths := make(map[string]bool)
26 for _, path := range fm1.GetPaths() {
27 paths[path] = true
28 }
29 for _, path := range fm2.GetPaths() {
30 if _, ok := paths[path]; !ok {
31 return false
32 }
33 }
34
35 return true
36 }
37
38 func newFieldMask(paths ...string) *field_mask.FieldMask {
39 return &field_mask.FieldMask{Paths: paths}
40 }
41
42 func fieldMaskString(fm *field_mask.FieldMask) string {
43 if fm == nil {
44 return ""
45 }
46 return fmt.Sprintf("%v", fm.GetPaths())
47 }
48
49
50
51
52 func TestFieldMaskFromRequestBodyWithDescriptor(t *testing.T) {
53 if testing.Short() {
54 t.Skip()
55 return
56 }
57
58 _, md := descriptor.ForMessage(new(examplepb.NonStandardMessage))
59 jsonInput := `{"id":"foo", "thing":{"subThing":{"sub_value":"bar"}}}`
60 expected := newFieldMask("id", "thing.subThing.sub_value")
61
62 actual, err := runtime.FieldMaskFromRequestBody(bytes.NewReader([]byte(jsonInput)), md)
63 if !fieldMasksEqual(actual, expected) {
64 t.Errorf("want %v; got %v", fieldMaskString(expected), fieldMaskString(actual))
65 }
66 if err != nil {
67 t.Errorf("err %v", err)
68 }
69 }
70
71 func TestFieldMaskFromRequestBodyWithJsonNames(t *testing.T) {
72 if testing.Short() {
73 t.Skip()
74 return
75 }
76
77 _, md := descriptor.ForMessage(new(examplepb.NonStandardMessageWithJSONNames))
78 jsonInput := `{"ID":"foo", "Thingy":{"SubThing":{"sub_Value":"bar"}}}`
79 expected := newFieldMask("id", "thing.subThing.sub_value")
80
81 actual, err := runtime.FieldMaskFromRequestBody(bytes.NewReader([]byte(jsonInput)), md)
82 if !fieldMasksEqual(actual, expected) {
83 t.Errorf("want %v; got %v", fieldMaskString(expected), fieldMaskString(actual))
84 }
85 if err != nil {
86 t.Errorf("err %v", err)
87 }
88 }
89
90
91 var result *field_mask.FieldMask
92
93 func BenchmarkABEFieldMaskFromRequestBodyWithDescriptor(b *testing.B) {
94 if testing.Short() {
95 b.Skip()
96 return
97 }
98
99 _, md := descriptor.ForMessage(new(examplepb.ABitOfEverything))
100 input := `{` +
101 `"single_nested": {"name": "bar",` +
102 ` "amount": 10,` +
103 ` "ok": "TRUE"},` +
104 `"uuid": "6EC2446F-7E89-4127-B3E6-5C05E6BECBA7",` +
105 `"nested": [{"name": "bar",` +
106 ` "amount": 10},` +
107 ` {"name": "baz",` +
108 ` "amount": 20}],` +
109 `"float_value": 1.5,` +
110 `"double_value": 2.5,` +
111 `"int64_value": 4294967296,` +
112 `"uint64_value": 9223372036854775807,` +
113 `"int32_value": -2147483648,` +
114 `"fixed64_value": 9223372036854775807,` +
115 `"fixed32_value": 4294967295,` +
116 `"bool_value": true,` +
117 `"string_value": "strprefix/foo",` +
118 `"bytes_value": "132456",` +
119 `"uint32_value": 4294967295,` +
120 `"enum_value": "ONE",` +
121 `"path_enum_value": "DEF",` +
122 `"nested_path_enum_value": "JKL",` +
123 `"sfixed32_value": 2147483647,` +
124 `"sfixed64_value": -4611686018427387904,` +
125 `"sint32_value": 2147483647,` +
126 `"sint64_value": 4611686018427387903,` +
127 `"repeated_string_value": ["a", "b", "c"],` +
128 `"oneof_value": {"oneof_string":"x"},` +
129 `"map_value": {"a": "ONE",` +
130 ` "b": "ZERO"},` +
131 `"mapped_string_value": {"a": "x",` +
132 ` "b": "y"},` +
133 `"mapped_nested_value": {"a": {"name": "x", "amount": 1},` +
134 ` "b": {"name": "y", "amount": 2}},` +
135 `"nonConventionalNameValue": "camelCase",` +
136 `"timestamp_value": "2016-05-10T10:19:13.123Z",` +
137 `"repeated_enum_value": ["ONE", "ZERO"],` +
138 `"repeated_enum_annotation": ["ONE", "ZERO"],` +
139 `"enum_value_annotation": "ONE",` +
140 `"repeated_string_annotation": ["a", "b"],` +
141 `"repeated_nested_annotation": [{"name": "hoge",` +
142 ` "amount": 10},` +
143 ` {"name": "fuga",` +
144 ` "amount": 20}],` +
145 `"nested_annotation": {"name": "hoge",` +
146 ` "amount": 10},` +
147 `"int64_override_type": 12345` +
148 `}`
149 var r *field_mask.FieldMask
150 var err error
151 for i := 0; i < b.N; i++ {
152 r, err = runtime.FieldMaskFromRequestBody(bytes.NewReader([]byte(input)), md)
153 }
154 if err != nil {
155 b.Error(err)
156 }
157 result = r
158 }
159
160 func BenchmarkNonStandardFieldMaskFromRequestBodyWithDescriptor(b *testing.B) {
161 if testing.Short() {
162 b.Skip()
163 return
164 }
165
166 _, md := descriptor.ForMessage(new(examplepb.NonStandardMessage))
167 input := `{` +
168 `"id": "foo",` +
169 `"Num": 2,` +
170 `"line_num": 3,` +
171 `"langIdent": "bar",` +
172 `"STATUS": "baz"` +
173 `}`
174 var r *field_mask.FieldMask
175 var err error
176 for i := 0; i < b.N; i++ {
177 r, err = runtime.FieldMaskFromRequestBody(bytes.NewReader([]byte(input)), md)
178 }
179 if err != nil {
180 b.Error(err)
181 }
182 result = r
183 }
184
View as plain text