@@ -200,6 +200,7 @@ var _ = Describe("MantleBackup controller", func() {
200200 resMgr .ClusterID ,
201201 RoleStandalone ,
202202 nil ,
203+ nil ,
203204 "dummy image" ,
204205 "" ,
205206 nil ,
@@ -455,6 +456,7 @@ var _ = Describe("MantleBackup controller", func() {
455456 Client : grpcClient ,
456457 ExportDataStorageClass : resMgr .StorageClassName ,
457458 },
459+ nil ,
458460 "dummy image" ,
459461 "dummy-secret-env" ,
460462 & ObjectStorageSettings {
@@ -979,7 +981,7 @@ var _ = Describe("prepareForDataSynchronization", func() {
979981 }
980982
981983 mbr := NewMantleBackupReconciler (ctrlClient ,
982- ctrlClient .Scheme (), "test" , RolePrimary , nil , "dummy image" , "" , nil , nil , resource .MustParse ("1Gi" ))
984+ ctrlClient .Scheme (), "test" , RolePrimary , nil , nil , "dummy image" , "" , nil , nil , resource .MustParse ("1Gi" ))
983985
984986 ret , err := mbr .prepareForDataSynchronization (context .Background (),
985987 backup , grpcClient )
@@ -1516,6 +1518,7 @@ var _ = Describe("export and upload", func() {
15161518 ExportDataStorageClass : resMgr .StorageClassName ,
15171519 MaxExportJobs : 1 ,
15181520 },
1521+ nil ,
15191522 "dummy image" ,
15201523 "dummy-secret" ,
15211524 & ObjectStorageSettings {},
@@ -1606,6 +1609,7 @@ var _ = Describe("export and upload", func() {
16061609 ExportDataStorageClass : resMgr .StorageClassName ,
16071610 MaxExportJobs : 1 ,
16081611 },
1612+ nil ,
16091613 "dummy image" ,
16101614 "" ,
16111615 nil ,
@@ -1759,6 +1763,7 @@ var _ = Describe("import", func() {
17591763 nsController ,
17601764 RoleSecondary ,
17611765 nil ,
1766+ nil ,
17621767 "dummy-image" ,
17631768 "dummy-env-secret" ,
17641769 & ObjectStorageSettings {},
@@ -1777,6 +1782,32 @@ var _ = Describe("import", func() {
17771782 }
17781783 })
17791784
1785+ createAndReconcileImportJob := func (
1786+ ctx SpecContext ,
1787+ mbr * MantleBackupReconciler ,
1788+ name , ns string ,
1789+ ) {
1790+ GinkgoHelper ()
1791+
1792+ target , err := createMantleBackupUsingDummyPVC (ctx , name , ns )
1793+ Expect (err ).NotTo (HaveOccurred ())
1794+
1795+ err = updateStatus (ctx , k8sClient , target , func () error {
1796+ target .Status .SnapSize = ptr .To (int64 (testutil .FakeRBDSnapshotSize ))
1797+ transferPartSize := resource .MustParse ("1Gi" )
1798+ target .Status .TransferPartSize = & transferPartSize
1799+
1800+ return nil
1801+ })
1802+ Expect (err ).NotTo (HaveOccurred ())
1803+
1804+ snapshotTarget , err := getSnapshotTargetByDummyMB (target )
1805+ Expect (err ).NotTo (HaveOccurred ())
1806+
1807+ _ , err = mbr .reconcileImportJob (ctx , target , snapshotTarget , - 1 )
1808+ Expect (err ).NotTo (HaveOccurred ())
1809+ }
1810+
17801811 DescribeTable ("isExportDataAlreadyUploaded: inputs and outputs" ,
17811812 func (ctx SpecContext , gotExist , gotError , expectUploaded , expectError bool ) {
17821813 mockObjectStorage .EXPECT ().Exists (gomock .Any (), gomock .Eq ("name-uid-0.bin" )).DoAndReturn (
@@ -1858,6 +1889,88 @@ var _ = Describe("import", func() {
18581889 })
18591890 })
18601891
1892+ Context ("import job throttling" , func () {
1893+ It ("should throttle import jobs correctly" , func (ctx SpecContext ) {
1894+ nsController = resMgr .CreateNamespace ()
1895+ mbr = NewMantleBackupReconciler (
1896+ k8sClient ,
1897+ scheme .Scheme ,
1898+ nsController ,
1899+ RoleSecondary ,
1900+ nil ,
1901+ & SecondarySettings {
1902+ MaxImportJobs : 1 ,
1903+ },
1904+ "dummy-image" ,
1905+ "dummy-env-secret" ,
1906+ & ObjectStorageSettings {},
1907+ nil ,
1908+ resource .MustParse ("1Gi" ),
1909+ )
1910+ mbr .objectStorageClient = mockObjectStorage
1911+ mbr .ceph = testutil .NewFakeRBD ()
1912+
1913+ getNumOfImportJobs := func (ns string ) (int , error ) {
1914+ var jobs batchv1.JobList
1915+ err := k8sClient .List (ctx , & jobs , & client.ListOptions {
1916+ Namespace : ns ,
1917+ LabelSelector : labels .SelectorFromSet (map [string ]string {
1918+ "app.kubernetes.io/name" : labelAppNameValue ,
1919+ "app.kubernetes.io/component" : labelComponentImportJob ,
1920+ }),
1921+ })
1922+
1923+ return len (jobs .Items ), err
1924+ }
1925+
1926+ mockObjectStorage .EXPECT ().Exists (gomock .Any (), gomock .Any ()).
1927+ Return (true , nil ).AnyTimes ()
1928+
1929+ // create 5 different MantleBackup resources and call reconcileImportJob for each of them
1930+ for i := range 5 {
1931+ createAndReconcileImportJob (ctx , mbr , fmt .Sprintf ("target1-%d" , i ), ns )
1932+ }
1933+
1934+ // make sure that only 1 Job is created
1935+ Consistently (ctx , func (g Gomega ) error {
1936+ numJobs , err := getNumOfImportJobs (nsController )
1937+ g .Expect (err ).NotTo (HaveOccurred ())
1938+ g .Expect (numJobs ).To (Equal (1 ))
1939+
1940+ return nil
1941+ }, "1s" ).Should (Succeed ())
1942+
1943+ // make sure that another mantle-controller existing in a different namespace can create an import Job
1944+ nsController2 := resMgr .CreateNamespace ()
1945+ mbr2 := NewMantleBackupReconciler (
1946+ k8sClient ,
1947+ scheme .Scheme ,
1948+ nsController2 ,
1949+ RoleSecondary ,
1950+ nil ,
1951+ & SecondarySettings {
1952+ MaxImportJobs : 1 ,
1953+ },
1954+ "dummy-image" ,
1955+ "dummy-env-secret" ,
1956+ & ObjectStorageSettings {},
1957+ nil ,
1958+ resource .MustParse ("1Gi" ),
1959+ )
1960+ mbr2 .objectStorageClient = mockObjectStorage
1961+ mbr2 .ceph = testutil .NewFakeRBD ()
1962+ ns2 := resMgr .CreateNamespace ()
1963+ createAndReconcileImportJob (ctx , mbr2 , "target2" , ns2 )
1964+ Eventually (ctx , func (g Gomega ) error {
1965+ numJobs , err := getNumOfImportJobs (nsController2 )
1966+ g .Expect (err ).NotTo (HaveOccurred ())
1967+ g .Expect (numJobs ).To (Equal (1 ))
1968+
1969+ return nil
1970+ }).Should (Succeed ())
1971+ })
1972+ })
1973+
18611974 Context ("markSecondarySnapshotCaptured" , func () {
18621975 It ("should work correctly" , func (ctx SpecContext ) {
18631976 backup , err := createMantleBackupUsingDummyPVC (ctx , "target" , ns )
@@ -2580,7 +2693,7 @@ var _ = Describe("MantleBackupReconciler", func() {
25802693 }
25812694
25822695 It ("setup" , func (ctx SpecContext ) {
2583- reconciler = NewMantleBackupReconciler (nil , nil , "" , "" , nil , "" , "" , nil , nil , resource.Quantity {})
2696+ reconciler = NewMantleBackupReconciler (nil , nil , "" , "" , nil , nil , "" , "" , nil , nil , resource.Quantity {})
25842697 cephCmd = testutil .NewFakeRBD ()
25852698 reconciler .ceph = cephCmd
25862699 })
@@ -2617,7 +2730,7 @@ var _ = Describe("MantleBackupReconciler", func() {
26172730 var cephCmd * testutil.FakeRBD
26182731
26192732 It ("setup" , func (ctx SpecContext ) {
2620- reconciler = NewMantleBackupReconciler (nil , nil , "" , "" , nil , "" , "" , nil , nil , resource.Quantity {})
2733+ reconciler = NewMantleBackupReconciler (nil , nil , "" , "" , nil , nil , "" , "" , nil , nil , resource.Quantity {})
26212734 cephCmd = testutil .NewFakeRBD ()
26222735 reconciler .ceph = cephCmd
26232736 })
@@ -2834,6 +2947,7 @@ set -eux -o pipefail
28342947 podNamespace ,
28352948 "" , // unused
28362949 nil , // unused
2950+ nil , // unused
28372951 podImage ,
28382952 "" , // unused
28392953 nil , // unused
0 commit comments