github.com/projectcalico/api@v0.0.0-20231218190037-9183ab93f33e/pkg/lib/numorstring/numorstring_test.go (about)

     1  // Copyright (c) 2016-2017 Tigera, Inc. All rights reserved.
     2  
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package numorstring_test
    16  
    17  import (
    18  	"encoding/json"
    19  	"fmt"
    20  	"reflect"
    21  
    22  	. "github.com/onsi/ginkgo/extensions/table"
    23  	. "github.com/onsi/gomega"
    24  
    25  	"github.com/projectcalico/api/pkg/lib/numorstring"
    26  )
    27  
    28  func init() {
    29  
    30  	asNumberType := reflect.TypeOf(numorstring.ASNumber(0))
    31  	protocolType := reflect.TypeOf(numorstring.Protocol{})
    32  	portType := reflect.TypeOf(numorstring.Port{})
    33  
    34  	// Perform tests of JSON unmarshaling of the various field types.
    35  	DescribeTable("NumOrStringJSONUnmarshaling",
    36  		func(jtext string, typ reflect.Type, expected interface{}) {
    37  			// Create a new field type and invoke the unmarshaller interface
    38  			// directly (this covers a couple more error cases than calling
    39  			// through json.Unmarshal.
    40  			new := reflect.New(typ)
    41  			u := new.Interface().(json.Unmarshaler)
    42  			err := u.UnmarshalJSON([]byte(jtext))
    43  
    44  			if expected != nil {
    45  				Expect(err).To(BeNil(),
    46  					"expected json unmarshal to not error")
    47  				Expect(new.Elem().Interface()).To(Equal(expected),
    48  					"expected value not same as json unmarshalled value")
    49  			} else {
    50  				Expect(err).ToNot(BeNil(),
    51  					"expected json unmarshal to error")
    52  			}
    53  		},
    54  		// ASNumber tests.
    55  		Entry("should accept 0 AS number as int", "0", asNumberType, numorstring.ASNumber(0)),
    56  		Entry("should accept 4294967295 AS number as int", "4294967295", asNumberType, numorstring.ASNumber(4294967295)),
    57  		Entry("should accept 0 AS number as string", "\"0\"", asNumberType, numorstring.ASNumber(0)),
    58  		Entry("should accept 4294967295 AS number as string", "\"4294967295\"", asNumberType, numorstring.ASNumber(4294967295)),
    59  		Entry("should accept 1.10 AS number as string", "\"1.10\"", asNumberType, numorstring.ASNumber(65546)),
    60  		Entry("should accept 00.00 AS number as string", "\"00.00\"", asNumberType, numorstring.ASNumber(0)),
    61  		Entry("should accept 00.01 AS number as string", "\"00.01\"", asNumberType, numorstring.ASNumber(1)),
    62  		Entry("should accept 65535.65535 AS number as string", "\"65535.65535\"", asNumberType, numorstring.ASNumber(4294967295)),
    63  		Entry("should reject 1.1.1 AS number as string", "\"1.1.1\"", asNumberType, nil),
    64  		Entry("should reject 65536.65535 AS number as string", "\"65536.65535\"", asNumberType, nil),
    65  		Entry("should reject 65535.65536 AS number as string", "\"65535.65536\"", asNumberType, nil),
    66  		Entry("should reject 0.-1 AS number as string", "\"0.-1\"", asNumberType, nil),
    67  		Entry("should reject -1 AS number as int", "-1", asNumberType, nil),
    68  		Entry("should reject 4294967296 AS number as int", "4294967296", asNumberType, nil),
    69  
    70  		// Port tests.
    71  		Entry("should accept 0 port as int", "0", portType, numorstring.SinglePort(0)),
    72  		Entry("should accept 65535 port as int", "65535", portType, numorstring.SinglePort(65535)),
    73  		Entry("should accept 0:65535 port range as string", "\"0:65535\"", portType, portFromRange(0, 65535)),
    74  		Entry("should accept 1:10 port range as string", "\"1:10\"", portType, portFromRange(1, 10)),
    75  		Entry("should accept foo-bar as named port", "\"foo-bar\"", portType, numorstring.NamedPort("foo-bar")),
    76  		Entry("should reject -1 port as int", "-1", portType, nil),
    77  		Entry("should reject 65536 port as int", "65536", portType, nil),
    78  		Entry("should reject 0:65536 port range as string", "\"0:65536\"", portType, nil),
    79  		Entry("should reject -1:65535 port range as string", "\"-1:65535\"", portType, nil),
    80  		Entry("should reject 10:1 port range as string", "\"10:1\"", portType, nil),
    81  		Entry("should reject 1:2:3 port range as string", "\"1:2:3\"", portType, nil),
    82  		Entry("should reject bad named port string", "\"*\"", portType, nil),
    83  		Entry("should reject bad port string", "\"1:2", portType, nil),
    84  
    85  		// Protocol tests.  Invalid integer values will be stored as strings.
    86  		Entry("should accept 0 protocol as int", "0", protocolType, numorstring.ProtocolFromInt(0)),
    87  		Entry("should accept 255 protocol as int", "255", protocolType, numorstring.ProtocolFromInt(255)),
    88  		Entry("should accept tcp protocol as string", "\"TCP\"", protocolType, numorstring.ProtocolFromString("TCP")),
    89  		Entry("should accept tcp protocol as string", "\"TCP\"", protocolType, numorstring.ProtocolFromString("TCP")),
    90  		Entry("should accept 0 protocol as string", "\"0\"", protocolType, numorstring.ProtocolFromInt(0)),
    91  		Entry("should accept 0 protocol as string", "\"255\"", protocolType, numorstring.ProtocolFromInt(255)),
    92  		Entry("should accept 256 protocol as string", "\"256\"", protocolType, numorstring.ProtocolFromString("256")),
    93  		Entry("should reject bad protocol string", "\"25", protocolType, nil),
    94  	)
    95  
    96  	// Perform tests of JSON marshaling of the various field types.
    97  	DescribeTable("NumOrStringJSONMarshaling",
    98  		func(field interface{}, jtext string) {
    99  			b, err := json.Marshal(field)
   100  			if jtext != "" {
   101  				Expect(err).To(BeNil(),
   102  					"expected json marshal to not error")
   103  				Expect(string(b)).To(Equal(jtext),
   104  					"expected json not same as marshalled value")
   105  			} else {
   106  				Expect(err).ToNot(BeNil(),
   107  					"expected json marshal to error")
   108  			}
   109  		},
   110  		// ASNumber tests.
   111  		Entry("should marshal ASN of 0", numorstring.ASNumber(0), "0"),
   112  		Entry("should marshal ASN of 4294967295", numorstring.ASNumber(4294967295), "4294967295"),
   113  
   114  		// Port tests.
   115  		Entry("should marshal port of 0", numorstring.SinglePort(0), "0"),
   116  		Entry("should marshal port of 65535", portFromRange(65535, 65535), "65535"),
   117  		Entry("should marshal port of 10", portFromString("10"), "10"),
   118  		Entry("should marshal port range of 10:20", portFromRange(10, 20), "\"10:20\""),
   119  		Entry("should marshal port range of 20:30", portFromRange(20, 30), "\"20:30\""),
   120  		Entry("should marshal named port", numorstring.NamedPort("foobar"), `"foobar"`),
   121  
   122  		// Protocol tests.
   123  		Entry("should marshal protocol of 0", numorstring.ProtocolFromInt(0), "0"),
   124  		Entry("should marshal protocol of udp", numorstring.ProtocolFromString("UDP"), "\"UDP\""),
   125  	)
   126  
   127  	// Perform tests of Stringer interface various field types.
   128  	DescribeTable("NumOrStringStringify",
   129  		func(field interface{}, s string) {
   130  			a := fmt.Sprint(field)
   131  			Expect(a).To(Equal(s),
   132  				"expected String() value to match")
   133  		},
   134  		// ASNumber tests.
   135  		Entry("should stringify ASN of 0", numorstring.ASNumber(0), "0"),
   136  		Entry("should stringify ASN of 4294967295", numorstring.ASNumber(4294967295), "4294967295"),
   137  
   138  		// Port tests.
   139  		Entry("should stringify port of 20", numorstring.SinglePort(20), "20"),
   140  		Entry("should stringify port range of 10:20", portFromRange(10, 20), "10:20"),
   141  
   142  		// Protocol tests.
   143  		Entry("should stringify protocol of 0", numorstring.ProtocolFromInt(0), "0"),
   144  		Entry("should stringify protocol of udp", numorstring.ProtocolFromString("UDP"), "UDP"),
   145  	)
   146  
   147  	// Perform tests of Protocols supporting ports.
   148  	DescribeTable("NumOrStringProtocolsSupportingPorts",
   149  		func(protocol numorstring.Protocol, supportsPorts bool) {
   150  			Expect(protocol.SupportsPorts()).To(Equal(supportsPorts),
   151  				"expected protocol port support to match")
   152  		},
   153  		Entry("protocol 6 supports ports", numorstring.ProtocolFromInt(6), true),
   154  		Entry("protocol 17 supports ports", numorstring.ProtocolFromInt(17), true),
   155  		Entry("protocol udp supports ports", numorstring.ProtocolFromString("UDP"), true),
   156  		Entry("protocol udp supports ports", numorstring.ProtocolFromString("TCP"), true),
   157  		Entry("protocol foo does not support ports", numorstring.ProtocolFromString("foo"), false),
   158  		Entry("protocol 2 does not support ports", numorstring.ProtocolFromInt(2), false),
   159  	)
   160  
   161  	// Perform tests of Protocols FromString method.
   162  	DescribeTable("NumOrStringProtocols FromString is not case-sensitive",
   163  		func(input, expected string) {
   164  			Expect(numorstring.ProtocolFromString(input).StrVal).To(Equal(expected),
   165  				"expected parsed protocol to match")
   166  		},
   167  		Entry("protocol udp -> UDP", "udp", "UDP"),
   168  		Entry("protocol tcp -> TCP", "tcp", "TCP"),
   169  		Entry("protocol updlite -> UDPLite", "udplite", "UDPLite"),
   170  		Entry("unknown protocol xxxXXX", "xxxXXX", "xxxXXX"),
   171  	)
   172  
   173  	// Perform tests of Protocols FromStringV1 method.
   174  	DescribeTable("NumOrStringProtocols FromStringV1 is lowercase",
   175  		func(input, expected string) {
   176  			Expect(numorstring.ProtocolFromStringV1(input).StrVal).To(Equal(expected),
   177  				"expected parsed protocol to match")
   178  		},
   179  		Entry("protocol udp -> UDP", "UDP", "udp"),
   180  		Entry("protocol tcp -> TCP", "TCP", "tcp"),
   181  		Entry("protocol updlite -> UDPLite", "UDPLite", "udplite"),
   182  		Entry("unknown protocol xxxXXX", "xxxXXX", "xxxxxx"),
   183  	)
   184  
   185  	// Perform tests of Protocols ToV1 method.
   186  	DescribeTable("NumOrStringProtocols FromStringV1 is lowercase",
   187  		func(input, expected numorstring.Protocol) {
   188  			Expect(input.ToV1()).To(Equal(expected),
   189  				"expected parsed protocol to match")
   190  		},
   191  		// Protocol tests.
   192  		Entry("protocol udp -> UDP", numorstring.ProtocolFromInt(2), numorstring.ProtocolFromInt(2)),
   193  		Entry("protocol tcp -> TCP", numorstring.ProtocolFromString("TCP"), numorstring.ProtocolFromStringV1("TCP")),
   194  	)
   195  }
   196  
   197  func portFromRange(minPort, maxPort uint16) numorstring.Port {
   198  	p, _ := numorstring.PortFromRange(minPort, maxPort)
   199  	return p
   200  }
   201  
   202  func portFromString(s string) numorstring.Port {
   203  	p, _ := numorstring.PortFromString(s)
   204  	return p
   205  }