@@ -2,6 +2,7 @@ package controller
22
33import (
44 "context"
5+ "errors"
56 "fmt"
67 "slices"
78 "strconv"
@@ -119,6 +120,7 @@ var _ = Describe("FinBackup Controller integration test", Ordered, func() {
119120 podImage : podImage ,
120121 maxPartSize : & defaultMaxPartSize ,
121122 snapRepo : rbdRepo ,
123+ imageLocker : rbdRepo ,
122124 rawImgExpansionUnitSize : 100 * 1 << 20 ,
123125 }
124126 err = reconciler .SetupWithManager (mgr )
@@ -725,6 +727,7 @@ var _ = Describe("FinBackup Controller Reconcile Test", Ordered, func() {
725727 podImage : podImage ,
726728 maxPartSize : & defaultMaxPartSize ,
727729 snapRepo : rbdRepo ,
730+ imageLocker : rbdRepo ,
728731 rawImgExpansionUnitSize : 100 * 1 << 20 ,
729732 }
730733 })
@@ -1208,6 +1211,158 @@ var _ = Describe("FinBackup Controller Reconcile Test", Ordered, func() {
12081211 })
12091212})
12101213
1214+ var _ = Describe ("FinBackup Controller Unit Tests" , Ordered , func () {
1215+ Context ("lockVolume" , func () {
1216+ var reconciler * FinBackupReconciler
1217+ var rbdRepo * fake.RBDRepository2
1218+
1219+ lock := func (poolName , imageName , lockID string , rbdErr error ) (bool , error ) {
1220+ rbdRepo .SetError (rbdErr )
1221+ defer rbdRepo .SetError (nil )
1222+
1223+ locked , err := reconciler .lockVolume (poolName , imageName , lockID )
1224+ if err != nil {
1225+ return locked , err
1226+ }
1227+ // Check if the lock with lockID exists
1228+ locks , err := rbdRepo .LockLs (poolName , imageName )
1229+ if err != nil {
1230+ return locked , err
1231+ }
1232+ lockExists := false
1233+ for _ , lock := range locks {
1234+ if lock .LockID == lockID {
1235+ lockExists = true
1236+ break
1237+ }
1238+ }
1239+ Expect (locked ).To (Equal (lockExists ))
1240+ return locked , nil
1241+ }
1242+
1243+ It ("setup" , func (ctx SpecContext ) {
1244+ volumeInfo := & fake.VolumeInfo {
1245+ Namespace : utils .GetUniqueName ("ns-" ),
1246+ PVCName : utils .GetUniqueName ("pvc-" ),
1247+ PVName : utils .GetUniqueName ("pv-" ),
1248+ PoolName : rbdPoolName ,
1249+ ImageName : rbdImageName ,
1250+ }
1251+ rbdRepo = fake .NewRBDRepository2 (volumeInfo .PoolName , volumeInfo .ImageName )
1252+
1253+ mgr , err := ctrl .NewManager (cfg , ctrl.Options {Scheme : scheme .Scheme })
1254+ Expect (err ).ToNot (HaveOccurred ())
1255+ reconciler = & FinBackupReconciler {
1256+ Client : mgr .GetClient (),
1257+ Scheme : mgr .GetScheme (),
1258+ cephClusterNamespace : namespace ,
1259+ podImage : podImage ,
1260+ maxPartSize : & defaultMaxPartSize ,
1261+ snapRepo : rbdRepo ,
1262+ imageLocker : rbdRepo ,
1263+ rawImgExpansionUnitSize : 100 * 1 << 20 ,
1264+ }
1265+ })
1266+
1267+ It ("lock a volume successfully" , func () {
1268+ locked , err := lock ("pool" , "image1" , "lock1" , nil )
1269+ Expect (err ).NotTo (HaveOccurred ())
1270+ Expect (locked ).To (BeTrue ())
1271+ })
1272+ It ("lock a volume that is already locked by the same lockID" , func () {
1273+ locked , err := lock ("pool" , "image1" , "lock1" , nil )
1274+ Expect (err ).NotTo (HaveOccurred ())
1275+ Expect (locked ).To (BeTrue ())
1276+ })
1277+ It ("fail to lock a volume that is already locked by a different lockID" , func () {
1278+ locked , err := lock ("pool" , "image1" , "lock2" , nil )
1279+ Expect (err ).NotTo (HaveOccurred ())
1280+ Expect (locked ).To (BeFalse ())
1281+ })
1282+ It ("lock a different volume successfully" , func () {
1283+ locked , err := lock ("pool" , "image2" , "lock1" , nil )
1284+ Expect (err ).NotTo (HaveOccurred ())
1285+ Expect (locked ).To (BeTrue ())
1286+ })
1287+ It ("error when rbd lock ls fails" , func () {
1288+ locked , err := lock ("pool" , "image1" , "lock1" , errors .New ("rbd lock ls error" ))
1289+ Expect (err ).To (HaveOccurred ())
1290+ Expect (locked ).To (BeFalse ())
1291+ })
1292+ })
1293+
1294+ Context ("unlockVolume" , func () {
1295+ var reconciler * FinBackupReconciler
1296+ var rbdRepo * fake.RBDRepository2
1297+
1298+ It ("setup" , func (ctx SpecContext ) {
1299+ volumeInfo := & fake.VolumeInfo {
1300+ Namespace : utils .GetUniqueName ("ns-" ),
1301+ PVCName : utils .GetUniqueName ("pvc-" ),
1302+ PVName : utils .GetUniqueName ("pv-" ),
1303+ PoolName : rbdPoolName ,
1304+ ImageName : rbdImageName ,
1305+ }
1306+ rbdRepo = fake .NewRBDRepository2 (volumeInfo .PoolName , volumeInfo .ImageName )
1307+
1308+ mgr , err := ctrl .NewManager (cfg , ctrl.Options {Scheme : scheme .Scheme })
1309+ Expect (err ).ToNot (HaveOccurred ())
1310+ reconciler = & FinBackupReconciler {
1311+ Client : mgr .GetClient (),
1312+ Scheme : mgr .GetScheme (),
1313+ cephClusterNamespace : namespace ,
1314+ podImage : podImage ,
1315+ maxPartSize : & defaultMaxPartSize ,
1316+ snapRepo : rbdRepo ,
1317+ imageLocker : rbdRepo ,
1318+ rawImgExpansionUnitSize : 100 * 1 << 20 ,
1319+ }
1320+ })
1321+
1322+ It ("locks a volume" , func (ctx SpecContext ) {
1323+ locked , err := reconciler .lockVolume ("pool" , "image" , "lock1" )
1324+ Expect (err ).NotTo (HaveOccurred ())
1325+ Expect (locked ).To (BeTrue ())
1326+ })
1327+
1328+ DescribeTable ("" , func (
1329+ ctx SpecContext ,
1330+ poolName , imageName , lockID string , rbdErr error ,
1331+ expectErr bool ,
1332+ ) {
1333+ rbdRepo .SetError (rbdErr )
1334+ defer rbdRepo .SetError (nil )
1335+
1336+ err := reconciler .unlockVolume (poolName , imageName , lockID )
1337+ if expectErr {
1338+ Expect (err ).To (HaveOccurred ())
1339+ } else {
1340+ Expect (err ).NotTo (HaveOccurred ())
1341+ }
1342+ // Check if the lock is removed
1343+ locks , err := rbdRepo .LockLs (poolName , imageName )
1344+ if expectErr {
1345+ Expect (err ).To (HaveOccurred ())
1346+ } else {
1347+ Expect (err ).NotTo (HaveOccurred ())
1348+ for _ , l := range locks {
1349+ Expect (l .LockID ).NotTo (Equal (lockID ))
1350+ }
1351+ }
1352+ },
1353+ Entry ("unlock a volume successfully" ,
1354+ "pool" , "image" , "lock1" , nil ,
1355+ false ),
1356+ Entry ("unlock the same volume again (no-op)" ,
1357+ "pool" , "image" , "lock1" , nil ,
1358+ false ),
1359+ Entry ("error when rbd unlock fails" ,
1360+ "pool" , "image" , "lock1" , errors .New ("rbd unlock error" ),
1361+ true ),
1362+ )
1363+ })
1364+ })
1365+
12111366// CSATEST-1627
12121367// Description:
12131368//
0 commit comments