Skip to content

Commit

Permalink
Add unit tests in tunnel to cover IPv6/dual-stack
Browse files Browse the repository at this point in the history
...for installation of cables. Cable removal will be handled when
support is added to the cable driver interface.

Signed-off-by: Tom Pantelis <[email protected]>
  • Loading branch information
tpantelis committed Feb 26, 2025
1 parent 0d3888b commit 7373981
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 19 deletions.
7 changes: 4 additions & 3 deletions pkg/cableengine/cableengine.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,14 +218,15 @@ func (i *engine) installCableWithNATInfo(rnat *natdiscovery.NATEndpointInfo) err
}
}

logger.Infof("Installing Endpoint cable %q", endpoint.Spec.CableName)
logger.Infof("Installing IPv%v Endpoint cable %q", rnat.UseFamily, endpoint.Spec.CableName)

remoteEndpointIP, err := i.driver.ConnectToEndpoint(rnat)
if err != nil {
return errors.Wrapf(err, "error installing Endpoint cable %q", endpoint.Spec.CableName)
return errors.Wrapf(err, "error installing IPv%v Endpoint cable %q", rnat.UseFamily, endpoint.Spec.CableName)
}

logger.Infof("Successfully installed Endpoint cable %q with remote IP %s", endpoint.Spec.CableName, remoteEndpointIP)
logger.Infof("Successfully installed IPv%v Endpoint cable %q with remote IP %s", rnat.UseFamily, endpoint.Spec.CableName,
remoteEndpointIP)

i.installedCables[rnat.Endpoint.Spec.CableName] = endpoint.CreationTimestamp

