@@ -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 )
@@ -766,6 +768,7 @@ var _ = Describe("FinBackup Controller Reconcile Test", Ordered, func() {
766768 podImage : podImage ,
767769 maxPartSize : & defaultMaxPartSize ,
768770 snapRepo : rbdRepo ,
771+ imageLocker : rbdRepo ,
769772 rawImgExpansionUnitSize : 100 * 1 << 20 ,
770773 }
771774 })
@@ -1249,6 +1252,158 @@ var _ = Describe("FinBackup Controller Reconcile Test", Ordered, func() {
12491252 })
12501253})
12511254
1255+ var _ = Describe ("FinBackup Controller Unit Tests" , Ordered , func () {
1256+ Context ("lockVolume" , func () {
1257+ var reconciler * FinBackupReconciler
1258+ var rbdRepo * fake.RBDRepository2
1259+
1260+ lock := func (poolName , imageName , lockID string , rbdErr error ) (bool , error ) {
1261+ rbdRepo .SetError (rbdErr )
1262+ defer rbdRepo .SetError (nil )
1263+
1264+ locked , err := reconciler .lockVolume (poolName , imageName , lockID )
1265+ if err != nil {
1266+ return locked , err
1267+ }
1268+ // Check if the lock with lockID exists
1269+ locks , err := rbdRepo .LockLs (poolName , imageName )
1270+ if err != nil {
1271+ return locked , err
1272+ }
1273+ lockExists := false
1274+ for _ , lock := range locks {
1275+ if lock .LockID == lockID {
1276+ lockExists = true
1277+ break
1278+ }
1279+ }
1280+ Expect (locked ).To (Equal (lockExists ))
1281+ return locked , nil
1282+ }
1283+
1284+ It ("setup" , func (ctx SpecContext ) {
1285+ volumeInfo := & fake.VolumeInfo {
1286+ Namespace : utils .GetUniqueName ("ns-" ),
1287+ PVCName : utils .GetUniqueName ("pvc-" ),
1288+ PVName : utils .GetUniqueName ("pv-" ),
1289+ PoolName : rbdPoolName ,
1290+ ImageName : rbdImageName ,
1291+ }
1292+ rbdRepo = fake .NewRBDRepository2 (volumeInfo .PoolName , volumeInfo .ImageName )
1293+
1294+ mgr , err := ctrl .NewManager (cfg , ctrl.Options {Scheme : scheme .Scheme })
1295+ Expect (err ).ToNot (HaveOccurred ())
1296+ reconciler = & FinBackupReconciler {
1297+ Client : mgr .GetClient (),
1298+ Scheme : mgr .GetScheme (),
1299+ cephClusterNamespace : namespace ,
1300+ podImage : podImage ,
1301+ maxPartSize : & defaultMaxPartSize ,
1302+ snapRepo : rbdRepo ,
1303+ imageLocker : rbdRepo ,
1304+ rawImgExpansionUnitSize : 100 * 1 << 20 ,
1305+ }
1306+ })
1307+
1308+ It ("lock a volume successfully" , func () {
1309+ locked , err := lock ("pool" , "image1" , "lock1" , nil )
1310+ Expect (err ).NotTo (HaveOccurred ())
1311+ Expect (locked ).To (BeTrue ())
1312+ })
1313+ It ("lock a volume that is already locked by the same lockID" , func () {
1314+ locked , err := lock ("pool" , "image1" , "lock1" , nil )
1315+ Expect (err ).NotTo (HaveOccurred ())
1316+ Expect (locked ).To (BeTrue ())
1317+ })
1318+ It ("fail to lock a volume that is already locked by a different lockID" , func () {
1319+ locked , err := lock ("pool" , "image1" , "lock2" , nil )
1320+ Expect (err ).NotTo (HaveOccurred ())
1321+ Expect (locked ).To (BeFalse ())
1322+ })
1323+ It ("lock a different volume successfully" , func () {
1324+ locked , err := lock ("pool" , "image2" , "lock1" , nil )
1325+ Expect (err ).NotTo (HaveOccurred ())
1326+ Expect (locked ).To (BeTrue ())
1327+ })
1328+ It ("error when rbd lock ls fails" , func () {
1329+ locked , err := lock ("pool" , "image1" , "lock1" , errors .New ("rbd lock ls error" ))
1330+ Expect (err ).To (HaveOccurred ())
1331+ Expect (locked ).To (BeFalse ())
1332+ })
1333+ })
1334+
1335+ Context ("unlockVolume" , func () {
1336+ var reconciler * FinBackupReconciler
1337+ var rbdRepo * fake.RBDRepository2
1338+
1339+ It ("setup" , func (ctx SpecContext ) {
1340+ volumeInfo := & fake.VolumeInfo {
1341+ Namespace : utils .GetUniqueName ("ns-" ),
1342+ PVCName : utils .GetUniqueName ("pvc-" ),
1343+ PVName : utils .GetUniqueName ("pv-" ),
1344+ PoolName : rbdPoolName ,
1345+ ImageName : rbdImageName ,
1346+ }
1347+ rbdRepo = fake .NewRBDRepository2 (volumeInfo .PoolName , volumeInfo .ImageName )
1348+
1349+ mgr , err := ctrl .NewManager (cfg , ctrl.Options {Scheme : scheme .Scheme })
1350+ Expect (err ).ToNot (HaveOccurred ())
1351+ reconciler = & FinBackupReconciler {
1352+ Client : mgr .GetClient (),
1353+ Scheme : mgr .GetScheme (),
1354+ cephClusterNamespace : namespace ,
1355+ podImage : podImage ,
1356+ maxPartSize : & defaultMaxPartSize ,
1357+ snapRepo : rbdRepo ,
1358+ imageLocker : rbdRepo ,
1359+ rawImgExpansionUnitSize : 100 * 1 << 20 ,
1360+ }
1361+ })
1362+
1363+ It ("locks a volume" , func (ctx SpecContext ) {
1364+ locked , err := reconciler .lockVolume ("pool" , "image" , "lock1" )
1365+ Expect (err ).NotTo (HaveOccurred ())
1366+ Expect (locked ).To (BeTrue ())
1367+ })
1368+
1369+ DescribeTable ("" , func (
1370+ ctx SpecContext ,
1371+ poolName , imageName , lockID string , rbdErr error ,
1372+ expectErr bool ,
1373+ ) {
1374+ rbdRepo .SetError (rbdErr )
1375+ defer rbdRepo .SetError (nil )
1376+
1377+ err := reconciler .unlockVolume (poolName , imageName , lockID )
1378+ if expectErr {
1379+ Expect (err ).To (HaveOccurred ())
1380+ } else {
1381+ Expect (err ).NotTo (HaveOccurred ())
1382+ }
1383+ // Check if the lock is removed
1384+ locks , err := rbdRepo .LockLs (poolName , imageName )
1385+ if expectErr {
1386+ Expect (err ).To (HaveOccurred ())
1387+ } else {
1388+ Expect (err ).NotTo (HaveOccurred ())
1389+ for _ , l := range locks {
1390+ Expect (l .LockID ).NotTo (Equal (lockID ))
1391+ }
1392+ }
1393+ },
1394+ Entry ("unlock a volume successfully" ,
1395+ "pool" , "image" , "lock1" , nil ,
1396+ false ),
1397+ Entry ("unlock the same volume again (no-op)" ,
1398+ "pool" , "image" , "lock1" , nil ,
1399+ false ),
1400+ Entry ("error when rbd unlock fails" ,
1401+ "pool" , "image" , "lock1" , errors .New ("rbd unlock error" ),
1402+ true ),
1403+ )
1404+ })
1405+ })
1406+
12521407// CSATEST-1627
12531408// Description:
12541409//
0 commit comments