public static String[][] assignExecutors(
      List<? extends ScanTaskGroup<?>> taskGroups, List<String> executorLocations) {
    Map<Integer, JavaHash<StructLike>> partitionHashes = Maps.newHashMap();
    String[][] locations = new String[taskGroups.size()][];

    for (int index = 0; index < taskGroups.size(); index++) {
      locations[index] = assign(taskGroups.get(index), executorLocations, partitionHashes);
    }

    return locations;
  }
@TestTemplate
  public void testFileScanTaskWithDeletes() {
    StructLike partition1 = Row.of("k2", null);
    StructLike partition2 = Row.of("k1");
    List<ScanTask> tasks =
        ImmutableList.of(
            new MockFileScanTask(
                mockDataFile(partition1), mockDeleteFiles(1, partition1), SCHEMA, SPEC_1),
            new MockFileScanTask(
                mockDataFile(partition2), mockDeleteFiles(3, partition2), SCHEMA, SPEC_2),
            new MockFileScanTask(
                mockDataFile(partition1), mockDeleteFiles(2, partition1), SCHEMA, SPEC_1));
    ScanTaskGroup<ScanTask> taskGroup = new BaseScanTaskGroup<>(tasks);
    List<ScanTaskGroup<ScanTask>> taskGroups = ImmutableList.of(taskGroup);

    String[][] locations = SparkPlanningUtil.assignExecutors(taskGroups, EXECUTOR_LOCATIONS);

    // should assign executors and handle different size of partitions
    assertThat(locations.length).isEqualTo(1);
    assertThat(locations[0].length).isGreaterThanOrEqualTo(1);
  }