...

Source file src/github.com/grpc-ecosystem/grpc-gateway/examples/internal/integration/fieldmask_test.go

Documentation: github.com/grpc-ecosystem/grpc-gateway/examples/internal/integration

     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  // N.B. These tests are here rather than in the runtime package because they need
    50  // to import examplepb for the descriptor, which would result in a circular
    51  // dependency since examplepb imports runtime from the pb.gw.go files
    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  // avoid compiler optimising benchmark away
    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