package com.github.elazarl.multireducers;
import com.google.common.collect.*;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.mapreduce.Counters;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mrunit.mapreduce.mock.MockReduceContextWrapper;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.util.Collections;
import static com.github.elazarl.multireducers.MultiTestHelper.classList;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
public class MultiReducerTest {
static Multimap<String, Integer> reduceCalled;
@Before
public void before() {
reduceCalled = HashMultimap.create();
}
@Test
@SuppressWarnings("unchecked")
public void testReduce() throws Exception {
Configuration conf = new Configuration();
conf.set(MultiReducer.CONF_KEY, classList(FirstReducer.class, SecondReducer.class, ThirdReducer.class));
MultiReducer multiReducer = new MultiReducer();
Reducer.Context mockContext = new MockReduceContextWrapper(Collections.EMPTY_LIST, new Counters(), conf).getMockContext();
multiReducer.setup(mockContext);
multiReducer.reduce(new PerMapperOutputKey(0, new IntWritable(1)), ImmutableList.of(), mockContext);
multiReducer.reduce(new PerMapperOutputKey(0, new IntWritable(2)), ImmutableList.of(), mockContext);
multiReducer.reduce(new PerMapperOutputKey(0, new IntWritable(3)), ImmutableList.of(), mockContext);
assertThat(ImmutableSet.copyOf(reduceCalled.get("first")), is(ImmutableSet.of(1, 2, 3)));
assertThat(reduceCalled.containsKey("second"), is(false));
assertThat(reduceCalled.containsKey("third"), is(false));
}
@Test
@SuppressWarnings("unchecked")
public void testCombine() throws Exception {
Configuration conf = new Configuration();
conf.set(MultiCombiner.CONF_KEY, classList(FirstReducer.class, SecondReducer.class, ThirdReducer.class));
MultiReducer multiReducer = new MultiCombiner();
Reducer.Context mockContext = new MockReduceContextWrapper(Collections.EMPTY_LIST, new Counters(), conf).getMockContext();
multiReducer.setup(mockContext);
multiReducer.reduce(new PerMapperOutputKey(0, new IntWritable(1)), ImmutableList.of(), mockContext);
multiReducer.reduce(new PerMapperOutputKey(0, new IntWritable(2)), ImmutableList.of(), mockContext);
multiReducer.reduce(new PerMapperOutputKey(0, new IntWritable(3)), ImmutableList.of(), mockContext);
multiReducer.reduce(new PerMapperOutputKey(2, new IntWritable(21)), ImmutableList.of(), mockContext);
assertThat(ImmutableSet.copyOf(reduceCalled.get("first")), is(ImmutableSet.of(1, 2, 3)));
assertThat(reduceCalled.containsKey("second"), is(false));
assertThat(ImmutableSet.copyOf(reduceCalled.get("third")), is(ImmutableSet.of(21)));
}
static public class ReportReducer extends Reducer<IntWritable, NullWritable, NullWritable, NullWritable> {
@Override
protected void reduce(IntWritable key, Iterable<NullWritable> values, Context context) throws IOException, InterruptedException {
reduceCalled.put(name, key.get());
}
private String name;
public ReportReducer(String name) {
this.name = name;
}
@Override
protected void setup(Context context) throws IOException, InterruptedException {
}
}
static public class FirstReducer extends ReportReducer {
public FirstReducer() {
super("first");
}
}
static public class SecondReducer extends ReportReducer {
public SecondReducer() {
super("second");
}
}
static public class ThirdReducer extends ReportReducer {
public ThirdReducer() {
super("third");
}
}
}