Skip to content

Commit df05889

Browse files
authored
Merge pull request #1166 from k8up-io/add-unit-tests-coverage
Add unit tests for restic config validation and API types
2 parents f6cd0ba + 0ca5771 commit df05889

File tree

3 files changed

+281
-0
lines changed

3 files changed

+281
-0
lines changed

api/v1/backend_string_test.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package v1
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestIsNil(t *testing.T) {
10+
assert.True(t, IsNil(nil))
11+
assert.True(t, IsNil((*S3Spec)(nil)))
12+
assert.True(t, IsNil((*BackupSchedule)(nil)))
13+
assert.False(t, IsNil(&S3Spec{}))
14+
assert.False(t, IsNil("not nil"))
15+
assert.False(t, IsNil(42))
16+
}
17+
18+
func TestRestServerSpec_String(t *testing.T) {
19+
tests := map[string]struct {
20+
url string
21+
expected string
22+
}{
23+
"https URL": {
24+
url: "https://backup.example.com/repo",
25+
expected: "rest:https://$(USER):$(PASSWORD)@backup.example.com/repo",
26+
},
27+
"http URL": {
28+
url: "http://localhost:8000/repo",
29+
expected: "rest:http://$(USER):$(PASSWORD)@localhost:8000/repo",
30+
},
31+
"no protocol": {
32+
url: "backup.example.com",
33+
expected: "rest:backup.example.com://$(USER):$(PASSWORD)@",
34+
},
35+
}
36+
for name, tc := range tests {
37+
t.Run(name, func(t *testing.T) {
38+
spec := &RestServerSpec{URL: tc.url}
39+
assert.Equal(t, tc.expected, spec.String())
40+
})
41+
}
42+
}
43+
44+
func TestAzureSpec_String(t *testing.T) {
45+
t.Run("with path", func(t *testing.T) {
46+
spec := &AzureSpec{Container: "mycontainer", Path: "/backups"}
47+
assert.Equal(t, "azure:mycontainer:/backups", spec.String())
48+
})
49+
t.Run("without path defaults to /", func(t *testing.T) {
50+
spec := &AzureSpec{Container: "mycontainer"}
51+
assert.Equal(t, "azure:mycontainer:/", spec.String())
52+
})
53+
}
54+
55+
func TestSwiftSpec_String(t *testing.T) {
56+
spec := &SwiftSpec{Container: "mycontainer", Path: "backups"}
57+
assert.Equal(t, "swift:mycontainer:backups", spec.String())
58+
}
59+
60+
func TestB2Spec_String(t *testing.T) {
61+
spec := &B2Spec{Bucket: "mybucket", Path: "backups"}
62+
assert.Equal(t, "b2:mybucket:backups", spec.String())
63+
}

api/v1/schedule_definition_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package v1
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestScheduleDefinition_String(t *testing.T) {
10+
assert.Equal(t, "*/5 * * * *", ScheduleDefinition("*/5 * * * *").String())
11+
assert.Equal(t, "", ScheduleDefinition("").String())
12+
}
13+
14+
func TestScheduleDefinition_IsNonStandard(t *testing.T) {
15+
tests := map[string]struct {
16+
input ScheduleDefinition
17+
expected bool
18+
}{
19+
"standard cron": {input: "*/5 * * * *", expected: false},
20+
"@daily": {input: "@daily", expected: true},
21+
"@weekly-random": {input: "@weekly-random", expected: true},
22+
"@hourly-random": {input: "@hourly-random", expected: true},
23+
"empty": {input: "", expected: false},
24+
"just @": {input: "@", expected: true},
25+
"no @ prefix": {input: "daily", expected: false},
26+
}
27+
for name, tc := range tests {
28+
t.Run(name, func(t *testing.T) {
29+
assert.Equal(t, tc.expected, tc.input.IsNonStandard())
30+
})
31+
}
32+
}
33+
34+
func TestScheduleDefinition_IsRandom(t *testing.T) {
35+
tests := map[string]struct {
36+
input ScheduleDefinition
37+
expected bool
38+
}{
39+
"@daily-random": {input: "@daily-random", expected: true},
40+
"@weekly-random": {input: "@weekly-random", expected: true},
41+
"@daily": {input: "@daily", expected: false},
42+
"standard cron": {input: "*/5 * * * *", expected: false},
43+
"empty": {input: "", expected: false},
44+
"random no @": {input: "daily-random", expected: false},
45+
"just -random": {input: "-random", expected: false},
46+
"@-random": {input: "@-random", expected: true},
47+
}
48+
for name, tc := range tests {
49+
t.Run(name, func(t *testing.T) {
50+
assert.Equal(t, tc.expected, tc.input.IsRandom())
51+
})
52+
}
53+
}

