122 lines
3.7 KiB
Go
122 lines
3.7 KiB
Go
package oci
|
|
|
|
import "testing"
|
|
|
|
func TestNextSubnetIPv6CIDR(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
vcnCidr string
|
|
used []string
|
|
want string
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "无占用取首个",
|
|
vcnCidr: "2603:c020:e:de00::/56",
|
|
want: "2603:c020:e:de00::/64",
|
|
},
|
|
{
|
|
name: "跳过已用索引",
|
|
vcnCidr: "2603:c020:e:de00::/56",
|
|
used: []string{"2603:c020:e:de00::/64", "2603:c020:e:de01::/64"},
|
|
want: "2603:c020:e:de02::/64",
|
|
},
|
|
{
|
|
name: "其他前缀的占用不影响",
|
|
vcnCidr: "2603:c020:e:de00::/56",
|
|
used: []string{"2603:c020:f:aa00::/64"},
|
|
want: "2603:c020:e:de00::/64",
|
|
},
|
|
{
|
|
name: "非法 VCN 前缀报错",
|
|
vcnCidr: "not-a-cidr",
|
|
wantErr: true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got, err := nextSubnetIPv6CIDR(tt.vcnCidr, tt.used)
|
|
if (err != nil) != tt.wantErr {
|
|
t.Fatalf("nextSubnetIPv6CIDR() error = %v, wantErr %v", err, tt.wantErr)
|
|
}
|
|
if !tt.wantErr && got != tt.want {
|
|
t.Errorf("nextSubnetIPv6CIDR() = %q, want %q", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestNextSubnetIPv6CIDRExhausted(t *testing.T) {
|
|
used := make([]string, 0, 256)
|
|
base := "2603:c020:e:de00::/56"
|
|
for i := 0; i <= 255; i++ {
|
|
cidr, err := nextSubnetIPv6CIDR(base, used)
|
|
if err != nil {
|
|
t.Fatalf("allocation %d failed: %v", i, err)
|
|
}
|
|
used = append(used, cidr)
|
|
}
|
|
if _, err := nextSubnetIPv6CIDR(base, used); err == nil {
|
|
t.Error("257th allocation: got nil error, want exhausted failure")
|
|
}
|
|
}
|
|
|
|
func TestSameIPv6(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
a, b string
|
|
want bool
|
|
}{
|
|
{name: "完全一致", a: "2603:c020:e:de00::1", b: "2603:c020:e:de00::1", want: true},
|
|
{name: "大小写不敏感", a: "2603:C020:E:DE00::1", b: "2603:c020:e:de00::1", want: true},
|
|
{name: "缩写与全写等价", a: "2603:c020:e:de00:0:0:0:1", b: "2603:c020:e:de00::1", want: true},
|
|
{name: "不同地址", a: "2603:c020:e:de00::1", b: "2603:c020:e:de00::2", want: false},
|
|
{name: "非法输入回退字符串比较", a: "not-an-ip", b: "not-an-ip", want: true},
|
|
{name: "非法输入不相等", a: "not-an-ip", b: "2603:c020:e:de00::1", want: false},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := sameIPv6(tt.a, tt.b); got != tt.want {
|
|
t.Errorf("sameIPv6(%q, %q) = %v, want %v", tt.a, tt.b, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestBuildRuleOptions(t *testing.T) {
|
|
port := func(n int) *int { return &n }
|
|
tests := []struct {
|
|
name string
|
|
rule SecurityRule
|
|
wantTCP bool
|
|
wantUDP bool
|
|
wantICMP bool
|
|
}{
|
|
{name: "TCP 端口", rule: SecurityRule{Protocol: "6", PortMin: port(22)}, wantTCP: true},
|
|
{name: "UDP 端口", rule: SecurityRule{Protocol: "17", PortMin: port(53), PortMax: port(53)}, wantUDP: true},
|
|
{name: "ICMP 类型", rule: SecurityRule{Protocol: "1", IcmpType: port(8)}, wantICMP: true},
|
|
{name: "ICMPv6 类型", rule: SecurityRule{Protocol: "58", IcmpType: port(128)}, wantICMP: true},
|
|
{name: "all 无选项", rule: SecurityRule{Protocol: "all"}},
|
|
{name: "TCP 无端口无选项", rule: SecurityRule{Protocol: "6"}},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
tcp, udp, icmp := buildRuleOptions(tt.rule)
|
|
if (tcp != nil) != tt.wantTCP {
|
|
t.Errorf("tcp options = %v, want present=%v", tcp, tt.wantTCP)
|
|
}
|
|
if (udp != nil) != tt.wantUDP {
|
|
t.Errorf("udp options = %v, want present=%v", udp, tt.wantUDP)
|
|
}
|
|
if (icmp != nil) != tt.wantICMP {
|
|
t.Errorf("icmp options = %v, want present=%v", icmp, tt.wantICMP)
|
|
}
|
|
if tt.wantTCP && tt.rule.PortMax == nil {
|
|
if got, want := *tcp.DestinationPortRange.Max, *tt.rule.PortMin; got != want {
|
|
t.Errorf("port max = %d, want fallback to min %d", got, want)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|