@@ -1258,6 +1258,11 @@ func TestResolveSubTask(t *testing.T) {
12581258 require .NotNil (t , res )
12591259 assert .Equal (t , resolution .StateWaiting , res .State )
12601260
1261+ nextRetryBeforeRun := time.Time {}
1262+ if res .NextRetry != nil {
1263+ nextRetryBeforeRun = * res .NextRetry
1264+ }
1265+
12611266 for _ , subtaskName := range []string {"subtaskCreation" , "jsonInputSubtask" , "templatingJsonInputSubtask" } {
12621267 subtaskCreationOutput := res .Steps [subtaskName ].Output .(map [string ]interface {})
12631268 subtaskPublicID := subtaskCreationOutput ["id" ].(string )
@@ -1285,27 +1290,25 @@ func TestResolveSubTask(t *testing.T) {
12851290 assert .Equal (t , res .TaskID , parentTaskToResume .ID )
12861291 }
12871292
1288- // checking if the parent task is picked up after that the subtask is resolved.
1289- // need to sleep a bit because the parent task is resumed asynchronously
1290- ti := time .Second
1291- i := time .Duration (0 )
1292- for i < ti {
1293- res , err = resolution .LoadFromPublicID (dbp , res .PublicID )
1294- require .Nil (t , err )
1295- if res .State != resolution .StateWaiting {
1296- break
1297- }
1293+ // checking whether the parent task will be picked up by the RetryCollector after the subtask is resolved.
1294+ res , err = resolution .LoadFromPublicID (dbp , res .PublicID )
1295+ require .Nil (t , err )
1296+ assert .NotNil (t , res .NextRetry )
1297+ assert .False (t , res .NextRetry .IsZero ())
1298+ assert .True (t , res .NextRetry .After (nextRetryBeforeRun ))
1299+ assert .True (t , res .NextRetry .Before (time .Now ()))
12981300
1299- time .Sleep (time .Millisecond * 10 )
1300- i += time .Millisecond * 10
1301- }
1301+ // Starting the RetryCollector to resume the parent task
1302+ ctx , cancelFunc := context .WithCancel (context .Background ())
1303+ defer cancelFunc ()
1304+ engine .RetryCollector (ctx )
13021305
1303- ti = time .Second
1304- i = time .Duration (0 )
1306+ ti : = time .Second
1307+ i : = time .Duration (0 )
13051308 for i < ti {
13061309 res , err = resolution .LoadFromPublicID (dbp , res .PublicID )
13071310 require .Nil (t , err )
1308- if res .State != resolution .StateRunning {
1311+ if res .State == resolution .StateDone {
13091312 break
13101313 }
13111314
@@ -1409,6 +1412,11 @@ func TestBatch(t *testing.T) {
14091412 require .NotNil (t , res )
14101413 assert .Equal (t , resolution .StateWaiting , res .State )
14111414
1415+ nextRetryBeforeRun := time.Time {}
1416+ if res .NextRetry != nil {
1417+ nextRetryBeforeRun = * res .NextRetry
1418+ }
1419+
14121420 for _ , batchStepName := range []string {"batchJsonInputs" , "batchYamlInputs" } {
14131421 batchStepMetadataRaw , ok := res .Steps [batchStepName ].Metadata .(string )
14141422 assert .True (t , ok , "wrong type of metadata for step '%s'" , batchStepName )
@@ -1463,32 +1471,79 @@ func TestBatch(t *testing.T) {
14631471 }
14641472 }
14651473
1466- // checking if the parent task is picked up after the subtask is resolved.
1467- // We need to sleep a bit because the parent task is resumed asynchronously
1474+ // checking whether the parent task will be picked up by the RetryCollector after the subtask is resolved.
1475+ res , err = resolution .LoadFromPublicID (dbp , res .PublicID )
1476+ require .Nil (t , err )
1477+ assert .NotNil (t , res .NextRetry )
1478+ assert .False (t , res .NextRetry .IsZero ())
1479+ assert .True (t , res .NextRetry .After (nextRetryBeforeRun ))
1480+ assert .True (t , res .NextRetry .Before (time .Now ()))
1481+
1482+ // Starting the RetryCollector to resume the parent task
1483+ ctx , cancelFunc := context .WithCancel (context .Background ())
1484+ defer cancelFunc ()
1485+ engine .RetryCollector (ctx )
1486+
14681487 ti := time .Second
14691488 i := time .Duration (0 )
14701489 for i < ti {
14711490 res , err = resolution .LoadFromPublicID (dbp , res .PublicID )
14721491 require .Nil (t , err )
1473- if res .State != resolution .StateWaiting {
1492+ if res .State == resolution .StateDone {
14741493 break
14751494 }
14761495
14771496 time .Sleep (time .Millisecond * 10 )
14781497 i += time .Millisecond * 10
14791498 }
1499+ assert .Equal (t , resolution .StateDone , res .State )
1500+ }
14801501
1481- ti = time .Second
1482- i = time .Duration (0 )
1483- for i < ti {
1484- res , err = resolution .LoadFromPublicID (dbp , res .PublicID )
1485- require .Nil (t , err )
1486- if res .State != resolution .StateRunning {
1487- break
1488- }
1502+ func TestWakeParent (t * testing.T ) {
1503+ dbp , err := zesty .NewDBProvider (utask .DBName )
1504+ require .Nil (t , err )
14891505
1490- time .Sleep (time .Millisecond * 10 )
1491- i += time .Millisecond * 10
1492- }
1493- assert .Equal (t , resolution .StateDone , res .State )
1506+ // Create a task that spawns two simple subtasks
1507+ _ , err = templateFromYAML (dbp , "no-output.yaml" )
1508+ require .Nil (t , err )
1509+
1510+ res , err := createResolution ("noOutputSubtask.yaml" , map [string ]interface {}{}, nil )
1511+ require .Nil (t , err , "failed to create resolution: %s" , err )
1512+
1513+ res , err = runResolution (res )
1514+ require .Nil (t , err )
1515+ require .NotNil (t , res )
1516+ require .Equal (t , resolution .StateWaiting , res .State )
1517+ assert .True (t , res .NextRetry .IsZero ())
1518+
1519+ // Force the parent task to the RUNNING state
1520+ res .SetState (resolution .StateRunning )
1521+ res .Update (dbp )
1522+
1523+ // Create and run one of the subtasks
1524+ subtaskCreationOutput := res .Steps ["subtaskCreation" ].Output .(map [string ]interface {})
1525+ subtaskPublicID := subtaskCreationOutput ["id" ].(string )
1526+
1527+ subtask , err := task .LoadFromPublicID (dbp , subtaskPublicID )
1528+ require .Nil (t , err )
1529+ require .Equal (t , task .StateTODO , subtask .State )
1530+
1531+ subtaskResolution , err := resolution .Create (dbp , subtask , nil , "" , false , nil )
1532+ require .Nil (t , err )
1533+
1534+ beforeRun := time .Now ()
1535+ subtaskResolution , err = runResolution (subtaskResolution )
1536+ require .Nil (t , err )
1537+ require .Equal (t , task .StateDone , subtaskResolution .State )
1538+ afterRun := time .Now ()
1539+
1540+ // Refreshing parent resolution to check its next_retry value
1541+ res , err = resolution .LoadFromPublicID (dbp , res .PublicID )
1542+ require .Nil (t , err )
1543+ assert .Equal (t , res .State , resolution .StateRunning ) // Parent should still be RUNNING
1544+
1545+ // The parent's next_retry should have been updated so that the RetryCollector would pick it up
1546+ assert .NotNil (t , res .NextRetry )
1547+ assert .True (t , res .NextRetry .After (beforeRun ))
1548+ assert .True (t , res .NextRetry .Before (afterRun ))
14941549}
0 commit comments