@Test
  public void testReduceDriverImmutable() {
    try {
      {
        TestTaskContext<ReduceFunction<Tuple2<String, Integer>>, Tuple2<String, Integer>> context =
            new TestTaskContext<ReduceFunction<Tuple2<String, Integer>>, Tuple2<String, Integer>>(
                1024 * 1024);
        context.getTaskConfig().setRelativeMemoryDriver(0.5);

        List<Tuple2<String, Integer>> data = DriverTestData.createReduceImmutableData();
        Collections.shuffle(data);

        TupleTypeInfo<Tuple2<String, Integer>> typeInfo =
            (TupleTypeInfo<Tuple2<String, Integer>>) TypeExtractor.getForObject(data.get(0));
        MutableObjectIterator<Tuple2<String, Integer>> input =
            new RegularToMutableObjectIterator<Tuple2<String, Integer>>(
                data.iterator(), typeInfo.createSerializer(new ExecutionConfig()));
        TypeComparator<Tuple2<String, Integer>> comparator =
            typeInfo.createComparator(
                new int[] {0}, new boolean[] {true}, 0, new ExecutionConfig());

        GatheringCollector<Tuple2<String, Integer>> result =
            new GatheringCollector<Tuple2<String, Integer>>(
                typeInfo.createSerializer(new ExecutionConfig()));

        context.setDriverStrategy(DriverStrategy.SORTED_PARTIAL_REDUCE);
        context.setInput1(input, typeInfo.createSerializer(new ExecutionConfig()));
        context.setComparator1(comparator);
        context.setCollector(result);
        context.setUdf(new ConcatSumFirstReducer());

        ReduceCombineDriver<Tuple2<String, Integer>> driver =
            new ReduceCombineDriver<Tuple2<String, Integer>>();
        driver.setup(context);
        driver.prepare();
        driver.run();

        Object[] res = result.getList().toArray();
        Object[] expected = DriverTestData.createReduceImmutableDataGroupedResult().toArray();

        DriverTestData.compareTupleArrays(expected, res);
      }

      {
        TestTaskContext<ReduceFunction<Tuple2<String, Integer>>, Tuple2<String, Integer>> context =
            new TestTaskContext<ReduceFunction<Tuple2<String, Integer>>, Tuple2<String, Integer>>(
                1024 * 1024);
        context.getTaskConfig().setRelativeMemoryDriver(0.5);

        List<Tuple2<String, Integer>> data = DriverTestData.createReduceImmutableData();
        Collections.shuffle(data);

        TupleTypeInfo<Tuple2<String, Integer>> typeInfo =
            (TupleTypeInfo<Tuple2<String, Integer>>) TypeExtractor.getForObject(data.get(0));
        MutableObjectIterator<Tuple2<String, Integer>> input =
            new RegularToMutableObjectIterator<Tuple2<String, Integer>>(
                data.iterator(), typeInfo.createSerializer(new ExecutionConfig()));
        TypeComparator<Tuple2<String, Integer>> comparator =
            typeInfo.createComparator(
                new int[] {0}, new boolean[] {true}, 0, new ExecutionConfig());

        GatheringCollector<Tuple2<String, Integer>> result =
            new GatheringCollector<Tuple2<String, Integer>>(
                typeInfo.createSerializer(new ExecutionConfig()));

        context.setDriverStrategy(DriverStrategy.SORTED_PARTIAL_REDUCE);
        context.setInput1(input, typeInfo.createSerializer(new ExecutionConfig()));
        context.setComparator1(comparator);
        context.setCollector(result);
        context.setUdf(new ConcatSumSecondReducer());

        ReduceCombineDriver<Tuple2<String, Integer>> driver =
            new ReduceCombineDriver<Tuple2<String, Integer>>();
        driver.setup(context);
        driver.prepare();
        driver.run();

        Object[] res = result.getList().toArray();
        Object[] expected = DriverTestData.createReduceImmutableDataGroupedResult().toArray();

        DriverTestData.compareTupleArrays(expected, res);
      }
    } catch (Exception e) {
      System.err.println(e.getMessage());
      e.printStackTrace();
      Assert.fail(e.getMessage());
    }
  }