Object getFromSubworkflow(String subworkflowStepId, String stepId, String paramName) {
    try {
      return executor
          .submit(() -> fromSubworkflow(subworkflowStepId, stepId, paramName))
          .get(TIMEOUT_IN_MILLIS, TimeUnit.MILLISECONDS);
    } catch (Exception e) {
      throw new MaestroInternalError(
          e,
          "getFromSubworkflow throws an exception for subworkflowStepId=[%s], stepId=[%s], paramName=[%s]",
          subworkflowStepId,
          stepId,
          paramName);
    }
  }
@Test
  public void testInvalidGetFromSubworkflow() throws Exception {
    AssertHelper.assertThrows(
        "Cannot find the referenced step id",
        MaestroInternalError.class,
        "getFromSubworkflow throws an exception",
        () -> paramExtension.getFromSubworkflow("non-existing-job", "job1", "sleep_seconds"));

    StepRuntimeSummary summary = loadObject(TEST_STEP_RUNTIME_SUMMARY, StepRuntimeSummary.class);
    when(allStepOutputData.get("foo"))
        .thenReturn(Collections.singletonMap("maestro_step_runtime_summary", summary));
    AssertHelper.assertThrows(
        "step type is not subworkflow",
        MaestroInternalError.class,
        "getFromSubworkflow throws an exception",
        () -> paramExtension.getFromSubworkflow("foo", "job1", "sleep_seconds"));

    summary = loadObject(TEST_SUBWORKFLOW_STEP_RUNTIME_SUMMARY, StepRuntimeSummary.class);
    when(allStepOutputData.get("foo"))
        .thenReturn(Collections.singletonMap("maestro_step_runtime_summary", summary));
    StepInstance stepInSubworkflow = loadObject(TEST_STEP_INSTANCE, StepInstance.class);
    when(stepInstanceDao.getStepInstance(any(), anyLong(), anyLong(), any(), any()))
        .thenReturn(stepInSubworkflow);
    AssertHelper.assertThrows(
        "param name does not exist",
        MaestroInternalError.class,
        "getFromSubworkflow throws an exception",
        () -> paramExtension.getFromSubworkflow("foo", "job1", "not-existing"));
  }