...

Source file src/github.com/emissary-ingress/emissary/v3/pkg/api/getambassador.io/v2/common_test.go

Documentation: github.com/emissary-ingress/emissary/v3/pkg/api/getambassador.io/v2

     1  package v2_test
     2  
     3  import (
     4  	"encoding/json"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  	"sigs.k8s.io/yaml"
    10  
    11  	crds "github.com/emissary-ingress/emissary/v3/pkg/api/getambassador.io/v2"
    12  )
    13  
    14  func boolPtr(b bool) *bool {
    15  	return &b
    16  }
    17  
    18  func stringPtr(s string) *string {
    19  	return &s
    20  }
    21  
    22  func TestStringOrStringList(t *testing.T) {
    23  	t.Parallel()
    24  	type TestResource struct {
    25  		Field crds.StringOrStringList `json:"field,omitempty"`
    26  	}
    27  	type subtest struct {
    28  		inputYAML      string
    29  		expectedStruct TestResource
    30  		expectedJSON   string
    31  		expectedErr    string
    32  	}
    33  	subtests := map[string]subtest{
    34  		"empty":         {`{}`, TestResource{}, `{}`, ``},
    35  		"explicitEmpty": {`field:`, TestResource{}, `{}`, ``},
    36  		"explicitnull":  {`field: null`, TestResource{}, `{}`, ``},
    37  		"explicitNull":  {`field: Null`, TestResource{}, `{}`, ``},
    38  		"explicitNULL":  {`field: NULL`, TestResource{}, `{}`, ``},
    39  		"explicitTilde": {`field: ~`, TestResource{}, `{}`, ``},
    40  		"single":        {`field: "single"`, TestResource{crds.StringOrStringList{"single"}}, `{"field":["single"]}`, ``},
    41  		"singleEmpty":   {`field: ""`, TestResource{crds.StringOrStringList{""}}, `{"field":[""]}`, ``},
    42  		"listSingle":    {`field: ["single"]`, TestResource{crds.StringOrStringList{"single"}}, `{"field":["single"]}`, ``},
    43  		"listEmpty":     {`field: []`, TestResource{crds.StringOrStringList{}}, `{}`, ``},
    44  		"double":        {`field: ["first", "second"]`, TestResource{crds.StringOrStringList{"first", "second"}}, `{"field":["first","second"]}`, ``},
    45  		"number":        {`field: 12`, TestResource{}, `{}`, "error unmarshaling JSON: while decoding JSON: json: cannot unmarshal number into Go struct field TestResource.field of type []string"},
    46  	}
    47  	for name, info := range subtests {
    48  		info := info // capture loop variable
    49  		t.Run(name, func(t *testing.T) {
    50  			t.Parallel()
    51  			var parsed TestResource
    52  			err := yaml.Unmarshal([]byte(info.inputYAML), &parsed)
    53  			if info.expectedErr == `` {
    54  				assert.NoError(t, err)
    55  			} else {
    56  				assert.EqualError(t, err, info.expectedErr)
    57  			}
    58  			assert.Equal(t, info.expectedStruct, parsed)
    59  			jsonbytes, err := json.Marshal(parsed)
    60  			assert.NoError(t, err)
    61  			assert.Equal(t, info.expectedJSON, string(jsonbytes))
    62  		})
    63  	}
    64  }
    65  
    66  func TestBoolOrString(t *testing.T) {
    67  	t.Parallel()
    68  	type TestResource struct {
    69  		Field crds.BoolOrString `json:"field,omitempty"`
    70  	}
    71  	type subtest struct {
    72  		inputYAML      string
    73  		expectedStruct TestResource
    74  		expectedJSON   string
    75  		expectedErr    string
    76  	}
    77  	subtests := map[string]subtest{
    78  		"empty":         {`{}`, TestResource{}, `{"field":null}`, ``},
    79  		"explicitEmpty": {`field:`, TestResource{}, `{"field":null}`, ``},
    80  		"explicitnull":  {`field: null`, TestResource{}, `{"field":null}`, ``},
    81  		"explicitNull":  {`field: Null`, TestResource{}, `{"field":null}`, ``},
    82  		"explicitNULL":  {`field: NULL`, TestResource{}, `{"field":null}`, ``},
    83  		"explicitTilde": {`field: ~`, TestResource{}, `{"field":null}`, ``},
    84  		"true":          {`field: true`, TestResource{crds.BoolOrString{Bool: boolPtr(true)}}, `{"field":true}`, ``},
    85  		"True":          {`field: True`, TestResource{crds.BoolOrString{Bool: boolPtr(true)}}, `{"field":true}`, ``},
    86  		"TRUE":          {`field: TRUE`, TestResource{crds.BoolOrString{Bool: boolPtr(true)}}, `{"field":true}`, ``},
    87  		"false":         {`field: false`, TestResource{crds.BoolOrString{Bool: boolPtr(false)}}, `{"field":false}`, ``},
    88  		"False":         {`field: False`, TestResource{crds.BoolOrString{Bool: boolPtr(false)}}, `{"field":false}`, ``},
    89  		"FALSE":         {`field: FALSE`, TestResource{crds.BoolOrString{Bool: boolPtr(false)}}, `{"field":false}`, ``},
    90  		"strTrue":       {`field: "true"`, TestResource{crds.BoolOrString{String: stringPtr("true")}}, `{"field":"true"}`, ``}, // quoted
    91  		"strTRue":       {`field: TRue`, TestResource{crds.BoolOrString{String: stringPtr("TRue")}}, `{"field":"TRue"}`, ``},   // capitalized wrong
    92  		"strBare":       {`field: bare`, TestResource{crds.BoolOrString{String: stringPtr("bare")}}, `{"field":"bare"}`, ``},
    93  		"number":        {`field: 12`, TestResource{}, `{"field":null}`, "error unmarshaling JSON: while decoding JSON: json: cannot unmarshal number into Go struct field TestResource.field of type string"},
    94  		"invalid":       {``, TestResource{crds.BoolOrString{Bool: boolPtr(true), String: stringPtr("foo")}}, ``, "json: error calling MarshalJSON for type v2.BoolOrString: invalid BoolOrString"},
    95  	}
    96  	for name, info := range subtests {
    97  		info := info // capture loop variable
    98  		t.Run(name, func(t *testing.T) {
    99  			t.Parallel()
   100  			if info.inputYAML == `` {
   101  				jsonbytes, err := json.Marshal(info.expectedStruct)
   102  				assert.Equal(t, info.expectedJSON, string(jsonbytes))
   103  				assert.EqualError(t, err, info.expectedErr)
   104  			} else {
   105  				var parsed TestResource
   106  				err := yaml.Unmarshal([]byte(info.inputYAML), &parsed)
   107  				if info.expectedErr == `` {
   108  					assert.NoError(t, err)
   109  				} else {
   110  					assert.EqualError(t, err, info.expectedErr)
   111  				}
   112  				assert.Equal(t, info.expectedStruct, parsed)
   113  				jsonbytes, err := json.Marshal(parsed)
   114  				assert.NoError(t, err)
   115  				assert.Equal(t, info.expectedJSON, string(jsonbytes))
   116  			}
   117  		})
   118  	}
   119  }
   120  
   121  func TestBoolOrStringPtr(t *testing.T) {
   122  	t.Parallel()
   123  	type TestResource struct {
   124  		Field *crds.BoolOrString `json:"field,omitempty"`
   125  	}
   126  	type subtest struct {
   127  		inputYAML      string
   128  		expectedStruct TestResource
   129  		expectedJSON   string
   130  		expectedErr    string
   131  	}
   132  	subtests := map[string]subtest{
   133  		"empty":         {`{}`, TestResource{}, `{}`, ``},
   134  		"explicitEmpty": {`field:`, TestResource{}, `{}`, ``},
   135  		"explicitnull":  {`field: null`, TestResource{}, `{}`, ``},
   136  		"explicitNull":  {`field: Null`, TestResource{}, `{}`, ``},
   137  		"explicitNULL":  {`field: NULL`, TestResource{}, `{}`, ``},
   138  		"explicitTilde": {`field: ~`, TestResource{}, `{}`, ``},
   139  		"true":          {`field: true`, TestResource{&crds.BoolOrString{Bool: boolPtr(true)}}, `{"field":true}`, ``},
   140  		"True":          {`field: True`, TestResource{&crds.BoolOrString{Bool: boolPtr(true)}}, `{"field":true}`, ``},
   141  		"TRUE":          {`field: TRUE`, TestResource{&crds.BoolOrString{Bool: boolPtr(true)}}, `{"field":true}`, ``},
   142  		"false":         {`field: false`, TestResource{&crds.BoolOrString{Bool: boolPtr(false)}}, `{"field":false}`, ``},
   143  		"False":         {`field: False`, TestResource{&crds.BoolOrString{Bool: boolPtr(false)}}, `{"field":false}`, ``},
   144  		"FALSE":         {`field: FALSE`, TestResource{&crds.BoolOrString{Bool: boolPtr(false)}}, `{"field":false}`, ``},
   145  		"strTrue":       {`field: "true"`, TestResource{&crds.BoolOrString{String: stringPtr("true")}}, `{"field":"true"}`, ``}, // quoted
   146  		"strTRue":       {`field: TRue`, TestResource{&crds.BoolOrString{String: stringPtr("TRue")}}, `{"field":"TRue"}`, ``},   // capitalized wrong
   147  		"strBare":       {`field: bare`, TestResource{&crds.BoolOrString{String: stringPtr("bare")}}, `{"field":"bare"}`, ``},
   148  		"number":        {`field: 12`, TestResource{&crds.BoolOrString{}}, `{"field":null}`, "error unmarshaling JSON: while decoding JSON: json: cannot unmarshal number into Go struct field TestResource.field of type string"},
   149  	}
   150  	for name, info := range subtests {
   151  		info := info // capture loop variable
   152  		t.Run(name, func(t *testing.T) {
   153  			t.Parallel()
   154  			var parsed TestResource
   155  			err := yaml.Unmarshal([]byte(info.inputYAML), &parsed)
   156  			if info.expectedErr == `` {
   157  				assert.NoError(t, err)
   158  			} else {
   159  				assert.EqualError(t, err, info.expectedErr)
   160  			}
   161  			assert.Equal(t, info.expectedStruct, parsed)
   162  			jsonbytes, err := json.Marshal(parsed)
   163  			assert.NoError(t, err)
   164  			assert.Equal(t, info.expectedJSON, string(jsonbytes))
   165  		})
   166  	}
   167  }
   168  
   169  func TestMillisecondDuration(t *testing.T) {
   170  	t.Parallel()
   171  	type TestResource struct {
   172  		Field crds.MillisecondDuration `json:"field,omitempty"`
   173  	}
   174  	type subtest struct {
   175  		inputYAML      string
   176  		expectedStruct TestResource
   177  		expectedJSON   string
   178  		expectedErr    string
   179  	}
   180  	subtests := map[string]subtest{
   181  		"empty":         {`{}`, TestResource{}, `{"field":0}`, ``},
   182  		"explicitEmpty": {`field:`, TestResource{}, `{"field":0}`, ``},
   183  		"explicitnull":  {`field: null`, TestResource{}, `{"field":0}`, ``},
   184  		"explicitNull":  {`field: Null`, TestResource{}, `{"field":0}`, ``},
   185  		"explicitNULL":  {`field: NULL`, TestResource{}, `{"field":0}`, ``},
   186  		"explicitTilde": {`field: ~`, TestResource{}, `{"field":0}`, ``},
   187  		"3000":          {`field: 3000`, TestResource{crds.MillisecondDuration{3 * time.Second}}, `{"field":3000}`, ``},
   188  		"overflow32":    {`field: 4320000000`, TestResource{crds.MillisecondDuration{50 * 24 * time.Hour}}, `{"field":4320000000}`, ``},
   189  		"string":        {`field: "30s"`, TestResource{crds.MillisecondDuration{0}}, `{"field":0}`, "error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string into Go struct field TestResource.field of type int64"},
   190  	}
   191  	for name, info := range subtests {
   192  		info := info // capture loop variable
   193  		t.Run(name, func(t *testing.T) {
   194  			t.Parallel()
   195  			var parsed TestResource
   196  			err := yaml.Unmarshal([]byte(info.inputYAML), &parsed)
   197  			if info.expectedErr == `` {
   198  				assert.NoError(t, err)
   199  			} else {
   200  				assert.EqualError(t, err, info.expectedErr)
   201  			}
   202  			assert.Equal(t, info.expectedStruct, parsed)
   203  			jsonbytes, err := json.Marshal(parsed)
   204  			assert.NoError(t, err)
   205  			assert.Equal(t, info.expectedJSON, string(jsonbytes))
   206  		})
   207  	}
   208  }
   209  
   210  func TestMillisecondDurationPtr(t *testing.T) {
   211  	t.Parallel()
   212  	type TestResource struct {
   213  		Field *crds.MillisecondDuration `json:"field,omitempty"`
   214  	}
   215  	type subtest struct {
   216  		inputYAML      string
   217  		expectedStruct TestResource
   218  		expectedJSON   string
   219  		expectedErr    string
   220  	}
   221  	subtests := map[string]subtest{
   222  		"empty":         {`{}`, TestResource{}, `{}`, ``},
   223  		"explicitEmpty": {`field:`, TestResource{}, `{}`, ``},
   224  		"explicitnull":  {`field: null`, TestResource{}, `{}`, ``},
   225  		"explicitNull":  {`field: Null`, TestResource{}, `{}`, ``},
   226  		"explicitNULL":  {`field: NULL`, TestResource{}, `{}`, ``},
   227  		"explicitTilde": {`field: ~`, TestResource{}, `{}`, ``},
   228  		"3000":          {`field: 3000`, TestResource{&crds.MillisecondDuration{3 * time.Second}}, `{"field":3000}`, ``},
   229  		"overflow32":    {`field: 4320000000`, TestResource{&crds.MillisecondDuration{50 * 24 * time.Hour}}, `{"field":4320000000}`, ``},
   230  		"string":        {`field: "30s"`, TestResource{&crds.MillisecondDuration{0}}, `{"field":0}`, "error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string into Go struct field TestResource.field of type int64"},
   231  	}
   232  	for name, info := range subtests {
   233  		info := info // capture loop variable
   234  		t.Run(name, func(t *testing.T) {
   235  			t.Parallel()
   236  			var parsed TestResource
   237  			err := yaml.Unmarshal([]byte(info.inputYAML), &parsed)
   238  			if info.expectedErr == `` {
   239  				assert.NoError(t, err)
   240  			} else {
   241  				assert.EqualError(t, err, info.expectedErr)
   242  			}
   243  			assert.Equal(t, info.expectedStruct, parsed)
   244  			jsonbytes, err := json.Marshal(parsed)
   245  			assert.NoError(t, err)
   246  			assert.Equal(t, info.expectedJSON, string(jsonbytes))
   247  		})
   248  	}
   249  }
   250  
   251  func TestUntypedDict(t *testing.T) {
   252  	t.Parallel()
   253  	type TestResource struct {
   254  		Field crds.UntypedDict `json:"field,omitempty"`
   255  	}
   256  	type subtest struct {
   257  		inputYAML      string
   258  		expectedStruct TestResource
   259  		expectedJSON   string
   260  		expectedErr    string
   261  	}
   262  	subtests := map[string]subtest{
   263  		"empty":         {`{}`, TestResource{}, `{"field":null}`, ``},
   264  		"explicitEmpty": {`field:`, TestResource{}, `{"field":null}`, ``},
   265  		"explicitnull":  {`field: null`, TestResource{}, `{"field":null}`, ``},
   266  		"explicitNull":  {`field: Null`, TestResource{}, `{"field":null}`, ``},
   267  		"explicitNULL":  {`field: NULL`, TestResource{}, `{"field":null}`, ``},
   268  		"explicitTilde": {`field: ~`, TestResource{}, `{"field":null}`, ``},
   269  		"basic":         {`field: {foo: "bar"}`, TestResource{crds.UntypedDict{map[string]json.RawMessage{"foo": json.RawMessage(`"bar"`)}}}, `{"field":{"foo":"bar"}}`, ``},
   270  		"string":        {`field: "str"`, TestResource{}, `{"field":null}`, "error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string into Go struct field TestResource.field of type map[string]json.RawMessage"},
   271  		"badkey": {`
   272  badkey: &anchor
   273    baz: qux
   274  field: { *anchor: "bar"}`, TestResource{}, `{"field":null}`, "error converting YAML to JSON: yaml: invalid map key: map[interface {}]interface {}{\"baz\":\"qux\"}"},
   275  	}
   276  	for name, info := range subtests {
   277  		info := info // capture loop variable
   278  		t.Run(name, func(t *testing.T) {
   279  			t.Parallel()
   280  			var parsed TestResource
   281  			err := yaml.Unmarshal([]byte(info.inputYAML), &parsed)
   282  			if info.expectedErr == `` {
   283  				assert.NoError(t, err)
   284  			} else {
   285  				assert.EqualError(t, err, info.expectedErr)
   286  			}
   287  			assert.Equal(t, info.expectedStruct, parsed)
   288  			jsonbytes, err := json.Marshal(parsed)
   289  			assert.NoError(t, err)
   290  			assert.Equal(t, info.expectedJSON, string(jsonbytes))
   291  		})
   292  	}
   293  }
   294  
   295  func TestUntypedDictPtr(t *testing.T) {
   296  	t.Parallel()
   297  	type TestResource struct {
   298  		Field *crds.UntypedDict `json:"field,omitempty"`
   299  	}
   300  	type subtest struct {
   301  		inputYAML      string
   302  		expectedStruct TestResource
   303  		expectedJSON   string
   304  		expectedErr    string
   305  	}
   306  	subtests := map[string]subtest{
   307  		"empty":         {`{}`, TestResource{}, `{}`, ``},
   308  		"explicitEmpty": {`field:`, TestResource{}, `{}`, ``},
   309  		"explicitnull":  {`field: null`, TestResource{}, `{}`, ``},
   310  		"explicitNull":  {`field: Null`, TestResource{}, `{}`, ``},
   311  		"explicitNULL":  {`field: NULL`, TestResource{}, `{}`, ``},
   312  		"explicitTilde": {`field: ~`, TestResource{}, `{}`, ``},
   313  		"basic":         {`field: {foo: "bar"}`, TestResource{&crds.UntypedDict{map[string]json.RawMessage{"foo": json.RawMessage(`"bar"`)}}}, `{"field":{"foo":"bar"}}`, ``},
   314  		"string":        {`field: "str"`, TestResource{&crds.UntypedDict{}}, `{"field":null}`, "error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string into Go struct field TestResource.field of type map[string]json.RawMessage"},
   315  		"badkey": {`
   316  badkey: &anchor
   317    baz: qux
   318  field: { *anchor: "bar"}`, TestResource{}, `{}`, "error converting YAML to JSON: yaml: invalid map key: map[interface {}]interface {}{\"baz\":\"qux\"}"},
   319  	}
   320  	for name, info := range subtests {
   321  		info := info // capture loop variable
   322  		t.Run(name, func(t *testing.T) {
   323  			t.Parallel()
   324  			var parsed TestResource
   325  			err := yaml.Unmarshal([]byte(info.inputYAML), &parsed)
   326  			if info.expectedErr == `` {
   327  				assert.NoError(t, err)
   328  			} else {
   329  				assert.EqualError(t, err, info.expectedErr)
   330  			}
   331  			assert.Equal(t, info.expectedStruct, parsed)
   332  			jsonbytes, err := json.Marshal(parsed)
   333  			assert.NoError(t, err)
   334  			assert.Equal(t, info.expectedJSON, string(jsonbytes))
   335  		})
   336  	}
   337  }
   338  

View as plain text