@@ -4,6 +4,7 @@ package fake
4
4
5
5
import (
6
6
"context"
7
+ "errors"
7
8
8
9
"github.com/hashicorp/go-uuid"
9
10
@@ -12,13 +13,13 @@ import (
12
13
)
13
14
14
15
const zoneID = "a1887604-237c-4212-a9cd-94620b7880fa"
15
- const snapshotID = "9d076136-657b-4c84-b279-455da3ea484c"
16
16
17
17
type fakeConnector struct {
18
- node * cloud.VM
19
- snapshot * cloud.Snapshot
20
- volumesByID map [string ]cloud.Volume
21
- volumesByName map [string ]cloud.Volume
18
+ node * cloud.VM
19
+ volumesByID map [string ]cloud.Volume
20
+ volumesByName map [string ]cloud.Volume
21
+ snapshotsByID map [string ]* cloud.Snapshot
22
+ snapshotsByName map [string ][]* cloud.Snapshot
22
23
}
23
24
24
25
// New returns a new fake implementation of the
@@ -38,20 +39,15 @@ func New() cloud.Interface {
38
39
ZoneID : zoneID ,
39
40
}
40
41
41
- snapshot := & cloud.Snapshot {
42
- ID : "9d076136-657b-4c84-b279-455da3ea484c" ,
43
- Name : "pvc-vol-snap-1" ,
44
- DomainID : "51f0fcb5-db16-4637-94f5-30131010214f" ,
45
- ZoneID : zoneID ,
46
- VolumeID : "4f1f610d-6f17-4ff9-9228-e4062af93e54" ,
47
- CreatedAt : "2025-07-07 16:13:06" ,
48
- }
42
+ snapshotsByID := make (map [string ]* cloud.Snapshot )
43
+ snapshotsByName := make (map [string ][]* cloud.Snapshot )
49
44
50
45
return & fakeConnector {
51
- node : node ,
52
- snapshot : snapshot ,
53
- volumesByID : map [string ]cloud.Volume {volume .ID : volume },
54
- volumesByName : map [string ]cloud.Volume {volume .Name : volume },
46
+ node : node ,
47
+ volumesByID : map [string ]cloud.Volume {volume .ID : volume },
48
+ volumesByName : map [string ]cloud.Volume {volume .Name : volume },
49
+ snapshotsByID : snapshotsByID ,
50
+ snapshotsByName : snapshotsByName ,
55
51
}
56
52
}
57
53
@@ -72,6 +68,9 @@ func (f *fakeConnector) ListZonesID(_ context.Context) ([]string, error) {
72
68
}
73
69
74
70
func (f * fakeConnector ) GetVolumeByID (_ context.Context , volumeID string ) (* cloud.Volume , error ) {
71
+ if volumeID == "" {
72
+ return nil , errors .New ("invalid volume ID: empty string" )
73
+ }
75
74
vol , ok := f .volumesByID [volumeID ]
76
75
if ok {
77
76
return & vol , nil
@@ -81,6 +80,9 @@ func (f *fakeConnector) GetVolumeByID(_ context.Context, volumeID string) (*clou
81
80
}
82
81
83
82
func (f * fakeConnector ) GetVolumeByName (_ context.Context , name string ) (* cloud.Volume , error ) {
83
+ if name == "" {
84
+ return nil , errors .New ("invalid volume name: empty string" )
85
+ }
84
86
vol , ok := f .volumesByName [name ]
85
87
if ok {
86
88
return & vol , nil
@@ -137,18 +139,120 @@ func (f *fakeConnector) ExpandVolume(_ context.Context, volumeID string, newSize
137
139
return cloud .ErrNotFound
138
140
}
139
141
140
- func (f * fakeConnector ) CreateVolumeFromSnapshot (ctx context.Context , zoneID , name , domainID , projectID , snapshotID string , sizeInGB int64 ) (* cloud.Volume , error ) {
141
- return nil , nil
142
+ func (f * fakeConnector ) CreateVolumeFromSnapshot (_ context.Context , zoneID , name , _ , _ string , sizeInGB int64 ) (* cloud.Volume , error ) {
143
+ vol := & cloud.Volume {
144
+ ID : "fake-vol-from-snap-" + name ,
145
+ Name : name ,
146
+ Size : util .GigaBytesToBytes (sizeInGB ),
147
+ DiskOfferingID : "fake-disk-offering" ,
148
+ ZoneID : zoneID ,
149
+ }
150
+ f .volumesByID [vol .ID ] = * vol
151
+ f .volumesByName [vol .Name ] = * vol
152
+
153
+ return vol , nil
142
154
}
143
155
144
- func (f * fakeConnector ) GetSnapshotByID (ctx context.Context , snapshotID string ) (* cloud.Snapshot , error ) {
145
- return f .snapshot , nil
156
+ func (f * fakeConnector ) CreateSnapshot (_ context.Context , volumeID , name string ) (* cloud.Snapshot , error ) {
157
+ if name == "" {
158
+ return nil , errors .New ("invalid snapshot name: empty string" )
159
+ }
160
+ for _ , snap := range f .snapshotsByName [name ] {
161
+ if snap .VolumeID == volumeID {
162
+ // Allow multiple snapshots with the same name for the same volume
163
+ continue
164
+ }
165
+
166
+ // Name conflict: same name, different volume
167
+ return nil , cloud .ErrAlreadyExists
168
+ }
169
+ id , _ := uuid .GenerateUUID ()
170
+ newSnap := & cloud.Snapshot {
171
+ ID : id ,
172
+ Name : name ,
173
+ DomainID : "fake-domain" ,
174
+ ZoneID : zoneID ,
175
+ VolumeID : volumeID ,
176
+ CreatedAt : "2025-07-07T16:13:06-0700" ,
177
+ }
178
+ f .snapshotsByID [newSnap .ID ] = newSnap
179
+ f .snapshotsByName [name ] = append (f .snapshotsByName [name ], newSnap )
180
+
181
+ return newSnap , nil
146
182
}
147
183
148
- func (f * fakeConnector ) CreateSnapshot (ctx context.Context , volumeID string ) (* cloud.Snapshot , error ) {
149
- return f .snapshot , nil
184
+ func (f * fakeConnector ) GetSnapshotByID (_ context.Context , snapshotID string ) (* cloud.Snapshot , error ) {
185
+ snap , ok := f .snapshotsByID [snapshotID ]
186
+ if ok {
187
+ return snap , nil
188
+ }
189
+
190
+ return nil , cloud .ErrNotFound
150
191
}
151
192
152
- func (f * fakeConnector ) DeleteSnapshot (ctx context.Context , snapshotID string ) error {
193
+ func (f * fakeConnector ) GetSnapshotByName (_ context.Context , name string ) (* cloud.Snapshot , error ) {
194
+ if name == "" {
195
+ return nil , errors .New ("invalid snapshot name: empty string" )
196
+ }
197
+ snaps , ok := f .snapshotsByName [name ]
198
+ if ok && len (snaps ) > 0 {
199
+ return snaps [0 ], nil // Return the first for compatibility
200
+ }
201
+
202
+ return nil , cloud .ErrNotFound
203
+ }
204
+
205
+ // ListSnapshots returns all matching snapshots; pagination must be handled by the controller.
206
+ func (f * fakeConnector ) ListSnapshots (_ context.Context , volumeID , snapshotID string ) ([]* cloud.Snapshot , error ) {
207
+ if snapshotID != "" {
208
+ result := make ([]* cloud.Snapshot , 0 , 1 )
209
+ if snap , ok := f .snapshotsByID [snapshotID ]; ok {
210
+ result = append (result , snap )
211
+ }
212
+
213
+ return result , nil
214
+ }
215
+ if volumeID != "" {
216
+ count := 0
217
+ for _ , snap := range f .snapshotsByID {
218
+ if snap .VolumeID == volumeID {
219
+ count ++
220
+ }
221
+ }
222
+ result := make ([]* cloud.Snapshot , 0 , count )
223
+ for _ , snap := range f .snapshotsByID {
224
+ if snap .VolumeID == volumeID {
225
+ result = append (result , snap )
226
+ }
227
+ }
228
+
229
+ return result , nil
230
+ }
231
+ result := make ([]* cloud.Snapshot , 0 , len (f .snapshotsByID ))
232
+ for _ , snap := range f .snapshotsByID {
233
+ result = append (result , snap )
234
+ }
235
+
236
+ return result , nil
237
+ }
238
+
239
+ func (f * fakeConnector ) DeleteSnapshot (_ context.Context , snapshotID string ) error {
240
+ snap , ok := f .snapshotsByID [snapshotID ]
241
+ if ! ok {
242
+ return cloud .ErrNotFound
243
+ }
244
+
245
+ delete (f .snapshotsByID , snapshotID )
246
+
247
+ name := snap .Name
248
+ snaps := f .snapshotsByName [name ]
249
+ for i , s := range snaps {
250
+ if s .ID == snapshotID {
251
+ f .snapshotsByName [name ] = append (snaps [:i ], snaps [i + 1 :]... )
252
+
253
+ break
254
+ }
255
+ }
256
+
153
257
return nil
154
258
}
0 commit comments