272 lines
5.7 KiB
Go
272 lines
5.7 KiB
Go
// Copyright 2021 CNI authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package ip
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net"
|
|
|
|
. "github.com/onsi/ginkgo/v2"
|
|
. "github.com/onsi/gomega"
|
|
)
|
|
|
|
var _ = Describe("IP Operations", func() {
|
|
It("Parse", func() {
|
|
testCases := []struct {
|
|
ipStr string
|
|
expected *IP
|
|
}{
|
|
{
|
|
"192.168.0.10",
|
|
newIP(net.IPv4(192, 168, 0, 10), nil),
|
|
},
|
|
{
|
|
"2001:db8::1",
|
|
newIP(net.ParseIP("2001:db8::1"), nil),
|
|
},
|
|
{
|
|
"192.168.0.10/24",
|
|
newIP(net.IPv4(192, 168, 0, 10), net.IPv4Mask(255, 255, 255, 0)),
|
|
},
|
|
{
|
|
"2001:db8::1/64",
|
|
newIP(net.ParseIP("2001:db8::1"), net.CIDRMask(64, 128)),
|
|
},
|
|
{
|
|
"invalid",
|
|
nil,
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
ip := ParseIP(test.ipStr)
|
|
|
|
Expect(ip).To(Equal(test.expected))
|
|
}
|
|
})
|
|
|
|
It("String", func() {
|
|
testCases := []struct {
|
|
ip *IP
|
|
expected string
|
|
}{
|
|
{
|
|
newIP(net.IPv4(192, 168, 0, 1), net.IPv4Mask(255, 255, 255, 0)),
|
|
"192.168.0.1/24",
|
|
},
|
|
{
|
|
newIP(net.IPv4(192, 168, 0, 2), nil),
|
|
"192.168.0.2",
|
|
},
|
|
{
|
|
newIP(net.ParseIP("2001:db8::1"), nil),
|
|
"2001:db8::1",
|
|
},
|
|
{
|
|
newIP(net.ParseIP("2001:db8::1"), net.CIDRMask(64, 128)),
|
|
"2001:db8::1/64",
|
|
},
|
|
{
|
|
newIP(nil, nil),
|
|
"<nil>",
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
Expect(test.ip.String()).To(Equal(test.expected))
|
|
}
|
|
})
|
|
|
|
It("ToIP", func() {
|
|
testCases := []struct {
|
|
ip *IP
|
|
expectedLen int
|
|
expectedIP net.IP
|
|
}{
|
|
{
|
|
newIP(net.IPv4(192, 168, 0, 1), net.IPv4Mask(255, 255, 255, 0)),
|
|
net.IPv4len,
|
|
net.IP{192, 168, 0, 1},
|
|
},
|
|
{
|
|
newIP(net.IPv4(192, 168, 0, 2), nil),
|
|
net.IPv4len,
|
|
net.IP{192, 168, 0, 2},
|
|
},
|
|
{
|
|
newIP(net.ParseIP("2001:db8::1"), nil),
|
|
net.IPv6len,
|
|
net.IP{32, 1, 13, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
},
|
|
{
|
|
newIP(net.ParseIP("2001:db8::1"), net.CIDRMask(64, 128)),
|
|
net.IPv6len,
|
|
net.IP{32, 1, 13, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
},
|
|
{
|
|
newIP(nil, nil),
|
|
0,
|
|
nil,
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
Expect(test.ip.ToIP()).To(HaveLen(test.expectedLen))
|
|
Expect(test.ip.ToIP()).To(Equal(test.expectedIP))
|
|
}
|
|
})
|
|
|
|
It("Encode", func() {
|
|
testCases := []struct {
|
|
object interface{}
|
|
expected string
|
|
}{
|
|
{
|
|
newIP(net.IPv4(192, 168, 0, 1), net.IPv4Mask(255, 255, 255, 0)),
|
|
`"192.168.0.1/24"`,
|
|
},
|
|
{
|
|
newIP(net.IPv4(192, 168, 0, 2), nil),
|
|
`"192.168.0.2"`,
|
|
},
|
|
{
|
|
newIP(net.ParseIP("2001:db8::1"), nil),
|
|
`"2001:db8::1"`,
|
|
},
|
|
{
|
|
newIP(net.ParseIP("2001:db8::1"), net.CIDRMask(64, 128)),
|
|
`"2001:db8::1/64"`,
|
|
},
|
|
{
|
|
newIP(nil, nil),
|
|
`""`,
|
|
},
|
|
{
|
|
[]*IP{
|
|
newIP(net.IPv4(192, 168, 0, 1), net.IPv4Mask(255, 255, 255, 0)),
|
|
newIP(net.IPv4(192, 168, 0, 2), nil),
|
|
newIP(net.ParseIP("2001:db8::1"), nil),
|
|
newIP(net.ParseIP("2001:db8::1"), net.CIDRMask(64, 128)),
|
|
newIP(nil, nil),
|
|
},
|
|
`["192.168.0.1/24","192.168.0.2","2001:db8::1","2001:db8::1/64",""]`,
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
bytes, err := json.Marshal(test.object)
|
|
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(string(bytes)).To(Equal(test.expected))
|
|
}
|
|
})
|
|
|
|
Context("Decode", func() {
|
|
It("valid IP", func() {
|
|
testCases := []struct {
|
|
text string
|
|
expected *IP
|
|
}{
|
|
{
|
|
`"192.168.0.1"`,
|
|
newIP(net.IPv4(192, 168, 0, 1), nil),
|
|
},
|
|
{
|
|
`"192.168.0.1/24"`,
|
|
newIP(net.IPv4(192, 168, 0, 1), net.IPv4Mask(255, 255, 255, 0)),
|
|
},
|
|
{
|
|
`"2001:db8::1"`,
|
|
newIP(net.ParseIP("2001:db8::1"), nil),
|
|
},
|
|
{
|
|
`"2001:db8::1/64"`,
|
|
newIP(net.ParseIP("2001:db8::1"), net.CIDRMask(64, 128)),
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
ip := &IP{}
|
|
err := json.Unmarshal([]byte(test.text), ip)
|
|
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(ip).To(Equal(test.expected))
|
|
}
|
|
})
|
|
|
|
It("empty text", func() {
|
|
ip := &IP{}
|
|
err := json.Unmarshal([]byte(`""`), ip)
|
|
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(ip).To(Equal(newIP(nil, nil)))
|
|
})
|
|
|
|
It("invalid IP", func() {
|
|
testCases := []struct {
|
|
text string
|
|
expectedErr error
|
|
}{
|
|
{
|
|
`"192.168.0.1000"`,
|
|
fmt.Errorf("invalid IP address 192.168.0.1000"),
|
|
},
|
|
{
|
|
`"2001:db8::1/256"`,
|
|
fmt.Errorf("invalid IP address 2001:db8::1/256"),
|
|
},
|
|
{
|
|
`"test"`,
|
|
fmt.Errorf("invalid IP address test"),
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
err := json.Unmarshal([]byte(test.text), &IP{})
|
|
|
|
Expect(err).To(HaveOccurred())
|
|
Expect(err).To(Equal(test.expectedErr))
|
|
}
|
|
})
|
|
|
|
It("IP slice", func() {
|
|
testCases := []struct {
|
|
text string
|
|
expected []*IP
|
|
}{
|
|
{
|
|
`["192.168.0.1/24","192.168.0.2","2001:db8::1","2001:db8::1/64",""]`,
|
|
[]*IP{
|
|
newIP(net.IPv4(192, 168, 0, 1), net.IPv4Mask(255, 255, 255, 0)),
|
|
newIP(net.IPv4(192, 168, 0, 2), nil),
|
|
newIP(net.ParseIP("2001:db8::1"), nil),
|
|
newIP(net.ParseIP("2001:db8::1"), net.CIDRMask(64, 128)),
|
|
newIP(nil, nil),
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
ips := make([]*IP, 0)
|
|
err := json.Unmarshal([]byte(test.text), &ips)
|
|
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(ips).To(Equal(test.expected))
|
|
}
|
|
})
|
|
})
|
|
})
|