@@ -1325,3 +1325,143 @@ func TestValidate(t *testing.T) {
13251325 })
13261326 }
13271327}
1328+
1329+ func TestSyncSuspend (t * testing.T ) {
1330+ errClientGet := fmt .Errorf ("connection refused" )
1331+ errClientPatch := fmt .Errorf ("patch failed" )
1332+
1333+ cases := map [string ]struct {
1334+ trainJob * trainer.TrainJob
1335+ existingJobSet * jobsetv1alpha2.JobSet
1336+ clientGetErr error
1337+ clientPatchErr error
1338+ wantError error
1339+ wantSuspend * bool
1340+ }{
1341+ "patch JobSet suspend to true when TrainJob is suspended but JobSet is not" : {
1342+ trainJob : utiltesting .MakeTrainJobWrapper (metav1 .NamespaceDefault , "test" ).
1343+ Suspend (true ).
1344+ Obj (),
1345+ existingJobSet : utiltesting .MakeJobSetWrapper (metav1 .NamespaceDefault , "test" ).
1346+ Suspend (false ).
1347+ Obj (),
1348+ wantSuspend : ptr .To (true ),
1349+ },
1350+ "patch JobSet suspend to false when TrainJob is not suspended but JobSet is" : {
1351+ trainJob : utiltesting .MakeTrainJobWrapper (metav1 .NamespaceDefault , "test" ).
1352+ Suspend (false ).
1353+ Obj (),
1354+ existingJobSet : utiltesting .MakeJobSetWrapper (metav1 .NamespaceDefault , "test" ).
1355+ Suspend (true ).
1356+ Obj (),
1357+ wantSuspend : ptr .To (false ),
1358+ },
1359+ "no patch when both TrainJob and JobSet are suspended" : {
1360+ trainJob : utiltesting .MakeTrainJobWrapper (metav1 .NamespaceDefault , "test" ).
1361+ Suspend (true ).
1362+ Obj (),
1363+ existingJobSet : utiltesting .MakeJobSetWrapper (metav1 .NamespaceDefault , "test" ).
1364+ Suspend (true ).
1365+ Obj (),
1366+ wantSuspend : ptr .To (true ),
1367+ },
1368+ "no patch when both TrainJob and JobSet are not suspended" : {
1369+ trainJob : utiltesting .MakeTrainJobWrapper (metav1 .NamespaceDefault , "test" ).
1370+ Suspend (false ).
1371+ Obj (),
1372+ existingJobSet : utiltesting .MakeJobSetWrapper (metav1 .NamespaceDefault , "test" ).
1373+ Suspend (false ).
1374+ Obj (),
1375+ wantSuspend : ptr .To (false ),
1376+ },
1377+ "patch JobSet suspend to false when TrainJob suspend is nil and JobSet is suspended" : {
1378+ trainJob : utiltesting .MakeTrainJobWrapper (metav1 .NamespaceDefault , "test" ).
1379+ Obj (),
1380+ existingJobSet : utiltesting .MakeJobSetWrapper (metav1 .NamespaceDefault , "test" ).
1381+ Suspend (true ).
1382+ Obj (),
1383+ wantSuspend : ptr .To (false ),
1384+ },
1385+ "return nil when JobSet is not found" : {
1386+ trainJob : utiltesting .MakeTrainJobWrapper (metav1 .NamespaceDefault , "test" ).
1387+ Suspend (true ).
1388+ Obj (),
1389+ existingJobSet : nil ,
1390+ wantError : nil ,
1391+ },
1392+ "return error when client Get fails" : {
1393+ trainJob : utiltesting .MakeTrainJobWrapper (metav1 .NamespaceDefault , "test" ).
1394+ Suspend (true ).
1395+ Obj (),
1396+ existingJobSet : utiltesting .MakeJobSetWrapper (metav1 .NamespaceDefault , "test" ).
1397+ Suspend (false ).
1398+ Obj (),
1399+ clientGetErr : errClientGet ,
1400+ wantError : errClientGet ,
1401+ },
1402+ "return wrapped error when client Patch fails" : {
1403+ trainJob : utiltesting .MakeTrainJobWrapper (metav1 .NamespaceDefault , "test" ).
1404+ Suspend (true ).
1405+ Obj (),
1406+ existingJobSet : utiltesting .MakeJobSetWrapper (metav1 .NamespaceDefault , "test" ).
1407+ Suspend (false ).
1408+ Obj (),
1409+ clientPatchErr : errClientPatch ,
1410+ wantError : errClientPatch ,
1411+ },
1412+ }
1413+
1414+ for name , tc := range cases {
1415+ t .Run (name , func (t * testing.T ) {
1416+ _ , ctx := ktesting .NewTestContext (t )
1417+ var cancel func ()
1418+ ctx , cancel = context .WithCancel (ctx )
1419+ t .Cleanup (cancel )
1420+
1421+ clientBuilder := utiltesting .NewClientBuilder ()
1422+ if tc .existingJobSet != nil {
1423+ clientBuilder = clientBuilder .WithObjects (tc .existingJobSet )
1424+ }
1425+ if tc .clientGetErr != nil || tc .clientPatchErr != nil {
1426+ clientBuilder = clientBuilder .WithInterceptorFuncs (interceptor.Funcs {
1427+ Get : func (ctx context.Context , cli client.WithWatch , key client.ObjectKey , obj client.Object , opts ... client.GetOption ) error {
1428+ if tc .clientGetErr != nil {
1429+ if _ , ok := obj .(* jobsetv1alpha2.JobSet ); ok {
1430+ return tc .clientGetErr
1431+ }
1432+ }
1433+ return cli .Get (ctx , key , obj , opts ... )
1434+ },
1435+ Patch : func (ctx context.Context , cli client.WithWatch , obj client.Object , patch client.Patch , opts ... client.PatchOption ) error {
1436+ if tc .clientPatchErr != nil {
1437+ if _ , ok := obj .(* jobsetv1alpha2.JobSet ); ok {
1438+ return tc .clientPatchErr
1439+ }
1440+ }
1441+ return cli .Patch (ctx , obj , patch , opts ... )
1442+ },
1443+ })
1444+ }
1445+ cli := clientBuilder .Build ()
1446+
1447+ p , err := New (ctx , cli , nil )
1448+ if err != nil {
1449+ t .Fatalf ("Failed to initialize JobSet plugin: %v" , err )
1450+ }
1451+
1452+ err = p .(* JobSet ).SyncSuspend (ctx , tc .trainJob )
1453+ if diff := cmp .Diff (tc .wantError , err , cmpopts .EquateErrors ()); len (diff ) != 0 {
1454+ t .Errorf ("Unexpected error (-want,+got):\n %s" , diff )
1455+ }
1456+ if tc .wantError == nil && tc .existingJobSet != nil && tc .wantSuspend != nil {
1457+ jobSet := & jobsetv1alpha2.JobSet {}
1458+ if err := cli .Get (ctx , client .ObjectKeyFromObject (tc .trainJob ), jobSet ); err != nil {
1459+ t .Fatalf ("Failed to get JobSet: %v" , err )
1460+ }
1461+ if diff := cmp .Diff (tc .wantSuspend , jobSet .Spec .Suspend ); len (diff ) != 0 {
1462+ t .Errorf ("Unexpected JobSet suspend state (-want,+got):\n %s" , diff )
1463+ }
1464+ }
1465+ })
1466+ }
1467+ }
0 commit comments