restic/cfg/config_test.go

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
package cfg
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestValidate_NoOperations(t *testing.T) {
10+
c := &Configuration{}
11+
assert.NoError(t, c.Validate())
12+
}
13+
14+
func TestValidatePrune_NotEnabled(t *testing.T) {
15+
c := &Configuration{DoPrune: false}
16+
assert.NoError(t, c.Validate())
17+
}
18+
19+
func TestValidatePrune_ValidKeepN(t *testing.T) {
20+
c := &Configuration{
21+
DoPrune: true,
22+
PruneKeepLast: 5,
23+
PruneKeepDaily: 14,
24+
}
25+
assert.NoError(t, c.Validate())
26+
}
27+
28+
func TestValidatePrune_NegativeKeepN(t *testing.T) {
29+
c := &Configuration{
30+
DoPrune: true,
31+
PruneKeepLast: -1,
32+
}
33+
err := c.Validate()
34+
assert.Error(t, err)
35+
assert.Contains(t, err.Error(), "keepLast")
36+
assert.Contains(t, err.Error(), "must not be negative")
37+
}
38+
39+
func TestValidatePrune_ValidKeepWithin(t *testing.T) {
40+
c := &Configuration{
41+
DoPrune: true,
42+
PruneKeepWithin: "24h",
43+
}
44+
assert.NoError(t, c.Validate())
45+
}
46+
47+
func TestValidatePrune_InvalidKeepWithinDuration(t *testing.T) {
48+
c := &Configuration{
49+
DoPrune: true,
50+
PruneKeepWithin: "not-a-duration",
51+
}
52+
err := c.Validate()
53+
assert.Error(t, err)
54+
assert.Contains(t, err.Error(), "not valid")
55+
}
56+
57+
func TestValidatePrune_NegativeKeepWithinDuration(t *testing.T) {
58+
c := &Configuration{
59+
DoPrune: true,
60+
PruneKeepWithin: "-1h",
61+
}
62+
err := c.Validate()
63+
assert.Error(t, err)
64+
assert.Contains(t, err.Error(), "must not be negative")
65+
}
66+
67+
func TestValidatePrune_EmptyKeepWithinSkipped(t *testing.T) {
68+
c := &Configuration{
69+
DoPrune: true,
70+
PruneKeepWithin: "",
71+
}
72+
assert.NoError(t, c.Validate())
73+
}
74+
75+
func TestValidateRestore_NotEnabled(t *testing.T) {
76+
c := &Configuration{DoRestore: false}
77+
assert.NoError(t, c.Validate())
78+
}
79+
80+
func TestValidateRestore_S3Valid(t *testing.T) {
81+
c := &Configuration{
82+
DoRestore: true,
83+
RestoreType: "s3",
84+
RestoreS3Endpoint: "http://minio:9000",
85+
RestoreS3AccessKey: "access",
86+
RestoreS3SecretKey: "secret",
87+
}
88+
assert.NoError(t, c.Validate())
89+
}
90+
91+
func TestValidateRestore_S3MissingEndpoint(t *testing.T) {
92+
c := &Configuration{
93+
DoRestore: true,
94+
RestoreType: "s3",
95+
RestoreS3AccessKey: "access",
96+
RestoreS3SecretKey: "secret",
97+
}
98+
err := c.Validate()
99+
assert.Error(t, err)
100+
assert.Contains(t, err.Error(), "endpoint")
101+
}
102+
103+
func TestValidateRestore_S3MissingAccessKey(t *testing.T) {
104+
c := &Configuration{
105+
DoRestore: true,
106+
RestoreType: "s3",
107+
RestoreS3Endpoint: "http://minio:9000",
108+
RestoreS3SecretKey: "secret",
109+
}
110+
err := c.Validate()
111+
assert.Error(t, err)
112+
assert.Contains(t, err.Error(), "access key")
113+
}
114+
115+
func TestValidateRestore_S3MissingSecretKey(t *testing.T) {
116+
c := &Configuration{
117+
DoRestore: true,
118+
RestoreType: "s3",
119+
RestoreS3Endpoint: "http://minio:9000",
120+
RestoreS3AccessKey: "access",
121+
}
122+
err := c.Validate()
123+
assert.Error(t, err)
124+
assert.Contains(t, err.Error(), "secret key")
125+
}
126+
127+
func TestValidateRestore_FolderValid(t *testing.T) {
128+
c := &Configuration{
129+
DoRestore: true,
130+
RestoreType: "folder",
131+
RestoreDir: "/restore",
132+
}
133+
assert.NoError(t, c.Validate())
134+
}
135+
136+
func TestValidateRestore_FolderMissingDir(t *testing.T) {
137+
c := &Configuration{
138+
DoRestore: true,
139+
RestoreType: "folder",
140+
}
141+
err := c.Validate()
142+
assert.Error(t, err)
143+
assert.Contains(t, err.Error(), "directory")
144+
}
145+
146+
func TestValidateRestore_UnknownType(t *testing.T) {
147+
c := &Configuration{
148+
DoRestore: true,
149+
RestoreType: "unknown",
150+
}
151+
err := c.Validate()
152+
assert.Error(t, err)
153+
assert.Contains(t, err.Error(), "unknown")
154+
}
155+
156+
func TestValidateRestore_TypeCaseInsensitive(t *testing.T) {
157+
c := &Configuration{
158+
DoRestore: true,
159+
RestoreType: "S3",
160+
RestoreS3Endpoint: "http://minio:9000",
161+
RestoreS3AccessKey: "access",
162+
RestoreS3SecretKey: "secret",
163+
}
164+
assert.NoError(t, c.Validate())
165+
}

0 commit comments

Comments
 (0)