Skip to content

Commit 23ad32d

Browse files
committed
Add tests for vpc
1 parent 2969bf2 commit 23ad32d

File tree

1 file changed

+220
-0
lines changed

1 file changed

+220
-0
lines changed

pkg/cloud/vpc_test.go

+220
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
/*
2+
Copyright 2024 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package cloud_test
18+
19+
import (
20+
"errors"
21+
"fmt"
22+
23+
csapi "github.com/apache/cloudstack-go/v2/cloudstack"
24+
"github.com/golang/mock/gomock"
25+
"github.com/onsi/ginkgo/v2"
26+
gomega "github.com/onsi/gomega"
27+
infrav1 "sigs.k8s.io/cluster-api-provider-cloudstack/api/v1beta3"
28+
"sigs.k8s.io/cluster-api-provider-cloudstack/pkg/cloud"
29+
dummies "sigs.k8s.io/cluster-api-provider-cloudstack/test/dummies/v1beta3"
30+
)
31+
32+
var _ = ginkgo.Describe("VPC", func() {
33+
var (
34+
mockCtrl *gomock.Controller
35+
mockClient *csapi.CloudStackClient
36+
vs *csapi.MockVPCServiceIface
37+
client cloud.Client
38+
)
39+
40+
ginkgo.BeforeEach(func() {
41+
// Setup new mock services.
42+
mockCtrl = gomock.NewController(ginkgo.GinkgoT())
43+
mockClient = csapi.NewMockClient(mockCtrl)
44+
vs = mockClient.VPC.(*csapi.MockVPCServiceIface)
45+
client = cloud.NewClientFromCSAPIClient(mockClient, nil)
46+
dummies.SetDummyVars()
47+
})
48+
49+
ginkgo.AfterEach(func() {
50+
mockCtrl.Finish()
51+
})
52+
53+
ginkgo.Context("for an existing VPC", func() {
54+
var dummyVPC infrav1.VPC
55+
56+
ginkgo.BeforeEach(func() {
57+
dummyVPC = infrav1.VPC{
58+
ID: "vpc-123",
59+
Name: "test-vpc",
60+
CIDR: "10.0.0.0/16",
61+
}
62+
})
63+
64+
ginkgo.It("resolves VPC by ID", func() {
65+
dummyCSVPC := &csapi.VPC{
66+
Id: dummyVPC.ID,
67+
Name: dummyVPC.Name,
68+
Cidr: dummyVPC.CIDR,
69+
}
70+
71+
vs.EXPECT().GetVPCByID(dummyVPC.ID, gomock.Any()).Return(dummyCSVPC, 1, nil)
72+
73+
gomega.Ω(client.ResolveVPC(&dummyVPC)).Should(gomega.Succeed())
74+
gomega.Ω(dummyVPC.Name).Should(gomega.Equal("test-vpc"))
75+
})
76+
77+
ginkgo.It("resolves VPC by Name", func() {
78+
dummyVPC.ID = "" // Clear ID to test by name
79+
80+
dummyCSVPC := &csapi.VPC{
81+
Id: "vpc-123",
82+
Name: dummyVPC.Name,
83+
Cidr: dummyVPC.CIDR,
84+
}
85+
86+
vs.EXPECT().GetVPCByName(dummyVPC.Name, gomock.Any()).Return(dummyCSVPC, 1, nil)
87+
88+
gomega.Ω(client.ResolveVPC(&dummyVPC)).Should(gomega.Succeed())
89+
gomega.Ω(dummyVPC.ID).Should(gomega.Equal("vpc-123"))
90+
})
91+
92+
ginkgo.It("returns error when VPC not found by ID", func() {
93+
vs.EXPECT().GetVPCByID(dummyVPC.ID, gomock.Any()).Return(nil, 0, nil)
94+
95+
err := client.ResolveVPC(&dummyVPC)
96+
gomega.Ω(err).ShouldNot(gomega.Succeed())
97+
gomega.Ω(err.Error()).Should(gomega.ContainSubstring(fmt.Sprintf("no VPC found with ID %s", dummyVPC.ID)))
98+
})
99+
100+
ginkgo.It("returns error when VPC not found by Name", func() {
101+
dummyVPC.ID = "" // Clear ID to test by name
102+
103+
vs.EXPECT().GetVPCByName(dummyVPC.Name, gomock.Any()).Return(nil, 0, nil)
104+
105+
err := client.ResolveVPC(&dummyVPC)
106+
gomega.Ω(err).ShouldNot(gomega.Succeed())
107+
gomega.Ω(err.Error()).Should(gomega.ContainSubstring(fmt.Sprintf("no VPC found with name %s", dummyVPC.Name)))
108+
})
109+
110+
ginkgo.It("returns error when GetVPCByID fails", func() {
111+
expectedErr := errors.New("API error")
112+
vs.EXPECT().GetVPCByID(dummyVPC.ID, gomock.Any()).Return(nil, 0, expectedErr)
113+
114+
err := client.ResolveVPC(&dummyVPC)
115+
gomega.Ω(err).ShouldNot(gomega.Succeed())
116+
gomega.Ω(err.Error()).Should(gomega.ContainSubstring(fmt.Sprintf("failed to get VPC with ID %s", dummyVPC.ID)))
117+
})
118+
119+
ginkgo.It("returns error when GetVPCByName fails", func() {
120+
dummyVPC.ID = "" // Clear ID to test by name
121+
expectedErr := errors.New("API error")
122+
vs.EXPECT().GetVPCByName(dummyVPC.Name, gomock.Any()).Return(nil, 0, expectedErr)
123+
124+
err := client.ResolveVPC(&dummyVPC)
125+
gomega.Ω(err).ShouldNot(gomega.Succeed())
126+
gomega.Ω(err.Error()).Should(gomega.ContainSubstring(fmt.Sprintf("failed to get VPC with name %s", dummyVPC.Name)))
127+
})
128+
129+
ginkgo.It("handles nil VPC", func() {
130+
gomega.Ω(client.ResolveVPC(nil)).Should(gomega.Succeed())
131+
})
132+
133+
ginkgo.It("handles empty VPC", func() {
134+
emptyVPC := &infrav1.VPC{}
135+
gomega.Ω(client.ResolveVPC(emptyVPC)).Should(gomega.Succeed())
136+
})
137+
})
138+
139+
ginkgo.Context("for creating a VPC", func() {
140+
var (
141+
dummyFD infrav1.CloudStackFailureDomain
142+
dummyVPC infrav1.VPC
143+
)
144+
145+
ginkgo.BeforeEach(func() {
146+
dummyFD = infrav1.CloudStackFailureDomain{
147+
Spec: infrav1.CloudStackFailureDomainSpec{
148+
Zone: infrav1.CloudStackZoneSpec{
149+
ID: "zone-123",
150+
},
151+
},
152+
}
153+
dummyVPC = infrav1.VPC{
154+
Name: "test-vpc",
155+
CIDR: "10.0.0.0/16",
156+
}
157+
})
158+
159+
ginkgo.It("creates a new VPC successfully", func() {
160+
offeringID := "offering-123"
161+
createVPCParams := &csapi.CreateVPCParams{}
162+
createVPCResponse := &csapi.CreateVPCResponse{
163+
Id: "vpc-123",
164+
}
165+
166+
vs.EXPECT().GetVPCOfferingID(cloud.VPCOffering).Return(offeringID, 1, nil)
167+
vs.EXPECT().NewCreateVPCParams(dummyVPC.CIDR, dummyVPC.Name, dummyVPC.Name, offeringID, dummyFD.Spec.Zone.ID).Return(createVPCParams)
168+
vs.EXPECT().CreateVPC(createVPCParams).Return(createVPCResponse, nil)
169+
170+
gomega.Ω(client.CreateVPC(&dummyFD, &dummyVPC)).Should(gomega.Succeed())
171+
gomega.Ω(dummyVPC.ID).Should(gomega.Equal("vpc-123"))
172+
})
173+
174+
ginkgo.It("returns error when VPC offering cannot be fetched", func() {
175+
expectedErr := errors.New("failed to get VPC offering")
176+
vs.EXPECT().GetVPCOfferingID(cloud.VPCOffering).Return("", 0, expectedErr)
177+
178+
err := client.CreateVPC(&dummyFD, &dummyVPC)
179+
gomega.Ω(err).ShouldNot(gomega.Succeed())
180+
gomega.Ω(err.Error()).Should(gomega.Equal(expectedErr.Error()))
181+
})
182+
183+
ginkgo.It("returns error when multiple VPC offerings found", func() {
184+
vs.EXPECT().GetVPCOfferingID(cloud.VPCOffering).Return("", 2, nil)
185+
186+
err := client.CreateVPC(&dummyFD, &dummyVPC)
187+
gomega.Ω(err).ShouldNot(gomega.Succeed())
188+
gomega.Ω(err.Error()).Should(gomega.Equal("found more than one vpc offering"))
189+
})
190+
191+
ginkgo.It("returns error when CreateVPC fails", func() {
192+
offeringID := "offering-123"
193+
createVPCParams := &csapi.CreateVPCParams{}
194+
expectedErr := errors.New("API error")
195+
196+
vs.EXPECT().GetVPCOfferingID(cloud.VPCOffering).Return(offeringID, 1, nil)
197+
vs.EXPECT().NewCreateVPCParams(dummyVPC.CIDR, dummyVPC.Name, dummyVPC.Name, offeringID, dummyFD.Spec.Zone.ID).Return(createVPCParams)
198+
vs.EXPECT().CreateVPC(createVPCParams).Return(nil, expectedErr)
199+
200+
err := client.CreateVPC(&dummyFD, &dummyVPC)
201+
gomega.Ω(err).ShouldNot(gomega.Succeed())
202+
gomega.Ω(err.Error()).Should(gomega.ContainSubstring(fmt.Sprintf("creating VPC with name %s", dummyVPC.Name)))
203+
})
204+
205+
ginkgo.It("returns error when VPC is nil", func() {
206+
err := client.CreateVPC(&dummyFD, nil)
207+
gomega.Ω(err).ShouldNot(gomega.Succeed())
208+
gomega.Ω(err.Error()).Should(gomega.Equal("VPC name must be specified"))
209+
})
210+
211+
ginkgo.It("returns error when VPC name is empty", func() {
212+
emptyNameVPC := &infrav1.VPC{
213+
CIDR: "10.0.0.0/16",
214+
}
215+
err := client.CreateVPC(&dummyFD, emptyNameVPC)
216+
gomega.Ω(err).ShouldNot(gomega.Succeed())
217+
gomega.Ω(err.Error()).Should(gomega.Equal("VPC name must be specified"))
218+
})
219+
})
220+
})

0 commit comments

Comments
 (0)