github.com/baraj55/containernetworking-cni@v0.7.2-0.20200219164625-56ace59a9e7f/pkg/types/types_test.go (about)

     1  // Copyright 2017 CNI authors
     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 types_test
    16  
    17  import (
    18  	"encoding/json"
    19  	"net"
    20  
    21  	"github.com/containernetworking/cni/pkg/types"
    22  	. "github.com/onsi/ginkgo"
    23  	. "github.com/onsi/ginkgo/extensions/table"
    24  	. "github.com/onsi/gomega"
    25  )
    26  
    27  var _ = Describe("Types", func() {
    28  
    29  	Describe("ParseCIDR", func() {
    30  		DescribeTable("Parse and stringify",
    31  			func(input, expectedIP string, expectedMask int) {
    32  				ipn, err := types.ParseCIDR(input)
    33  				Expect(err).NotTo(HaveOccurred())
    34  				Expect(ipn.String()).To(Equal(input))
    35  
    36  				Expect(ipn.IP.String()).To(Equal(expectedIP))
    37  				ones, _ := ipn.Mask.Size()
    38  				Expect(ones).To(Equal(expectedMask))
    39  			},
    40  			Entry("ipv4", "1.2.3.4/24", "1.2.3.4", 24),
    41  			Entry("ipv6", "2001:db8::/32", "2001:db8::", 32),
    42  		)
    43  		It("returns an error when given invalid inputs", func() {
    44  			ipn, err := types.ParseCIDR("1.2.3/45")
    45  			Expect(ipn).To(BeNil())
    46  			Expect(err).To(MatchError("invalid CIDR address: 1.2.3/45"))
    47  		})
    48  	})
    49  
    50  	Describe("custom IPNet type", func() {
    51  		It("marshals and unmarshals to JSON as a string", func() {
    52  			ipn := types.IPNet{
    53  				IP:   net.ParseIP("1.2.3.4"),
    54  				Mask: net.CIDRMask(24, 32),
    55  			}
    56  			jsonBytes, err := json.Marshal(ipn)
    57  			Expect(err).NotTo(HaveOccurred())
    58  			Expect(jsonBytes).To(MatchJSON(`"1.2.3.4/24"`))
    59  
    60  			var unmarshaled types.IPNet
    61  			Expect(json.Unmarshal(jsonBytes, &unmarshaled)).To(Succeed())
    62  			Expect(unmarshaled).To(Equal(ipn))
    63  		})
    64  
    65  		Context("when the json data is not syntactically valid", func() {
    66  			Specify("UnmarshalJSON returns an error", func() {
    67  				ipn := new(types.IPNet)
    68  				err := ipn.UnmarshalJSON([]byte("1"))
    69  				Expect(err).To(MatchError("json: cannot unmarshal number into Go value of type string"))
    70  			})
    71  		})
    72  
    73  		Context("when the json data is not semantically valid", func() {
    74  			Specify("UnmarshalJSON returns an error", func() {
    75  				ipn := new(types.IPNet)
    76  				err := ipn.UnmarshalJSON([]byte(`"1.2.3.4/99"`))
    77  				Expect(err).To(MatchError("invalid CIDR address: 1.2.3.4/99"))
    78  			})
    79  		})
    80  	})
    81  
    82  	Describe("custom Route type", func() {
    83  		var example types.Route
    84  		BeforeEach(func() {
    85  			example = types.Route{
    86  				Dst: net.IPNet{
    87  					IP:   net.ParseIP("1.2.3.0"),
    88  					Mask: net.CIDRMask(24, 32),
    89  				},
    90  				GW: net.ParseIP("1.2.3.1"),
    91  			}
    92  		})
    93  
    94  		It("marshals and unmarshals to JSON", func() {
    95  			jsonBytes, err := json.Marshal(example)
    96  			Expect(err).NotTo(HaveOccurred())
    97  			Expect(jsonBytes).To(MatchJSON(`{ "dst": "1.2.3.0/24", "gw": "1.2.3.1" }`))
    98  
    99  			var unmarshaled types.Route
   100  			Expect(json.Unmarshal(jsonBytes, &unmarshaled)).To(Succeed())
   101  			Expect(unmarshaled).To(Equal(example))
   102  		})
   103  
   104  		Context("when the json data is not valid", func() {
   105  			Specify("UnmarshalJSON returns an error", func() {
   106  				route := new(types.Route)
   107  				err := route.UnmarshalJSON([]byte(`{ "dst": "1.2.3.0/24", "gw": "1.2.3.x" }`))
   108  				Expect(err).To(MatchError("invalid IP address: 1.2.3.x"))
   109  			})
   110  		})
   111  
   112  		It("formats as a string with a hex mask", func() {
   113  			Expect(example.String()).To(Equal(`{Dst:{IP:1.2.3.0 Mask:ffffff00} GW:1.2.3.1}`))
   114  		})
   115  	})
   116  
   117  	Describe("Error type", func() {
   118  		var example *types.Error
   119  		BeforeEach(func() {
   120  			example = &types.Error{
   121  				Code:    1234,
   122  				Msg:     "some message",
   123  				Details: "some details",
   124  			}
   125  		})
   126  
   127  		Describe("Error() method (basic string)", func() {
   128  			It("returns a formatted string", func() {
   129  				Expect(example.Error()).To(Equal("some message; some details"))
   130  			})
   131  			Context("when details are not present", func() {
   132  				BeforeEach(func() {
   133  					example.Details = ""
   134  				})
   135  				It("returns only the message", func() {
   136  					Expect(example.Error()).To(Equal("some message"))
   137  				})
   138  			})
   139  		})
   140  
   141  		It("NewError method", func() {
   142  			err := types.NewError(1234, "some message", "some details")
   143  			Expect(err).To(Equal(example))
   144  		})
   145  	})
   146  })