Expand Down
132 changes: 116 additions & 16 deletions pkg/controllers/tunnel/tunnel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import (
const (
namespace = "submariner"
ipV4CIDR = "1.2.3.4/16"
ipV6CIDR = "2002::1234:abcd:ffff:c0a8:101/64"
)

func init() {
Expand Down Expand Up @@ -128,18 +129,20 @@ var _ = Describe("Managing tunnels", func() {
stopCh = make(chan struct{})

Expect(tunnel.StartController(engine, namespace, config, stopCh)).To(Succeed())

test.CreateResource(endpoints, endpoint)
})

AfterEach(func() {
close(stopCh)
})

verifyConnectToEndpoint := func() {
verifyConnectToEndpoint := func(family k8snet.IPFamily) {
fakeDriver.AwaitConnectToEndpoint(&natdiscovery.NATEndpointInfo{
UseIP: endpoint.Spec.GetPrivateIP(k8snet.IPv4),
UseIP: endpoint.Spec.GetPrivateIP(family),
UseNAT: false,
Endpoint: *endpoint,
UseFamily: k8snet.IPv4,
UseFamily: family,
})
}

Expand All @@ -148,29 +151,128 @@ var _ = Describe("Managing tunnels", func() {
}

When("an Endpoint is created", func() {
It("should install the cable", func() {
test.CreateResource(endpoints, endpoint)
verifyConnectToEndpoint()
Context("that supports only IPv4", func() {
Context("and the local Endpoint supports only IPv4", func() {
It("should install the IPv4 cable", func() {
verifyConnectToEndpoint(k8snet.IPv4)
fakeDriver.AwaitNoConnectToEndpoint()
})
})

Context("and the local Endpoint supports dual-stack", func() {
BeforeEach(func() {
localEPSpec.Subnets = []string{ipV6CIDR, ipV4CIDR}
})

It("should install the IPv4 cable", func() {
verifyConnectToEndpoint(k8snet.IPv4)
fakeDriver.AwaitNoConnectToEndpoint()
})
})

Context("and the local Endpoint supports only IPv6", func() {
BeforeEach(func() {
localEPSpec.Subnets = []string{ipV6CIDR}
})

It("should not install the cable", func() {
fakeDriver.AwaitNoConnectToEndpoint()
})
})
})

Context("that supports only IPv6", func() {
BeforeEach(func() {
endpoint.Spec.Subnets = []string{ipV6CIDR}
})

Context("and the local Endpoint supports only IPv6", func() {
BeforeEach(func() {
localEPSpec.Subnets = []string{ipV6CIDR}
})

It("should install the IPv6 cable", func() {
verifyConnectToEndpoint(k8snet.IPv6)
fakeDriver.AwaitNoConnectToEndpoint()
})
})

Context("and the local Endpoint supports dual-stack", func() {
BeforeEach(func() {
localEPSpec.Subnets = []string{ipV6CIDR, ipV4CIDR}
})

It("should install the IPv6 cable", func() {
verifyConnectToEndpoint(k8snet.IPv6)
fakeDriver.AwaitNoConnectToEndpoint()
})
})

Context("and the local Endpoint supports only IPv4", func() {
BeforeEach(func() {
localEPSpec.Subnets = []string{ipV4CIDR}
})

It("should not install the cable", func() {
fakeDriver.AwaitNoConnectToEndpoint()
})
})
})

Context("that supports dual-stack", func() {
BeforeEach(func() {
endpoint.Spec.Subnets = []string{ipV6CIDR, ipV4CIDR}
})

Context("and the local Endpoint supports only IPv6", func() {
BeforeEach(func() {
localEPSpec.Subnets = []string{ipV6CIDR}
})

It("should install the IPv6 cable", func() {
verifyConnectToEndpoint(k8snet.IPv6)
fakeDriver.AwaitNoConnectToEndpoint()
})
})

Context("and the local Endpoint supports dual-stack", func() {
BeforeEach(func() {
localEPSpec.Subnets = []string{ipV6CIDR, ipV4CIDR}
})

It("should install both cables", func() {
verifyConnectToEndpoint(k8snet.IPv6)
verifyConnectToEndpoint(k8snet.IPv4)
fakeDriver.AwaitNoConnectToEndpoint()
})
})

Context("and the local Endpoint supports only IPv4", func() {
BeforeEach(func() {
localEPSpec.Subnets = []string{ipV4CIDR}
})

It("should not install the IPv4 cable", func() {
verifyConnectToEndpoint(k8snet.IPv4)
})
})
})
})

When("an Endpoint is updated", func() {
It("should install the cable", func() {
test.CreateResource(endpoints, endpoint)
verifyConnectToEndpoint()
verifyConnectToEndpoint(k8snet.IPv4)

endpoint.Spec.PrivateIPs = []string{"192.68.1.3"}
test.UpdateResource(endpoints, endpoint)

verifyConnectToEndpoint()
verifyConnectToEndpoint(k8snet.IPv4)
})
})

When("an Endpoint is deleted", func() {
It("should remove the cable", func() {
test.CreateResource(endpoints, endpoint)
verifyConnectToEndpoint()

verifyConnectToEndpoint(k8snet.IPv4)
Expect(endpoints.Delete(context.TODO(), endpoint.Name, metav1.DeleteOptions{})).To(Succeed())
verifyDisconnectFromEndpoint()
})
Expand All @@ -183,8 +285,7 @@ var _ = Describe("Managing tunnels", func() {
})

It("should retry until it succeeds", func() {
test.CreateResource(endpoints, endpoint)
verifyConnectToEndpoint()
verifyConnectToEndpoint(k8snet.IPv4)
})
})

Expand All @@ -194,8 +295,7 @@ var _ = Describe("Managing tunnels", func() {
})

It("should retry until it succeeds", func() {
test.CreateResource(endpoints, endpoint)
verifyConnectToEndpoint()
verifyConnectToEndpoint(k8snet.IPv4)

Expect(endpoints.Delete(context.TODO(), endpoint.Name, metav1.DeleteOptions{})).To(Succeed())
verifyDisconnectFromEndpoint()
Expand Down

0 comments on commit 7373981

Please sign in to comment.