...

Source file src/github.com/grpc-ecosystem/grpc-gateway/runtime/query_test.go

Documentation: github.com/grpc-ecosystem/grpc-gateway/runtime

     1  package runtime_test
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"net/url"
     7  	"reflect"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/golang/protobuf/proto"
    12  	"github.com/golang/protobuf/ptypes"
    13  	"github.com/golang/protobuf/ptypes/duration"
    14  	"github.com/golang/protobuf/ptypes/timestamp"
    15  	"github.com/golang/protobuf/ptypes/wrappers"
    16  	"github.com/grpc-ecosystem/grpc-gateway/runtime"
    17  	"github.com/grpc-ecosystem/grpc-gateway/utilities"
    18  	"google.golang.org/genproto/protobuf/field_mask"
    19  )
    20  
    21  func BenchmarkPopulateQueryParameters(b *testing.B) {
    22  	timeT := time.Date(2016, time.December, 15, 12, 23, 32, 49, time.UTC)
    23  	timeStr := timeT.Format(time.RFC3339Nano)
    24  
    25  	durationT := 13 * time.Hour
    26  	durationStr := durationT.String()
    27  
    28  	fieldmaskStr := "float_value,double_value"
    29  
    30  	msg := &proto3Message{}
    31  	values := url.Values{
    32  		"float_value":            {"1.5"},
    33  		"double_value":           {"2.5"},
    34  		"int64_value":            {"-1"},
    35  		"int32_value":            {"-2"},
    36  		"uint64_value":           {"3"},
    37  		"uint32_value":           {"4"},
    38  		"bool_value":             {"true"},
    39  		"string_value":           {"str"},
    40  		"bytes_value":            {"Ynl0ZXM="},
    41  		"repeated_value":         {"a", "b", "c"},
    42  		"enum_value":             {"1"},
    43  		"repeated_enum":          {"1", "2", "0"},
    44  		"timestamp_value":        {timeStr},
    45  		"duration_value":         {durationStr},
    46  		"fieldmask_value":        {fieldmaskStr},
    47  		"wrapper_float_value":    {"1.5"},
    48  		"wrapper_double_value":   {"2.5"},
    49  		"wrapper_int64_value":    {"-1"},
    50  		"wrapper_int32_value":    {"-2"},
    51  		"wrapper_u_int64_value":  {"3"},
    52  		"wrapper_u_int32_value":  {"4"},
    53  		"wrapper_bool_value":     {"true"},
    54  		"wrapper_string_value":   {"str"},
    55  		"wrapper_bytes_value":    {"Ynl0ZXM="},
    56  		"map_value[key]":         {"value"},
    57  		"map_value[second]":      {"bar"},
    58  		"map_value[third]":       {"zzz"},
    59  		"map_value[fourth]":      {""},
    60  		`map_value[~!@#$%^&*()]`: {"value"},
    61  		"map_value2[key]":        {"-2"},
    62  		"map_value3[-2]":         {"value"},
    63  		"map_value4[key]":        {"-1"},
    64  		"map_value5[-1]":         {"value"},
    65  		"map_value6[key]":        {"3"},
    66  		"map_value7[3]":          {"value"},
    67  		"map_value8[key]":        {"4"},
    68  		"map_value9[4]":          {"value"},
    69  		"map_value10[key]":       {"1.5"},
    70  		"map_value11[1.5]":       {"value"},
    71  		"map_value12[key]":       {"2.5"},
    72  		"map_value13[2.5]":       {"value"},
    73  		"map_value14[key]":       {"true"},
    74  		"map_value15[true]":      {"value"},
    75  	}
    76  	filter := utilities.NewDoubleArray([][]string{
    77  		{"bool_value"}, {"repeated_value"},
    78  	})
    79  
    80  	for i := 0; i < b.N; i++ {
    81  		_ = runtime.PopulateQueryParameters(msg, values, filter)
    82  	}
    83  }
    84  
    85  func TestPopulateParameters(t *testing.T) {
    86  	timeT := time.Date(2016, time.December, 15, 12, 23, 32, 49, time.UTC)
    87  	timeStr := timeT.Format(time.RFC3339Nano)
    88  	timePb, err := ptypes.TimestampProto(timeT)
    89  	if err != nil {
    90  		t.Fatalf("Couldn't setup timestamp in Protobuf format: %v", err)
    91  	}
    92  
    93  	durationT := 13 * time.Hour
    94  	durationStr := durationT.String()
    95  	durationPb := ptypes.DurationProto(durationT)
    96  
    97  	fieldmaskStr := "float_value,double_value"
    98  	fieldmaskPb := &field_mask.FieldMask{Paths: []string{"float_value", "double_value"}}
    99  
   100  	for _, spec := range []struct {
   101  		values  url.Values
   102  		filter  *utilities.DoubleArray
   103  		want    proto.Message
   104  		wanterr error
   105  	}{
   106  		{
   107  			values: url.Values{
   108  				"float_value":            {"1.5"},
   109  				"double_value":           {"2.5"},
   110  				"int64_value":            {"-1"},
   111  				"int32_value":            {"-2"},
   112  				"uint64_value":           {"3"},
   113  				"uint32_value":           {"4"},
   114  				"bool_value":             {"true"},
   115  				"string_value":           {"str"},
   116  				"bytes_value":            {"Ynl0ZXM="},
   117  				"repeated_value":         {"a", "b", "c"},
   118  				"enum_value":             {"1"},
   119  				"repeated_enum":          {"1", "2", "0"},
   120  				"timestamp_value":        {timeStr},
   121  				"duration_value":         {durationStr},
   122  				"fieldmask_value":        {fieldmaskStr},
   123  				"wrapper_float_value":    {"1.5"},
   124  				"wrapper_double_value":   {"2.5"},
   125  				"wrapper_int64_value":    {"-1"},
   126  				"wrapper_int32_value":    {"-2"},
   127  				"wrapper_u_int64_value":  {"3"},
   128  				"wrapper_u_int32_value":  {"4"},
   129  				"wrapper_bool_value":     {"true"},
   130  				"wrapper_string_value":   {"str"},
   131  				"wrapper_bytes_value":    {"Ynl0ZXM="},
   132  				"map_value[key]":         {"value"},
   133  				"map_value[second]":      {"bar"},
   134  				"map_value[third]":       {"zzz"},
   135  				"map_value[fourth]":      {""},
   136  				`map_value[~!@#$%^&*()]`: {"value"},
   137  				"map_value2[key]":        {"-2"},
   138  				"map_value3[-2]":         {"value"},
   139  				"map_value4[key]":        {"-1"},
   140  				"map_value5[-1]":         {"value"},
   141  				"map_value6[key]":        {"3"},
   142  				"map_value7[3]":          {"value"},
   143  				"map_value8[key]":        {"4"},
   144  				"map_value9[4]":          {"value"},
   145  				"map_value10[key]":       {"1.5"},
   146  				"map_value11[1.5]":       {"value"},
   147  				"map_value12[key]":       {"2.5"},
   148  				"map_value13[2.5]":       {"value"},
   149  				"map_value14[key]":       {"true"},
   150  				"map_value15[true]":      {"value"},
   151  			},
   152  			filter: utilities.NewDoubleArray(nil),
   153  			want: &proto3Message{
   154  				FloatValue:         1.5,
   155  				DoubleValue:        2.5,
   156  				Int64Value:         -1,
   157  				Int32Value:         -2,
   158  				Uint64Value:        3,
   159  				Uint32Value:        4,
   160  				BoolValue:          true,
   161  				StringValue:        "str",
   162  				BytesValue:         []byte("bytes"),
   163  				RepeatedValue:      []string{"a", "b", "c"},
   164  				EnumValue:          EnumValue_Y,
   165  				RepeatedEnum:       []EnumValue{EnumValue_Y, EnumValue_Z, EnumValue_X},
   166  				TimestampValue:     timePb,
   167  				DurationValue:      durationPb,
   168  				FieldMaskValue:     fieldmaskPb,
   169  				WrapperFloatValue:  &wrappers.FloatValue{Value: 1.5},
   170  				WrapperDoubleValue: &wrappers.DoubleValue{Value: 2.5},
   171  				WrapperInt64Value:  &wrappers.Int64Value{Value: -1},
   172  				WrapperInt32Value:  &wrappers.Int32Value{Value: -2},
   173  				WrapperUInt64Value: &wrappers.UInt64Value{Value: 3},
   174  				WrapperUInt32Value: &wrappers.UInt32Value{Value: 4},
   175  				WrapperBoolValue:   &wrappers.BoolValue{Value: true},
   176  				WrapperStringValue: &wrappers.StringValue{Value: "str"},
   177  				WrapperBytesValue:  &wrappers.BytesValue{Value: []byte("bytes")},
   178  				MapValue: map[string]string{
   179  					"key":         "value",
   180  					"second":      "bar",
   181  					"third":       "zzz",
   182  					"fourth":      "",
   183  					`~!@#$%^&*()`: "value",
   184  				},
   185  				MapValue2:  map[string]int32{"key": -2},
   186  				MapValue3:  map[int32]string{-2: "value"},
   187  				MapValue4:  map[string]int64{"key": -1},
   188  				MapValue5:  map[int64]string{-1: "value"},
   189  				MapValue6:  map[string]uint32{"key": 3},
   190  				MapValue7:  map[uint32]string{3: "value"},
   191  				MapValue8:  map[string]uint64{"key": 4},
   192  				MapValue9:  map[uint64]string{4: "value"},
   193  				MapValue10: map[string]float32{"key": 1.5},
   194  				MapValue11: map[float32]string{1.5: "value"},
   195  				MapValue12: map[string]float64{"key": 2.5},
   196  				MapValue13: map[float64]string{2.5: "value"},
   197  				MapValue14: map[string]bool{"key": true},
   198  				MapValue15: map[bool]string{true: "value"},
   199  			},
   200  		},
   201  		{
   202  			values: url.Values{
   203  				"floatValue":         {"1.5"},
   204  				"doubleValue":        {"2.5"},
   205  				"int64Value":         {"-1"},
   206  				"int32Value":         {"-2"},
   207  				"uint64Value":        {"3"},
   208  				"uint32Value":        {"4"},
   209  				"boolValue":          {"true"},
   210  				"stringValue":        {"str"},
   211  				"bytesValue":         {"Ynl0ZXM="},
   212  				"repeatedValue":      {"a", "b", "c"},
   213  				"enumValue":          {"1"},
   214  				"repeatedEnum":       {"1", "2", "0"},
   215  				"timestampValue":     {timeStr},
   216  				"durationValue":      {durationStr},
   217  				"fieldmaskValue":     {fieldmaskStr},
   218  				"wrapperFloatValue":  {"1.5"},
   219  				"wrapperDoubleValue": {"2.5"},
   220  				"wrapperInt64Value":  {"-1"},
   221  				"wrapperInt32Value":  {"-2"},
   222  				"wrapperUInt64Value": {"3"},
   223  				"wrapperUInt32Value": {"4"},
   224  				"wrapperBoolValue":   {"true"},
   225  				"wrapperStringValue": {"str"},
   226  				"wrapperBytesValue":  {"Ynl0ZXM="},
   227  			},
   228  			filter: utilities.NewDoubleArray(nil),
   229  			want: &proto3Message{
   230  				FloatValue:         1.5,
   231  				DoubleValue:        2.5,
   232  				Int64Value:         -1,
   233  				Int32Value:         -2,
   234  				Uint64Value:        3,
   235  				Uint32Value:        4,
   236  				BoolValue:          true,
   237  				StringValue:        "str",
   238  				BytesValue:         []byte("bytes"),
   239  				RepeatedValue:      []string{"a", "b", "c"},
   240  				EnumValue:          EnumValue_Y,
   241  				RepeatedEnum:       []EnumValue{EnumValue_Y, EnumValue_Z, EnumValue_X},
   242  				TimestampValue:     timePb,
   243  				DurationValue:      durationPb,
   244  				FieldMaskValue:     fieldmaskPb,
   245  				WrapperFloatValue:  &wrappers.FloatValue{Value: 1.5},
   246  				WrapperDoubleValue: &wrappers.DoubleValue{Value: 2.5},
   247  				WrapperInt64Value:  &wrappers.Int64Value{Value: -1},
   248  				WrapperInt32Value:  &wrappers.Int32Value{Value: -2},
   249  				WrapperUInt64Value: &wrappers.UInt64Value{Value: 3},
   250  				WrapperUInt32Value: &wrappers.UInt32Value{Value: 4},
   251  				WrapperBoolValue:   &wrappers.BoolValue{Value: true},
   252  				WrapperStringValue: &wrappers.StringValue{Value: "str"},
   253  				WrapperBytesValue:  &wrappers.BytesValue{Value: []byte("bytes")},
   254  			},
   255  		},
   256  		{
   257  			values: url.Values{
   258  				"enum_value":    {"EnumValue_Z"},
   259  				"repeated_enum": {"EnumValue_X", "2", "0"},
   260  			},
   261  			filter: utilities.NewDoubleArray(nil),
   262  			want: &proto3Message{
   263  				EnumValue:    EnumValue_Z,
   264  				RepeatedEnum: []EnumValue{EnumValue_X, EnumValue_Z, EnumValue_X},
   265  			},
   266  		},
   267  		{
   268  			values: url.Values{
   269  				"float_value":    {"1.5"},
   270  				"double_value":   {"2.5"},
   271  				"int64_value":    {"-1"},
   272  				"int32_value":    {"-2"},
   273  				"uint64_value":   {"3"},
   274  				"uint32_value":   {"4"},
   275  				"bool_value":     {"true"},
   276  				"string_value":   {"str"},
   277  				"repeated_value": {"a", "b", "c"},
   278  				"enum_value":     {"1"},
   279  				"repeated_enum":  {"1", "2", "0"},
   280  			},
   281  			filter: utilities.NewDoubleArray(nil),
   282  			want: &proto2Message{
   283  				FloatValue:    proto.Float32(1.5),
   284  				DoubleValue:   proto.Float64(2.5),
   285  				Int64Value:    proto.Int64(-1),
   286  				Int32Value:    proto.Int32(-2),
   287  				Uint64Value:   proto.Uint64(3),
   288  				Uint32Value:   proto.Uint32(4),
   289  				BoolValue:     proto.Bool(true),
   290  				StringValue:   proto.String("str"),
   291  				RepeatedValue: []string{"a", "b", "c"},
   292  				EnumValue:     EnumValue_Y,
   293  				RepeatedEnum:  []EnumValue{EnumValue_Y, EnumValue_Z, EnumValue_X},
   294  			},
   295  		},
   296  		{
   297  			values: url.Values{
   298  				"floatValue":    {"1.5"},
   299  				"doubleValue":   {"2.5"},
   300  				"int64Value":    {"-1"},
   301  				"int32Value":    {"-2"},
   302  				"uint64Value":   {"3"},
   303  				"uint32Value":   {"4"},
   304  				"boolValue":     {"true"},
   305  				"stringValue":   {"str"},
   306  				"repeatedValue": {"a", "b", "c"},
   307  				"enumValue":     {"1"},
   308  				"repeatedEnum":  {"1", "2", "0"},
   309  			},
   310  			filter: utilities.NewDoubleArray(nil),
   311  			want: &proto2Message{
   312  				FloatValue:    proto.Float32(1.5),
   313  				DoubleValue:   proto.Float64(2.5),
   314  				Int64Value:    proto.Int64(-1),
   315  				Int32Value:    proto.Int32(-2),
   316  				Uint64Value:   proto.Uint64(3),
   317  				Uint32Value:   proto.Uint32(4),
   318  				BoolValue:     proto.Bool(true),
   319  				StringValue:   proto.String("str"),
   320  				RepeatedValue: []string{"a", "b", "c"},
   321  				EnumValue:     EnumValue_Y,
   322  				RepeatedEnum:  []EnumValue{EnumValue_Y, EnumValue_Z, EnumValue_X},
   323  			},
   324  		},
   325  		{
   326  			values: url.Values{
   327  				"nested.nested.nested.repeated_value": {"a", "b", "c"},
   328  				"nested.nested.nested.string_value":   {"s"},
   329  				"nested.nested.string_value":          {"t"},
   330  				"nested.string_value":                 {"u"},
   331  				"nested_non_null.string_value":        {"v"},
   332  				"nested.nested.map_value[first]":      {"foo"},
   333  				"nested.nested.map_value[second]":     {"bar"},
   334  			},
   335  			filter: utilities.NewDoubleArray(nil),
   336  			want: &proto3Message{
   337  				Nested: &proto2Message{
   338  					Nested: &proto3Message{
   339  						MapValue: map[string]string{
   340  							"first":  "foo",
   341  							"second": "bar",
   342  						},
   343  						Nested: &proto2Message{
   344  							RepeatedValue: []string{"a", "b", "c"},
   345  							StringValue:   proto.String("s"),
   346  						},
   347  						StringValue: "t",
   348  					},
   349  					StringValue: proto.String("u"),
   350  				},
   351  				NestedNonNull: proto2Message{
   352  					StringValue: proto.String("v"),
   353  				},
   354  			},
   355  		},
   356  		{
   357  			values: url.Values{
   358  				"uint64_value": {"1", "2", "3", "4", "5"},
   359  			},
   360  			filter: utilities.NewDoubleArray(nil),
   361  			want: &proto3Message{
   362  				Uint64Value: 1,
   363  			},
   364  		},
   365  		{
   366  			values: url.Values{
   367  				"oneof_string_value": {"foobar"},
   368  			},
   369  			filter: utilities.NewDoubleArray(nil),
   370  			want: &proto3Message{
   371  				OneofValue: &proto3Message_OneofStringValue{"foobar"},
   372  			},
   373  		},
   374  		{
   375  			values: url.Values{
   376  				"oneofStringValue": {"foobar"},
   377  			},
   378  			filter: utilities.NewDoubleArray(nil),
   379  			want: &proto3Message{
   380  				OneofValue: &proto3Message_OneofStringValue{"foobar"},
   381  			},
   382  		},
   383  		{
   384  			values: url.Values{
   385  				"oneof_bool_value": {"true"},
   386  			},
   387  			filter: utilities.NewDoubleArray(nil),
   388  			want: &proto3Message{
   389  				OneofValue: &proto3Message_OneofBoolValue{true},
   390  			},
   391  		},
   392  		{
   393  			// Don't allow setting a oneof more than once
   394  			values: url.Values{
   395  				"oneof_bool_value":   {"true"},
   396  				"oneof_string_value": {"foobar"},
   397  			},
   398  			filter:  utilities.NewDoubleArray(nil),
   399  			want:    &proto3Message{},
   400  			wanterr: errors.New("field already set for oneof_value oneof"),
   401  		},
   402  	} {
   403  		msg := proto.Clone(spec.want)
   404  		msg.Reset()
   405  		err := runtime.PopulateQueryParameters(msg, spec.values, spec.filter)
   406  		if spec.wanterr != nil {
   407  			if !reflect.DeepEqual(err, spec.wanterr) {
   408  				t.Errorf("runtime.PopulateQueryParameters(msg, %v, %v) failed with %v; want error %v", spec.values, spec.filter, err, spec.wanterr)
   409  			}
   410  			continue
   411  		}
   412  
   413  		if err != nil {
   414  			t.Errorf("runtime.PopulateQueryParameters(msg, %v, %v) failed with %v; want success", spec.values, spec.filter, err)
   415  			continue
   416  		}
   417  		if got, want := msg, spec.want; !proto.Equal(got, want) {
   418  			t.Errorf("runtime.PopulateQueryParameters(msg, %v, %v = %v; want %v", spec.values, spec.filter, got, want)
   419  		}
   420  	}
   421  }
   422  
   423  func TestPopulateParametersWithNativeTypes(t *testing.T) {
   424  	timeT := time.Date(2016, time.December, 15, 12, 23, 32, 49, time.UTC)
   425  	timeStr := timeT.Format(time.RFC3339Nano)
   426  
   427  	durationT := 13 * time.Hour
   428  	durationStr := durationT.String()
   429  
   430  	for _, spec := range []struct {
   431  		values url.Values
   432  		want   *nativeProto3Message
   433  	}{
   434  		{
   435  			values: url.Values{
   436  				"native_timestamp_value": {timeStr},
   437  				"native_duration_value":  {durationStr},
   438  			},
   439  			want: &nativeProto3Message{
   440  				NativeTimeValue:     &timeT,
   441  				NativeDurationValue: &durationT,
   442  			},
   443  		},
   444  		{
   445  			values: url.Values{
   446  				"nativeTimestampValue": {timeStr},
   447  				"nativeDurationValue":  {durationStr},
   448  			},
   449  			want: &nativeProto3Message{
   450  				NativeTimeValue:     &timeT,
   451  				NativeDurationValue: &durationT,
   452  			},
   453  		},
   454  	} {
   455  		msg := new(nativeProto3Message)
   456  		err := runtime.PopulateQueryParameters(msg, spec.values, utilities.NewDoubleArray(nil))
   457  
   458  		if err != nil {
   459  			t.Errorf("runtime.PopulateQueryParameters(msg, %v, utilities.NewDoubleArray(nil)) failed with %v; want success", spec.values, err)
   460  			continue
   461  		}
   462  		if got, want := msg, spec.want; !proto.Equal(got, want) {
   463  			t.Errorf("runtime.PopulateQueryParameters(msg, %v, utilities.NewDoubleArray(nil)) = %v; want %v", spec.values, got, want)
   464  		}
   465  	}
   466  }
   467  
   468  func TestPopulateParametersWithFilters(t *testing.T) {
   469  	for _, spec := range []struct {
   470  		values url.Values
   471  		filter *utilities.DoubleArray
   472  		want   proto.Message
   473  	}{
   474  		{
   475  			values: url.Values{
   476  				"bool_value":     {"true"},
   477  				"string_value":   {"str"},
   478  				"repeated_value": {"a", "b", "c"},
   479  			},
   480  			filter: utilities.NewDoubleArray([][]string{
   481  				{"bool_value"}, {"repeated_value"},
   482  			}),
   483  			want: &proto3Message{
   484  				StringValue: "str",
   485  			},
   486  		},
   487  		{
   488  			values: url.Values{
   489  				"nested.nested.bool_value":   {"true"},
   490  				"nested.nested.string_value": {"str"},
   491  				"nested.string_value":        {"str"},
   492  				"string_value":               {"str"},
   493  			},
   494  			filter: utilities.NewDoubleArray([][]string{
   495  				{"nested"},
   496  			}),
   497  			want: &proto3Message{
   498  				StringValue: "str",
   499  			},
   500  		},
   501  		{
   502  			values: url.Values{
   503  				"nested.nested.bool_value":   {"true"},
   504  				"nested.nested.string_value": {"str"},
   505  				"nested.string_value":        {"str"},
   506  				"string_value":               {"str"},
   507  			},
   508  			filter: utilities.NewDoubleArray([][]string{
   509  				{"nested", "nested"},
   510  			}),
   511  			want: &proto3Message{
   512  				Nested: &proto2Message{
   513  					StringValue: proto.String("str"),
   514  				},
   515  				StringValue: "str",
   516  			},
   517  		},
   518  		{
   519  			values: url.Values{
   520  				"nested.nested.bool_value":   {"true"},
   521  				"nested.nested.string_value": {"str"},
   522  				"nested.string_value":        {"str"},
   523  				"string_value":               {"str"},
   524  			},
   525  			filter: utilities.NewDoubleArray([][]string{
   526  				{"nested", "nested", "string_value"},
   527  			}),
   528  			want: &proto3Message{
   529  				Nested: &proto2Message{
   530  					StringValue: proto.String("str"),
   531  					Nested: &proto3Message{
   532  						BoolValue: true,
   533  					},
   534  				},
   535  				StringValue: "str",
   536  			},
   537  		},
   538  	} {
   539  		msg := proto.Clone(spec.want)
   540  		msg.Reset()
   541  		err := runtime.PopulateQueryParameters(msg, spec.values, spec.filter)
   542  		if err != nil {
   543  			t.Errorf("runtime.PoplateQueryParameters(msg, %v, %v) failed with %v; want success", spec.values, spec.filter, err)
   544  			continue
   545  		}
   546  		if got, want := msg, spec.want; !proto.Equal(got, want) {
   547  			t.Errorf("runtime.PopulateQueryParameters(msg, %v, %v = %v; want %v", spec.values, spec.filter, got, want)
   548  		}
   549  	}
   550  }
   551  
   552  func TestPopulateQueryParametersWithInvalidNestedParameters(t *testing.T) {
   553  	for _, spec := range []struct {
   554  		msg    proto.Message
   555  		values url.Values
   556  		filter *utilities.DoubleArray
   557  	}{
   558  		{
   559  			msg: &proto3Message{},
   560  			values: url.Values{
   561  				"float_value.nested": {"test"},
   562  			},
   563  			filter: utilities.NewDoubleArray(nil),
   564  		},
   565  		{
   566  			msg: &proto3Message{},
   567  			values: url.Values{
   568  				"double_value.nested": {"test"},
   569  			},
   570  			filter: utilities.NewDoubleArray(nil),
   571  		},
   572  		{
   573  			msg: &proto3Message{},
   574  			values: url.Values{
   575  				"int64_value.nested": {"test"},
   576  			},
   577  			filter: utilities.NewDoubleArray(nil),
   578  		},
   579  		{
   580  			msg: &proto3Message{},
   581  			values: url.Values{
   582  				"int32_value.nested": {"test"},
   583  			},
   584  			filter: utilities.NewDoubleArray(nil),
   585  		},
   586  		{
   587  			msg: &proto3Message{},
   588  			values: url.Values{
   589  				"uint64_value.nested": {"test"},
   590  			},
   591  			filter: utilities.NewDoubleArray(nil),
   592  		},
   593  		{
   594  			msg: &proto3Message{},
   595  			values: url.Values{
   596  				"uint32_value.nested": {"test"},
   597  			},
   598  			filter: utilities.NewDoubleArray(nil),
   599  		},
   600  		{
   601  			msg: &proto3Message{},
   602  			values: url.Values{
   603  				"bool_value.nested": {"test"},
   604  			},
   605  			filter: utilities.NewDoubleArray(nil),
   606  		},
   607  		{
   608  			msg: &proto3Message{},
   609  			values: url.Values{
   610  				"string_value.nested": {"test"},
   611  			},
   612  			filter: utilities.NewDoubleArray(nil),
   613  		},
   614  		{
   615  			msg: &proto3Message{},
   616  			values: url.Values{
   617  				"repeated_value.nested": {"test"},
   618  			},
   619  			filter: utilities.NewDoubleArray(nil),
   620  		},
   621  		{
   622  			msg: &proto3Message{},
   623  			values: url.Values{
   624  				"enum_value.nested": {"test"},
   625  			},
   626  			filter: utilities.NewDoubleArray(nil),
   627  		},
   628  		{
   629  			msg: &proto3Message{},
   630  			values: url.Values{
   631  				"enum_value.nested": {"test"},
   632  			},
   633  			filter: utilities.NewDoubleArray(nil),
   634  		},
   635  		{
   636  			msg: &proto3Message{},
   637  			values: url.Values{
   638  				"repeated_enum.nested": {"test"},
   639  			},
   640  			filter: utilities.NewDoubleArray(nil),
   641  		},
   642  	} {
   643  		spec.msg.Reset()
   644  		err := runtime.PopulateQueryParameters(spec.msg, spec.values, spec.filter)
   645  		if err == nil {
   646  			t.Errorf("runtime.PopulateQueryParameters(msg, %v, %v) did not fail; want error", spec.values, spec.filter)
   647  		}
   648  	}
   649  }
   650  
   651  type proto3Message struct {
   652  	Nested             *proto2Message           `protobuf:"bytes,1,opt,name=nested,json=nested" json:"nested,omitempty"`
   653  	NestedNonNull      proto2Message            `protobuf:"bytes,15,opt,name=nested_non_null,json=nestedNonNull" json:"nested_non_null,omitempty"`
   654  	FloatValue         float32                  `protobuf:"fixed32,2,opt,name=float_value,json=floatValue" json:"float_value,omitempty"`
   655  	DoubleValue        float64                  `protobuf:"fixed64,3,opt,name=double_value,json=doubleValue" json:"double_value,omitempty"`
   656  	Int64Value         int64                    `protobuf:"varint,4,opt,name=int64_value,json=int64Value" json:"int64_value,omitempty"`
   657  	Int32Value         int32                    `protobuf:"varint,5,opt,name=int32_value,json=int32Value" json:"int32_value,omitempty"`
   658  	Uint64Value        uint64                   `protobuf:"varint,6,opt,name=uint64_value,json=uint64Value" json:"uint64_value,omitempty"`
   659  	Uint32Value        uint32                   `protobuf:"varint,7,opt,name=uint32_value,json=uint32Value" json:"uint32_value,omitempty"`
   660  	BoolValue          bool                     `protobuf:"varint,8,opt,name=bool_value,json=boolValue" json:"bool_value,omitempty"`
   661  	StringValue        string                   `protobuf:"bytes,9,opt,name=string_value,json=stringValue" json:"string_value,omitempty"`
   662  	BytesValue         []byte                   `protobuf:"bytes,25,opt,name=bytes_value,json=bytesValue" json:"bytes_value,omitempty"`
   663  	RepeatedValue      []string                 `protobuf:"bytes,10,rep,name=repeated_value,json=repeatedValue" json:"repeated_value,omitempty"`
   664  	EnumValue          EnumValue                `protobuf:"varint,11,opt,name=enum_value,json=enumValue,enum=runtime_test_api.EnumValue" json:"enum_value,omitempty"`
   665  	RepeatedEnum       []EnumValue              `protobuf:"varint,12,rep,packed,name=repeated_enum,json=repeatedEnum,enum=runtime_test_api.EnumValue" json:"repeated_enum,omitempty"`
   666  	TimestampValue     *timestamp.Timestamp     `protobuf:"bytes,16,opt,name=timestamp_value,json=timestampValue" json:"timestamp_value,omitempty"`
   667  	DurationValue      *duration.Duration       `protobuf:"bytes,42,opt,name=duration_value,json=durationValue" json:"duration_value,omitempty"`
   668  	FieldMaskValue     *field_mask.FieldMask    `protobuf:"bytes,27,opt,name=fieldmask_value,json=fieldmaskValue" json:"fieldmask_value,omitempty"`
   669  	OneofValue         proto3Message_OneofValue `protobuf_oneof:"oneof_value"`
   670  	WrapperDoubleValue *wrappers.DoubleValue    `protobuf:"bytes,17,opt,name=wrapper_double_value,json=wrapperDoubleValue" json:"wrapper_double_value,omitempty"`
   671  	WrapperFloatValue  *wrappers.FloatValue     `protobuf:"bytes,18,opt,name=wrapper_float_value,json=wrapperFloatValue" json:"wrapper_float_value,omitempty"`
   672  	WrapperInt64Value  *wrappers.Int64Value     `protobuf:"bytes,19,opt,name=wrapper_int64_value,json=wrapperInt64Value" json:"wrapper_int64_value,omitempty"`
   673  	WrapperInt32Value  *wrappers.Int32Value     `protobuf:"bytes,20,opt,name=wrapper_int32_value,json=wrapperInt32Value" json:"wrapper_int32_value,omitempty"`
   674  	WrapperUInt64Value *wrappers.UInt64Value    `protobuf:"bytes,21,opt,name=wrapper_u_int64_value,json=wrapperUInt64Value" json:"wrapper_u_int64_value,omitempty"`
   675  	WrapperUInt32Value *wrappers.UInt32Value    `protobuf:"bytes,22,opt,name=wrapper_u_int32_value,json=wrapperUInt32Value" json:"wrapper_u_int32_value,omitempty"`
   676  	WrapperBoolValue   *wrappers.BoolValue      `protobuf:"bytes,23,opt,name=wrapper_bool_value,json=wrapperBoolValue" json:"wrapper_bool_value,omitempty"`
   677  	WrapperStringValue *wrappers.StringValue    `protobuf:"bytes,24,opt,name=wrapper_string_value,json=wrapperStringValue" json:"wrapper_string_value,omitempty"`
   678  	WrapperBytesValue  *wrappers.BytesValue     `protobuf:"bytes,26,opt,name=wrapper_bytes_value,json=wrapperBytesValue" json:"wrapper_bytes_value,omitempty"`
   679  	MapValue           map[string]string        `protobuf:"bytes,27,opt,name=map_value,json=mapValue" json:"map_value,omitempty"`
   680  	MapValue2          map[string]int32         `protobuf:"bytes,28,opt,name=map_value2,json=mapValue2" json:"map_value2,omitempty"`
   681  	MapValue3          map[int32]string         `protobuf:"bytes,29,opt,name=map_value3,json=mapValue3" json:"map_value3,omitempty"`
   682  	MapValue4          map[string]int64         `protobuf:"bytes,30,opt,name=map_value4,json=mapValue4" json:"map_value4,omitempty"`
   683  	MapValue5          map[int64]string         `protobuf:"bytes,31,opt,name=map_value5,json=mapValue5" json:"map_value5,omitempty"`
   684  	MapValue6          map[string]uint32        `protobuf:"bytes,32,opt,name=map_value6,json=mapValue6" json:"map_value6,omitempty"`
   685  	MapValue7          map[uint32]string        `protobuf:"bytes,33,opt,name=map_value7,json=mapValue7" json:"map_value7,omitempty"`
   686  	MapValue8          map[string]uint64        `protobuf:"bytes,34,opt,name=map_value8,json=mapValue8" json:"map_value8,omitempty"`
   687  	MapValue9          map[uint64]string        `protobuf:"bytes,35,opt,name=map_value9,json=mapValue9" json:"map_value9,omitempty"`
   688  	MapValue10         map[string]float32       `protobuf:"bytes,36,opt,name=map_value10,json=mapValue10" json:"map_value10,omitempty"`
   689  	MapValue11         map[float32]string       `protobuf:"bytes,37,opt,name=map_value11,json=mapValue11" json:"map_value11,omitempty"`
   690  	MapValue12         map[string]float64       `protobuf:"bytes,38,opt,name=map_value12,json=mapValue12" json:"map_value12,omitempty"`
   691  	MapValue13         map[float64]string       `protobuf:"bytes,39,opt,name=map_value13,json=mapValue13" json:"map_value13,omitempty"`
   692  	MapValue14         map[string]bool          `protobuf:"bytes,40,opt,name=map_value14,json=mapValue14" json:"map_value14,omitempty"`
   693  	MapValue15         map[bool]string          `protobuf:"bytes,41,opt,name=map_value15,json=mapValue15" json:"map_value15,omitempty"`
   694  }
   695  
   696  func (m *proto3Message) Reset()         { *m = proto3Message{} }
   697  func (m *proto3Message) String() string { return proto.CompactTextString(m) }
   698  func (*proto3Message) ProtoMessage()    {}
   699  
   700  func (m *proto3Message) GetNested() *proto2Message {
   701  	if m != nil {
   702  		return m.Nested
   703  	}
   704  	return nil
   705  }
   706  
   707  type proto3Message_OneofValue interface {
   708  	proto3Message_OneofValue()
   709  }
   710  
   711  type proto3Message_OneofBoolValue struct {
   712  	OneofBoolValue bool `protobuf:"varint,13,opt,name=oneof_bool_value,json=oneofBoolValue,oneof"`
   713  }
   714  type proto3Message_OneofStringValue struct {
   715  	OneofStringValue string `protobuf:"bytes,14,opt,name=oneof_string_value,json=oneofStringValue,oneof"`
   716  }
   717  
   718  func (*proto3Message_OneofBoolValue) proto3Message_OneofValue()   {}
   719  func (*proto3Message_OneofStringValue) proto3Message_OneofValue() {}
   720  
   721  func (m *proto3Message) GetOneofValue() proto3Message_OneofValue {
   722  	if m != nil {
   723  		return m.OneofValue
   724  	}
   725  	return nil
   726  }
   727  
   728  func (m *proto3Message) GetOneofBoolValue() bool {
   729  	if x, ok := m.GetOneofValue().(*proto3Message_OneofBoolValue); ok {
   730  		return x.OneofBoolValue
   731  	}
   732  	return false
   733  }
   734  
   735  func (m *proto3Message) GetOneofStringValue() string {
   736  	if x, ok := m.GetOneofValue().(*proto3Message_OneofStringValue); ok {
   737  		return x.OneofStringValue
   738  	}
   739  	return ""
   740  }
   741  
   742  // XXX_OneofFuncs is for the internal use of the proto package.
   743  func (*proto3Message) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
   744  	return _proto3Message_OneofMarshaler, _proto3Message_OneofUnmarshaler, _proto3Message_OneofSizer, []interface{}{
   745  		(*proto3Message_OneofBoolValue)(nil),
   746  		(*proto3Message_OneofStringValue)(nil),
   747  	}
   748  }
   749  
   750  func _proto3Message_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
   751  	m := msg.(*proto3Message)
   752  	// oneof_value
   753  	switch x := m.OneofValue.(type) {
   754  	case *proto3Message_OneofBoolValue:
   755  		t := uint64(0)
   756  		if x.OneofBoolValue {
   757  			t = 1
   758  		}
   759  		b.EncodeVarint(13<<3 | proto.WireVarint)
   760  		b.EncodeVarint(t)
   761  	case *proto3Message_OneofStringValue:
   762  		b.EncodeVarint(14<<3 | proto.WireBytes)
   763  		b.EncodeStringBytes(x.OneofStringValue)
   764  	case nil:
   765  	default:
   766  		return fmt.Errorf("proto3Message.OneofValue has unexpected type %T", x)
   767  	}
   768  	return nil
   769  }
   770  
   771  func _proto3Message_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
   772  	m := msg.(*proto3Message)
   773  	switch tag {
   774  	case 14: // oneof_value.oneof_bool_value
   775  		if wire != proto.WireVarint {
   776  			return true, proto.ErrInternalBadWireType
   777  		}
   778  		x, err := b.DecodeVarint()
   779  		m.OneofValue = &proto3Message_OneofBoolValue{x != 0}
   780  		return true, err
   781  	case 15: // oneof_value.oneof_string_value
   782  		if wire != proto.WireBytes {
   783  			return true, proto.ErrInternalBadWireType
   784  		}
   785  		x, err := b.DecodeStringBytes()
   786  		m.OneofValue = &proto3Message_OneofStringValue{x}
   787  		return true, err
   788  	default:
   789  		return false, nil
   790  	}
   791  }
   792  
   793  func _proto3Message_OneofSizer(msg proto.Message) (n int) {
   794  	m := msg.(*proto3Message)
   795  	// oneof_value
   796  	switch x := m.OneofValue.(type) {
   797  	case *proto3Message_OneofBoolValue:
   798  		n += proto.SizeVarint(14<<3 | proto.WireVarint)
   799  		n += 1
   800  	case *proto3Message_OneofStringValue:
   801  		n += proto.SizeVarint(15<<3 | proto.WireBytes)
   802  		n += proto.SizeVarint(uint64(len(x.OneofStringValue)))
   803  		n += len(x.OneofStringValue)
   804  	case nil:
   805  	default:
   806  		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
   807  	}
   808  	return n
   809  }
   810  
   811  type nativeProto3Message struct {
   812  	NativeTimeValue     *time.Time     `protobuf:"bytes,1,opt,name=native_timestamp_value,json=nativeTimestampValue" json:"native_timestamp_value,omitempty"`
   813  	NativeDurationValue *time.Duration `protobuf:"bytes,2,opt,name=native_duration_value,json=nativeDurationValue" json:"native_duration_value,omitempty"`
   814  }
   815  
   816  func (m *nativeProto3Message) Reset()         { *m = nativeProto3Message{} }
   817  func (m *nativeProto3Message) String() string { return proto.CompactTextString(m) }
   818  func (*nativeProto3Message) ProtoMessage()    {}
   819  
   820  type proto2Message struct {
   821  	Nested           *proto3Message `protobuf:"bytes,1,opt,name=nested,json=nested" json:"nested,omitempty"`
   822  	FloatValue       *float32       `protobuf:"fixed32,2,opt,name=float_value,json=floatValue" json:"float_value,omitempty"`
   823  	DoubleValue      *float64       `protobuf:"fixed64,3,opt,name=double_value,json=doubleValue" json:"double_value,omitempty"`
   824  	Int64Value       *int64         `protobuf:"varint,4,opt,name=int64_value,json=int64Value" json:"int64_value,omitempty"`
   825  	Int32Value       *int32         `protobuf:"varint,5,opt,name=int32_value,json=int32Value" json:"int32_value,omitempty"`
   826  	Uint64Value      *uint64        `protobuf:"varint,6,opt,name=uint64_value,json=uint64Value" json:"uint64_value,omitempty"`
   827  	Uint32Value      *uint32        `protobuf:"varint,7,opt,name=uint32_value,json=uint32Value" json:"uint32_value,omitempty"`
   828  	BoolValue        *bool          `protobuf:"varint,8,opt,name=bool_value,json=boolValue" json:"bool_value,omitempty"`
   829  	StringValue      *string        `protobuf:"bytes,9,opt,name=string_value,json=stringValue" json:"string_value,omitempty"`
   830  	RepeatedValue    []string       `protobuf:"bytes,10,rep,name=repeated_value,json=repeatedValue" json:"repeated_value,omitempty"`
   831  	EnumValue        EnumValue      `protobuf:"varint,11,opt,name=enum_value,json=enumValue,enum=runtime_test_api.EnumValue" json:"enum_value,omitempty"`
   832  	RepeatedEnum     []EnumValue    `protobuf:"varint,12,rep,packed,name=repeated_enum,json=repeatedEnum,enum=runtime_test_api.EnumValue" json:"repeated_enum,omitempty"`
   833  	XXX_unrecognized []byte         `json:"-"`
   834  }
   835  
   836  func (m *proto2Message) Reset()         { *m = proto2Message{} }
   837  func (m *proto2Message) String() string { return proto.CompactTextString(m) }
   838  func (*proto2Message) ProtoMessage()    {}
   839  
   840  func (m *proto2Message) GetNested() *proto3Message {
   841  	if m != nil {
   842  		return m.Nested
   843  	}
   844  	return nil
   845  }
   846  
   847  func (m *proto2Message) GetFloatValue() float32 {
   848  	if m != nil && m.FloatValue != nil {
   849  		return *m.FloatValue
   850  	}
   851  	return 0
   852  }
   853  
   854  func (m *proto2Message) GetDoubleValue() float64 {
   855  	if m != nil && m.DoubleValue != nil {
   856  		return *m.DoubleValue
   857  	}
   858  	return 0
   859  }
   860  
   861  func (m *proto2Message) GetInt64Value() int64 {
   862  	if m != nil && m.Int64Value != nil {
   863  		return *m.Int64Value
   864  	}
   865  	return 0
   866  }
   867  
   868  func (m *proto2Message) GetInt32Value() int32 {
   869  	if m != nil && m.Int32Value != nil {
   870  		return *m.Int32Value
   871  	}
   872  	return 0
   873  }
   874  
   875  func (m *proto2Message) GetUint64Value() uint64 {
   876  	if m != nil && m.Uint64Value != nil {
   877  		return *m.Uint64Value
   878  	}
   879  	return 0
   880  }
   881  
   882  func (m *proto2Message) GetUint32Value() uint32 {
   883  	if m != nil && m.Uint32Value != nil {
   884  		return *m.Uint32Value
   885  	}
   886  	return 0
   887  }
   888  
   889  func (m *proto2Message) GetBoolValue() bool {
   890  	if m != nil && m.BoolValue != nil {
   891  		return *m.BoolValue
   892  	}
   893  	return false
   894  }
   895  
   896  func (m *proto2Message) GetStringValue() string {
   897  	if m != nil && m.StringValue != nil {
   898  		return *m.StringValue
   899  	}
   900  	return ""
   901  }
   902  
   903  func (m *proto2Message) GetRepeatedValue() []string {
   904  	if m != nil {
   905  		return m.RepeatedValue
   906  	}
   907  	return nil
   908  }
   909  
   910  type EnumValue int32
   911  
   912  const (
   913  	EnumValue_X EnumValue = 0
   914  	EnumValue_Y EnumValue = 1
   915  	EnumValue_Z EnumValue = 2
   916  )
   917  
   918  var EnumValue_name = map[int32]string{
   919  	0: "EnumValue_X",
   920  	1: "EnumValue_Y",
   921  	2: "EnumValue_Z",
   922  }
   923  var EnumValue_value = map[string]int32{
   924  	"EnumValue_X": 0,
   925  	"EnumValue_Y": 1,
   926  	"EnumValue_Z": 2,
   927  }
   928  
   929  func init() {
   930  	proto.RegisterEnum("runtime_test_api.EnumValue", EnumValue_name, EnumValue_value)
   931  }
   932  

View as plain text