Skip to content

Commit 0c67298

Browse files
stackit-skexoxys
andauthored
[release-v1.31] Add more low-hanging tests (#65)
* Add more low-hanging tests * cleanup * fix linter --------- Co-authored-by: Robert Kaussow <[email protected]>
1 parent 2d3e24a commit 0c67298

File tree

10 files changed

+592
-4
lines changed

10 files changed

+592
-4
lines changed

pkg/csi/util/suite_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package util
2+
3+
import (
4+
"testing"
5+
6+
. "github.com/onsi/ginkgo/v2"
7+
. "github.com/onsi/gomega"
8+
)
9+
10+
func TestUtil(t *testing.T) {
11+
RegisterFailHandler(Fail)
12+
RunSpecs(t, "Util Suite")
13+
}

pkg/csi/util/util_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package util
2+
3+
import (
4+
. "github.com/onsi/ginkgo/v2"
5+
. "github.com/onsi/gomega"
6+
)
7+
8+
var _ = Describe("RoundUpSize", func() {
9+
Context("when calculating allocation units", func() {
10+
It("should return exact multiple when volume size is exact", func() {
11+
// 10GB volume with 1GB allocation units
12+
result := RoundUpSize(10*GIBIBYTE, 1*GIBIBYTE)
13+
Expect(result).To(Equal(int64(10)))
14+
})
15+
16+
It("should round up when volume size is not exact", func() {
17+
// 1500MB volume with 1GB allocation units
18+
result := RoundUpSize(1500*MEBIBYTE, 1*GIBIBYTE)
19+
Expect(result).To(Equal(int64(2)))
20+
})
21+
22+
It("should handle zero volume size", func() {
23+
result := RoundUpSize(0, 1*GIBIBYTE)
24+
Expect(result).To(Equal(int64(0)))
25+
})
26+
27+
It("should handle allocation unit larger than volume", func() {
28+
// 500MB volume with 1GB allocation units
29+
result := RoundUpSize(500*MEBIBYTE, 1*GIBIBYTE)
30+
Expect(result).To(Equal(int64(1)))
31+
})
32+
})
33+
})

pkg/labels/labels_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package labels
2+
3+
import (
4+
. "github.com/onsi/ginkgo/v2"
5+
. "github.com/onsi/gomega"
6+
)
7+
8+
var _ = Describe("Sanitize", func() {
9+
Context("when sanitizing labels", func() {
10+
It("should replace non-alphanumeric characters with hyphens", func() {
11+
result := Sanitize("test-label_with.special@chars!")
12+
Expect(result).To(Equal("test-label_with.special-chars"))
13+
})
14+
15+
It("should trim hyphens, underscores, and dots from the beginning and end", func() {
16+
result := Sanitize("...test-label---")
17+
Expect(result).To(Equal("test-label"))
18+
})
19+
20+
It("should truncate labels longer than 63 characters", func() {
21+
longLabel := "this-is-a-very-long-label-that-should-be-truncated-to-63-characters-1234567890"
22+
result := Sanitize(longLabel)
23+
Expect(len(result)).To(BeNumerically("<=", 63))
24+
Expect(result).To(Equal("this-is-a-very-long-label-that-should-be-truncated-to-63-charac"))
25+
})
26+
27+
It("should handle empty string", func() {
28+
result := Sanitize("")
29+
Expect(result).To(Equal(""))
30+
})
31+
32+
It("should handle string with only invalid characters", func() {
33+
result := Sanitize("!@#$%^&*()")
34+
Expect(result).To(Equal(""))
35+
})
36+
})
37+
})

pkg/labels/suit_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package labels
2+
3+
import (
4+
"testing"
5+
6+
. "github.com/onsi/ginkgo/v2"
7+
. "github.com/onsi/gomega"
8+
)
9+
10+
func TestLabels(t *testing.T) {
11+
RegisterFailHandler(Fail)
12+
RunSpecs(t, "Labels Suite")
13+
}

pkg/stackit/backups.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ const (
2626
)
2727

2828
func (os *iaasClient) CreateBackup(ctx context.Context, name, volID, snapshotID string, tags map[string]string) (*iaas.Backup, error) {
29+
if name == "" {
30+
return nil, errors.New("backup name cannot be empty")
31+
}
32+
33+
if volID == "" && snapshotID == "" {
34+
return nil, errors.New("either volID or snapshotID must be provided")
35+
}
36+
2937
var backupSource VolumeSourceTypes
3038
var backupSourceID string
3139
if volID != "" {
@@ -49,7 +57,12 @@ func (os *iaasClient) CreateBackup(ctx context.Context, name, volID, snapshotID
4957
}
5058
var httpResp *http.Response
5159
ctxWithHTTPResp := runtime.WithCaptureHTTPResponse(ctx, &httpResp)
52-
backup, err := os.iaas.CreateBackup(ctxWithHTTPResp, os.projectID, os.region).CreateBackupPayload(opts).Execute()
60+
createBackupRequest := os.iaas.CreateBackup(ctxWithHTTPResp, os.projectID, os.region)
61+
if createBackupRequest == nil {
62+
return nil, errors.New("failed to create backup request")
63+
}
64+
65+
backup, err := createBackupRequest.CreateBackupPayload(opts).Execute()
5366
if err != nil {
5467
if httpResp != nil {
5568
reqID := httpResp.Header.Get(wait.XRequestIDHeader)

pkg/stackit/backups_test.go

Lines changed: 162 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ var _ = Describe("Backup", func() {
5353
mockCreateBackup(
5454
mockCtrl,
5555
mockAPI,
56-
projectID,
57-
region,
5856
expectedPayload,
5957
)
6058

@@ -94,11 +92,172 @@ var _ = Describe("Backup", func() {
9492
},
9593
),
9694
)
95+
})
96+
97+
Context("CreateBackup error cases", func() {
98+
const projectID = "project-id"
99+
100+
BeforeEach(func() {
101+
config = &Config{
102+
Global: GlobalOpts{
103+
ProjectID: projectID,
104+
},
105+
}
106+
openStack, err = CreateSTACKITProvider(mockAPI, config)
107+
Expect(err).ToNot(HaveOccurred())
108+
})
109+
110+
It("should return error when API fails", func() {
111+
mockAPI.EXPECT().CreateBackup(gomock.Any(), projectID, region).Return(nil).Times(1)
112+
113+
backup, err := openStack.CreateBackup(context.Background(), "expected-name", "volume-id", "", nil)
114+
Expect(err).To(HaveOccurred())
115+
Expect(backup).To(BeNil())
116+
})
97117

118+
It("should return error when both volID and snapshotID are empty", func() {
119+
backup, err := openStack.CreateBackup(context.Background(), "expected-name", "", "", nil)
120+
Expect(err).To(HaveOccurred())
121+
Expect(backup).To(BeNil())
122+
})
123+
124+
It("should return error when name is empty", func() {
125+
backup, err := openStack.CreateBackup(context.Background(), "", "volume-id", "", nil)
126+
Expect(err).To(HaveOccurred())
127+
Expect(backup).To(BeNil())
128+
})
129+
})
130+
131+
Context("CreateBackup validation cases", func() {
132+
const projectID = "project-id"
133+
134+
BeforeEach(func() {
135+
config = &Config{
136+
Global: GlobalOpts{
137+
ProjectID: projectID,
138+
},
139+
}
140+
openStack, err = CreateSTACKITProvider(mockAPI, config)
141+
Expect(err).ToNot(HaveOccurred())
142+
})
143+
144+
It("should return error when source type is invalid", func() {
145+
// Test with an invalid source type
146+
// Mock the API call to return nil, which will trigger our validation
147+
mockAPI.EXPECT().CreateBackup(gomock.Any(), projectID, region).Return(nil).Times(1)
148+
149+
backup, err := openStack.CreateBackup(context.Background(), "expected-name", "volume-id", "", nil)
150+
Expect(err).To(HaveOccurred())
151+
Expect(err.Error()).To(ContainSubstring("failed to create backup request"))
152+
Expect(backup).To(BeNil())
153+
})
154+
155+
It("should handle special characters in tags", func() {
156+
tags := map[string]string{
157+
"special": "tag with spaces and !@#$%^&*()",
158+
"normal": "value",
159+
}
160+
161+
expectedPayload := iaas.CreateBackupPayload{
162+
Name: ptr.To("expected-name"),
163+
Source: &iaas.BackupSource{
164+
Type: ptr.To("volume"),
165+
Id: ptr.To("volume-id"),
166+
},
167+
Labels: ptr.To(map[string]any{
168+
"special": "tag with spaces and !@#$%^&*()",
169+
"normal": "value",
170+
}),
171+
}
172+
173+
mockCreateBackup(mockCtrl, mockAPI, expectedPayload)
174+
175+
backup, err := openStack.CreateBackup(context.Background(), "expected-name", "volume-id", "", tags)
176+
Expect(err).ToNot(HaveOccurred())
177+
Expect(backup).ToNot(BeNil())
178+
Expect(backup.Id).ToNot(BeNil())
179+
Expect(*backup.Id).To(Equal("expected backup"))
180+
})
181+
})
182+
183+
Context("CreateBackup edge cases", func() {
184+
const projectID = "project-id"
185+
186+
BeforeEach(func() {
187+
config = &Config{
188+
Global: GlobalOpts{
189+
ProjectID: projectID,
190+
},
191+
}
192+
openStack, err = CreateSTACKITProvider(mockAPI, config)
193+
Expect(err).ToNot(HaveOccurred())
194+
})
195+
196+
It("should handle nil tags", func() {
197+
expectedPayload := iaas.CreateBackupPayload{
198+
Name: ptr.To("expected-name"),
199+
Source: &iaas.BackupSource{
200+
Type: ptr.To("volume"),
201+
Id: ptr.To("volume-id"),
202+
},
203+
Labels: nil,
204+
}
205+
206+
mockCreateBackup(mockCtrl, mockAPI, expectedPayload)
207+
208+
backup, err := openStack.CreateBackup(context.Background(), "expected-name", "volume-id", "", nil)
209+
Expect(err).ToNot(HaveOccurred())
210+
Expect(backup).ToNot(BeNil())
211+
Expect(backup.Id).ToNot(BeNil())
212+
Expect(*backup.Id).To(Equal("expected backup"))
213+
})
214+
215+
It("should handle empty tags map", func() {
216+
expectedPayload := iaas.CreateBackupPayload{
217+
Name: ptr.To("expected-name"),
218+
Source: &iaas.BackupSource{
219+
Type: ptr.To("volume"),
220+
Id: ptr.To("volume-id"),
221+
},
222+
Labels: ptr.To(map[string]any{}),
223+
}
224+
225+
mockCreateBackup(mockCtrl, mockAPI, expectedPayload)
226+
227+
backup, err := openStack.CreateBackup(context.Background(), "expected-name", "volume-id", "", map[string]string{})
228+
Expect(err).ToNot(HaveOccurred())
229+
Expect(backup).ToNot(BeNil())
230+
Expect(backup.Id).ToNot(BeNil())
231+
Expect(*backup.Id).To(Equal("expected backup"))
232+
})
233+
234+
It("should handle long backup name", func() {
235+
longName := "very-long-backup-name-" + string(make([]byte, 200))
236+
237+
expectedPayload := iaas.CreateBackupPayload{
238+
Name: ptr.To(longName),
239+
Source: &iaas.BackupSource{
240+
Type: ptr.To("volume"),
241+
Id: ptr.To("volume-id"),
242+
},
243+
}
244+
245+
mockCreateBackup(mockCtrl, mockAPI, expectedPayload)
246+
247+
backup, err := openStack.CreateBackup(context.Background(), longName, "volume-id", "", nil)
248+
Expect(err).ToNot(HaveOccurred())
249+
Expect(backup).ToNot(BeNil())
250+
Expect(backup.Id).ToNot(BeNil())
251+
Expect(*backup.Id).To(Equal("expected backup"))
252+
})
98253
})
99254
})
100255

101-
func mockCreateBackup(mockCtrl *gomock.Controller, mockAPI *mock.MockDefaultApi, projectID, region string, expectedPayload iaas.CreateBackupPayload) {
256+
func mockCreateBackup(mockCtrl *gomock.Controller, mockAPI *mock.MockDefaultApi, expectedPayload iaas.CreateBackupPayload) {
257+
const (
258+
projectID = "project-id"
259+
region = "eu01"
260+
)
102261
createRequest := mock.NewMockApiCreateBackupRequest(mockCtrl)
103262
createRequest.EXPECT().CreateBackupPayload(expectedPayload).Return(createRequest)
104263
createRequest.EXPECT().Execute().Return(&iaas.Backup{Id: ptr.To("expected backup")}, nil)

0 commit comments

Comments
 (0)