@VisibleForTesting
  List<WorkflowRollupOverview> getForeachAndSubworkflowStepRollups(
      String workflowId,
      long workflowInstanceId,
      Map<String, Long> stepIdRunIdForeachSubworkflowPrevious) {
    List<WorkflowRollupOverview> rollupOverviewsForForeachAndSubworkflow = new ArrayList<>();
    if (stepIdRunIdForeachSubworkflowPrevious == null
        || stepIdRunIdForeachSubworkflowPrevious.isEmpty()) {
      return rollupOverviewsForForeachAndSubworkflow;
    }

    List<Map<String, Artifact>> artifacts =
        stepInstanceDao.getBatchStepInstancesArtifactsFromList(
            workflowId, workflowInstanceId, stepIdRunIdForeachSubworkflowPrevious);

    for (Map<String, Artifact> artifact : artifacts) {
      if (artifact.containsKey(Artifact.Type.SUBWORKFLOW.key())) {
        SubworkflowArtifact subworkflowArtifact =
            artifact.get(Artifact.Type.SUBWORKFLOW.key()).asSubworkflow();
        if (subworkflowArtifact.getSubworkflowOverview() != null) {
          rollupOverviewsForForeachAndSubworkflow.add(
              subworkflowArtifact.getSubworkflowOverview().getRollupOverview());
        }
      }

      if (artifact.containsKey(Artifact.Type.FOREACH.key())) {
        ForeachArtifact foreachArtifact = artifact.get(Artifact.Type.FOREACH.key()).asForeach();
        if (foreachArtifact.getForeachOverview() != null
            && foreachArtifact.getForeachOverview().getCheckpoint() > 0) {
          rollupOverviewsForForeachAndSubworkflow.add(
              foreachArtifact.getForeachOverview().getOverallRollup());
        }
      }
    }

    return rollupOverviewsForForeachAndSubworkflow;
  }
@Test
  public void testGetForeachAndSubworkflowStepRollups() throws IOException {
    ArtifactMap artifacts =
        loadObject("fixtures/artifact/sample-artifacts.json", ArtifactMap.class);

    artifacts.getArtifacts().remove("artifact1");
    artifacts.getArtifacts().remove("artifact2");

    String workflowId = "test_workflow_id";
    long workflowInstanceId = 2L;

    Map<String, Long> stepIdToRunId = new HashMap<>();
    stepIdToRunId.put("maestro_subworkflow", 1L);
    stepIdToRunId.put("maestro_foreach", 1L);

    doReturn(Collections.singletonList(artifacts.getArtifacts()))
        .when(stepInstanceDao)
        .getBatchStepInstancesArtifactsFromList(workflowId, workflowInstanceId, stepIdToRunId);

    RollupAggregationHelper rollupAggregationHelper = new RollupAggregationHelper(stepInstanceDao);

    List<WorkflowRollupOverview> rollups =
        rollupAggregationHelper.getForeachAndSubworkflowStepRollups(
            workflowId, workflowInstanceId, stepIdToRunId);

    assertEquals(2, rollups.size());
    assertEquals(29, rollups.get(0).getTotalLeafCount());
    assertEquals(2, rollups.get(0).getOverview().size());
    assertEquals(14, rollups.get(1).getTotalLeafCount());
    assertEquals(2, rollups.get(1).getOverview().size());

    // passing null stepIdToRunId
    rollups =
        this.rollupAggregationHelper.getForeachAndSubworkflowStepRollups(
            workflowId, workflowInstanceId, null);
    assertTrue(rollups.isEmpty());

    // passing empty stepIdToRunId
    rollups =
        this.rollupAggregationHelper.getForeachAndSubworkflowStepRollups(
            workflowId, workflowInstanceId, new HashMap<>());
    assertTrue(rollups.isEmpty());
  }