package com.codecademy.eventhub.integration;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.name.Names;
import com.codecademy.eventhub.*;
import com.codecademy.eventhub.index.DatedEventIndex;
import com.codecademy.eventhub.index.DatedEventIndexModule;
import com.codecademy.eventhub.index.EventIndex;
import com.codecademy.eventhub.index.PropertiesIndex;
import com.codecademy.eventhub.index.PropertiesIndexModule;
import com.codecademy.eventhub.index.ShardedEventIndex;
import com.codecademy.eventhub.index.ShardedEventIndexModule;
import com.codecademy.eventhub.index.UserEventIndex;
import com.codecademy.eventhub.index.UserEventIndexModule;
import com.codecademy.eventhub.list.DmaIdListModule;
import com.codecademy.eventhub.model.Event;
import com.codecademy.eventhub.model.User;
import com.codecademy.eventhub.storage.EventStorage;
import com.codecademy.eventhub.storage.EventStorageModule;
import com.codecademy.eventhub.storage.JournalEventStorage;
import com.codecademy.eventhub.storage.JournalUserStorage;
import com.codecademy.eventhub.storage.UserStorageModule;
import com.codecademy.eventhub.storage.UserStorage;
import com.codecademy.eventhub.storage.filter.ExactMatch;
import com.codecademy.eventhub.storage.filter.Filter;
import com.codecademy.eventhub.storage.filter.Regex;
import com.codecademy.eventhub.storage.filter.TrueFilter;
import org.junit.Assert;
import org.junit.Test;
import javax.inject.Provider;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;
public class EventHubTest extends GuiceTestCase {
@Test
public void testSingleUser() throws Exception {
Provider<EventHub> eventHubProvider = getEventHubProvider();
EventHub eventHub = eventHubProvider.get();
final String[] USER_IDS = { "10" };
final String[] EVENT_TYPES = { "eventType1", "eventType2", "eventType3", "eventType4", "eventType5" };
final String[] DATES = { "20130101", "20130102", "20130103", "20130104", "20130105" };
addEvent(eventHub, EVENT_TYPES[0], USER_IDS[0], DATES[0], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[0], DATES[1], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[2], USER_IDS[0], DATES[2], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[3], USER_IDS[0], DATES[3], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[4], USER_IDS[0], DATES[4], Maps.<String, String>newHashMap());
final String[] funnelSteps = { EVENT_TYPES[1], EVENT_TYPES[2], EVENT_TYPES[3] };
List<Filter> eventFilters = Lists.<Filter>newArrayList(TrueFilter.INSTANCE, TrueFilter.INSTANCE, TrueFilter.INSTANCE);
Assert.assertArrayEquals(new int[] { 1 },
eventHub.getFunnelCounts(DATES[0], DATES[4], new String[] { EVENT_TYPES[1] }, 7 /* numDaysToCompleteFunnel */,
eventFilters, TrueFilter.INSTANCE));
Assert.assertArrayEquals(new int[] { 1, 1, 1 },
eventHub.getFunnelCounts(DATES[0], DATES[4], funnelSteps, 7 /* numDaysToCompleteFunnel */,
eventFilters, TrueFilter.INSTANCE));
Assert.assertArrayEquals(new int[] { 0, 0, 0 },
eventHub.getFunnelCounts(DATES[0], DATES[1], funnelSteps, 7 /* numDaysToCompleteFunnel */,
eventFilters, TrueFilter.INSTANCE));
Assert.assertArrayEquals(new int[] { 1, 1, 1 },
eventHub.getFunnelCounts(DATES[1], DATES[2], funnelSteps, 7 /* numDaysToCompleteFunnel */,
eventFilters, TrueFilter.INSTANCE));
Assert.assertArrayEquals(new int[] { 1, 0, 0 },
eventHub.getFunnelCounts(DATES[0], DATES[4], funnelSteps, 1 /* numDaysToCompleteFunnel */,
eventFilters, TrueFilter.INSTANCE));
Assert.assertArrayEquals(new int[] { 1, 1, 1 },
eventHub.getFunnelCounts(DATES[1], DATES[2], funnelSteps, 3 /* numDaysToCompleteFunnel */,
eventFilters, TrueFilter.INSTANCE));
Assert.assertArrayEquals(new int[] { 1, 1, 0 },
eventHub.getFunnelCounts(DATES[1], DATES[2], funnelSteps, 2 /* numDaysToCompleteFunnel */,
eventFilters, TrueFilter.INSTANCE));
Assert.assertArrayEquals(new int[] { 1, 0, 0 },
eventHub.getFunnelCounts(DATES[1], DATES[2], funnelSteps, 1 /* numDaysToCompleteFunnel */,
eventFilters, TrueFilter.INSTANCE));
}
@Test
public void testAll() throws Exception {
Provider<EventHub> eventHubProvider = getEventHubProvider();
EventHub eventHub = eventHubProvider.get();
final String[] EVENT_TYPES = { "eventType1", "eventType2", "eventType3", "eventType4" };
final String[] USER_IDS = { "10", "11", "12", "13", "14", "15", "16", "17", "18" };
final String[] DATES = { "20130101", "20130102", "20130103", "20130104", "20130105" };
eventHub.addOrUpdateUser(new User.Builder("10", Maps.<String, String>newHashMap()).build());
eventHub.addOrUpdateUser(new User.Builder("11", ImmutableMap.of("hello", "world")).build());
addEvent(eventHub, EVENT_TYPES[0], USER_IDS[0], DATES[0], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[0], USER_IDS[1], DATES[0], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[0], USER_IDS[3], DATES[0], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[0], USER_IDS[6], DATES[0], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[6], DATES[0], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[0], USER_IDS[7], DATES[0], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[0], USER_IDS[0], DATES[1], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[1], DATES[1], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[0], USER_IDS[2], DATES[1], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[3], DATES[1], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[0], USER_IDS[5], DATES[1], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[3], USER_IDS[6], DATES[1], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[7], DATES[1], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[3], USER_IDS[7], DATES[1], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[0], USER_IDS[8], DATES[1], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[8], DATES[1], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[0], DATES[2], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[3], USER_IDS[1], DATES[2], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[2], DATES[2], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[2], USER_IDS[3], DATES[2], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[4], DATES[2], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[3], USER_IDS[5], DATES[2], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[3], USER_IDS[0], DATES[3], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[3], USER_IDS[2], DATES[3], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[3], USER_IDS[3], DATES[3], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[2], USER_IDS[4], DATES[3], Maps.<String, String>newHashMap());
final String[] funnelSteps = { EVENT_TYPES[0], EVENT_TYPES[1], EVENT_TYPES[3] };
List<Filter> eventFilters = Lists.<Filter>newArrayList(TrueFilter.INSTANCE, TrueFilter.INSTANCE, TrueFilter.INSTANCE);
Assert.assertArrayEquals(new int[] { 8, 7, 6 },
eventHub.getFunnelCounts(DATES[0], DATES[4], funnelSteps, 7 /* numDaysToCompleteFunnel */,
eventFilters, TrueFilter.INSTANCE));
Assert.assertArrayEquals(new int[] { 4, 3, 2 },
eventHub.getFunnelCounts(DATES[1], DATES[4], funnelSteps, 7 /* numDaysToCompleteFunnel */,
eventFilters, TrueFilter.INSTANCE));
Assert.assertArrayEquals(new int[] { 4, 1, 0 },
eventHub.getFunnelCounts(DATES[1], DATES[2], funnelSteps, 1 /* numDaysToCompleteFunnel */,
eventFilters, TrueFilter.INSTANCE));
Function<User, String> getExternalUserId = new Function<User, String>() {
@Override
public String apply(User user) {
return user.getExternalId();
}
};
Assert.assertEquals(Lists.newArrayList("10", "11", "13", "16", "17", "12", "15", "18", "14"),
Lists.transform(eventHub.findUsers(TrueFilter.INSTANCE), getExternalUserId));
Assert.assertEquals(Lists.newArrayList("11"),
Lists.transform(eventHub.findUsers(new ExactMatch("hello", "world")), getExternalUserId));
Assert.assertEquals(Lists.newArrayList("16"),
Lists.transform(eventHub.findUsers(new ExactMatch("external_user_id", "16")), getExternalUserId));
eventHub.close();
eventHub = eventHubProvider.get();
Assert.assertArrayEquals(new int[] { 8, 7, 6 },
eventHub.getFunnelCounts(DATES[0], DATES[4], funnelSteps, 7 /* numDaysToCompleteFunnel */,
eventFilters, TrueFilter.INSTANCE));
Assert.assertArrayEquals(new int[] { 4, 3, 2 },
eventHub.getFunnelCounts(DATES[1], DATES[4], funnelSteps, 7 /* numDaysToCompleteFunnel */,
eventFilters, TrueFilter.INSTANCE));
Assert.assertArrayEquals(new int[] { 4, 1, 0 },
eventHub.getFunnelCounts(DATES[1], DATES[2], funnelSteps, 1 /* numDaysToCompleteFunnel */,
eventFilters, TrueFilter.INSTANCE));
Assert.assertEquals(Lists.newArrayList("10", "11", "13", "16", "17", "12", "15", "18", "14"),
Lists.transform(eventHub.findUsers(TrueFilter.INSTANCE), getExternalUserId));
Assert.assertEquals(Lists.newArrayList("11"),
Lists.transform(eventHub.findUsers(new ExactMatch("hello", "world")), getExternalUserId));
Assert.assertEquals(Lists.newArrayList("16"),
Lists.transform(eventHub.findUsers(new ExactMatch("external_user_id", "16")), getExternalUserId));
}
@Test
public void testConcurrentAddEvent() throws Exception {
Injector injector = getInjector();
final String directory = injector.getInstance(Key.get(String.class, Names.named("eventhub.directory")));
final ShardedEventIndex shardedEventIndex = injector.getInstance(ShardedEventIndex.class);
final DatedEventIndex datedEventIndex = injector.getInstance(DatedEventIndex.class);
final PropertiesIndex propertiesIndex = injector.getInstance(PropertiesIndex.class);
final UserEventIndex userEventIndex = injector.getInstance(UserEventIndex.class);
final EventStorage eventStorage = injector.getInstance(JournalEventStorage.class);
final UserStorage userStorage = injector.getInstance(JournalUserStorage.class);
final EventHub eventHub = new EventHub(directory, shardedEventIndex, datedEventIndex,
propertiesIndex, userEventIndex, eventStorage, userStorage);
final int NUM_EVENTS = 2000;
final int NUM_THREADS = 20; // NUM_EVENTS needs to be muliple of NUM_THREADS
final String[] EVENT_TYPES = { "eventType1", "eventType2", "eventType3", "eventType4" };
final String[] EXTERNAL_USER_IDS = { "10", "11", "12", "13", "14", "15", "16", "17", "18" };
final String[] DATES = { "20130101", "20130102", "20130103", "20130104", "20130105" };
final AtomicInteger counter = new AtomicInteger(0);
final Random random = new Random();
final CountDownLatch latch = new CountDownLatch(NUM_THREADS);
Thread[] threads = new Thread[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
latch.countDown();
try {
latch.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
for (int j = 0; j < NUM_EVENTS / NUM_THREADS; j++) {
int eventTypeIndex = random.nextInt(EVENT_TYPES.length);
int userIdIndex = random.nextInt(EXTERNAL_USER_IDS.length);
int dateIndex = counter.getAndIncrement() * DATES.length / NUM_EVENTS;
addEvent(eventHub, EVENT_TYPES[eventTypeIndex], EXTERNAL_USER_IDS[userIdIndex], DATES[dateIndex],
Maps.<String, String>newHashMap());
}
}
});
threads[i] = thread;
thread.start();
}
for (int i = 0; i < NUM_THREADS; i++) {
threads[i].join();
}
for (int eventId = 0; eventId < NUM_EVENTS; eventId++) {
Event event = eventStorage.getEvent(eventId);
Assert.assertEquals(shardedEventIndex.getEventTypeId(event.getEventType()), eventStorage.getEventTypeId(eventId));
Assert.assertEquals(userStorage.getId(event.getExternalUserId()), eventStorage.getUserId(eventId));
}
Set<String> externalUserIds = Sets.newHashSet();
for (int i = 0; i < EXTERNAL_USER_IDS.length; i++) {
externalUserIds.add(userStorage.getUser(i).getExternalId());
}
Assert.assertEquals(Sets.newHashSet(EXTERNAL_USER_IDS), externalUserIds);
try {
userStorage.getUser(EXTERNAL_USER_IDS.length);
Assert.fail("Should fail when fetching an user with inexistent id.");
} catch (RuntimeException e) {}
for (int eventTypeId = 0; eventTypeId < EVENT_TYPES.length; eventTypeId++) {
final int EVENT_TYPE_ID = eventTypeId;
// didn't bother check the callback is actually called
shardedEventIndex.enumerateEventIds(EVENT_TYPES[eventTypeId], DATES[0], "21991231",
new EventIndex.Callback() {
@Override
public void onEventId(long eventId) {
Assert.assertEquals(EVENT_TYPES[EVENT_TYPE_ID],
eventStorage.getEvent(eventId).getEventType());
}
});
}
for (int userId = 0; userId < EXTERNAL_USER_IDS.length; userId++) {
final int USER_ID = userId;
userEventIndex.enumerateEventIds(userId, 0, NUM_EVENTS, new UserEventIndex.Callback() {
@Override
public boolean shouldContinueOnEventId(long eventId) {
Assert.assertEquals(USER_ID, userStorage.getId(
eventStorage.getEvent(eventId).getExternalUserId()));
return true;
}
});
}
}
@Test
public void testFilter() throws Exception {
Provider<EventHub> eventHubProvider = getEventHubProvider();
EventHub eventHub = eventHubProvider.get();
final String[] USER_IDS = { "10", "11" };
final String[] EVENT_TYPES = { "eventType1", "eventType2", "eventType3", "eventType4", "eventType5" };
final String[] DATES = { "20130101", "20130102", "20130103", "20130104", "20130105" };
@SuppressWarnings("unchecked") final Map<String, String>[] properties = (Map<String, String>[]) new Map[] {
ImmutableMap.<String, String>builder().put("foo1", "bar1").put("foo2", "bar2").build(),
ImmutableMap.<String, String>builder().put("foo2", "bar2").put("foo3", "bar3").build(),
ImmutableMap.<String, String>builder().put("foo3", "bar3").build()
};
eventHub.addOrUpdateUser(new User.Builder(USER_IDS[0], properties[0]).build());
eventHub.addOrUpdateUser(new User.Builder(USER_IDS[1], properties[1]).build());
addEvent(eventHub, EVENT_TYPES[0], USER_IDS[0], DATES[0], properties[0]);
addEvent(eventHub, EVENT_TYPES[0], USER_IDS[1], DATES[0], properties[0]);
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[0], DATES[1], properties[0]);
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[1], DATES[1], properties[0]);
addEvent(eventHub, EVENT_TYPES[2], USER_IDS[0], DATES[2], properties[1]);
addEvent(eventHub, EVENT_TYPES[2], USER_IDS[1], DATES[2], properties[1]);
addEvent(eventHub, EVENT_TYPES[3], USER_IDS[0], DATES[3], properties[1]);
addEvent(eventHub, EVENT_TYPES[3], USER_IDS[1], DATES[3], properties[1]);
addEvent(eventHub, EVENT_TYPES[4], USER_IDS[0], DATES[4], properties[2]);
addEvent(eventHub, EVENT_TYPES[4], USER_IDS[1], DATES[4], properties[2]);
final String[] funnelSteps = { EVENT_TYPES[1], EVENT_TYPES[2], EVENT_TYPES[4] };
List<Filter> eventFilters = Lists.<Filter>newArrayList(TrueFilter.INSTANCE, TrueFilter.INSTANCE, TrueFilter.INSTANCE);
Assert.assertArrayEquals(new int[] { 2, 2, 2 },
eventHub.getFunnelCounts(DATES[0], DATES[4], funnelSteps, 7 /* numDaysToCompleteFunnel */,
eventFilters, TrueFilter.INSTANCE));
Assert.assertArrayEquals(new int[] {2, 0, 0},
eventHub.getFunnelCounts(DATES[0], DATES[4], funnelSteps, 7 /* numDaysToCompleteFunnel */,
Lists.<Filter>newArrayList(
new ExactMatch("foo1", "bar1"),
new Regex("foo4", Pattern.compile("b.*4")),
TrueFilter.INSTANCE),
TrueFilter.INSTANCE));
Assert.assertArrayEquals(new int[] { 2, 2, 0 },
eventHub.getFunnelCounts(DATES[0], DATES[4], funnelSteps, 7 /* numDaysToCompleteFunnel */,
Lists.<Filter>newArrayList(
new ExactMatch("foo2", "bar2"),
new Regex("foo2", Pattern.compile("bar2")),
new ExactMatch("foo2", "bar2")),
TrueFilter.INSTANCE));
Assert.assertArrayEquals(new int[] {2, 2, 2},
eventHub.getFunnelCounts(DATES[0], DATES[4], funnelSteps, 7 /* numDaysToCompleteFunnel */,
eventFilters, new ExactMatch("foo2", "bar2")));
Assert.assertArrayEquals(new int[] { 1, 1, 1 },
eventHub.getFunnelCounts(DATES[0], DATES[4], funnelSteps, 7 /* numDaysToCompleteFunnel */,
eventFilters, new ExactMatch("foo3", "bar3")));
}
@Test
public void testGetEventsByExternalUserId() throws Exception {
Provider<EventHub> eventHubProvider = getEventHubProvider();
EventHub eventHub = eventHubProvider.get();
final String[] USER_IDS = { "10" };
final String[] EVENT_TYPES = { "eventType1", "eventType2", "eventType3", "eventType4", "eventType5" };
final String[] DATES = { "20130101", "20130102", "20130103", "20130104", "20130105" };
addEvent(eventHub, EVENT_TYPES[0], USER_IDS[0], DATES[0], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[0], DATES[1], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[2], USER_IDS[0], DATES[2], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[3], USER_IDS[0], DATES[3], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[4], USER_IDS[0], DATES[4], Maps.<String, String>newHashMap());
List<Event> events = eventHub.getUserEvents(USER_IDS[0], 2, 10);
for (int i = 0; i < events.size(); i++) {
Assert.assertEquals(EVENT_TYPES[i + 2], events.get(i).getEventType());
Assert.assertEquals(DATES[i + 2], events.get(i).getDate());
Assert.assertEquals(USER_IDS[0], events.get(i).getExternalUserId());
}
events = eventHub.getUserEvents(USER_IDS[0], 2, 2);
for (int i = 0; i < events.size(); i++) {
Assert.assertEquals(EVENT_TYPES[i + 2], events.get(i).getEventType());
Assert.assertEquals(DATES[i + 2], events.get(i).getDate());
Assert.assertEquals(USER_IDS[0], events.get(i).getExternalUserId());
}
}
@Test
public void testGetRetentionTable() throws Exception {
Provider<EventHub> eventHubProvider = getEventHubProvider();
EventHub eventHub = eventHubProvider.get();
final String[] USER_IDS = { "10", "11", "12", "13", "14" };
final String[] EVENT_TYPES = { "receive_email", "purchase", "dummy" };
final String[] DATES = { "20130101", "20130102", "20130103", "20130104", "20130105", "20130106",
"20130107" };
addEvent(eventHub, EVENT_TYPES[2], USER_IDS[0], DATES[0], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[0], USER_IDS[0], DATES[0], ImmutableMap.of("foo1", "bar1"));
addEvent(eventHub, EVENT_TYPES[0], USER_IDS[1], DATES[0], ImmutableMap.of("foo1", "bar1"));
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[1], DATES[0], ImmutableMap.of("foo2", "bar2"));
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[1], DATES[1], ImmutableMap.of("foo2", "bar2"));
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[1], DATES[1], ImmutableMap.of("foo2", "bar2"));
addEvent(eventHub, EVENT_TYPES[0], USER_IDS[1], DATES[2], ImmutableMap.of("foo1", "bar1"));
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[1], DATES[2], ImmutableMap.of("foo2", "bar2"));
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[1], DATES[2], ImmutableMap.of("foo2", "bar2"));
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[1], DATES[2], ImmutableMap.of("foo2", "bar2"));
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[1], DATES[3], ImmutableMap.of("foo2", "bar2"));
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[1], DATES[3], ImmutableMap.of("foo2", "bar2"));
addEvent(eventHub, EVENT_TYPES[2], USER_IDS[2], DATES[0], Maps.<String, String>newHashMap());
addEvent(eventHub, EVENT_TYPES[0], USER_IDS[2], DATES[1], ImmutableMap.of("foo1", "bar1"));
addEvent(eventHub, EVENT_TYPES[0], USER_IDS[3], DATES[2], ImmutableMap.of("foo1", "bar1"));
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[3], DATES[2], ImmutableMap.of("foo2", "bar2"));
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[3], DATES[3], ImmutableMap.of("foo2", "bar2"));
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[3], DATES[3], ImmutableMap.of("foo2", "bar2"));
addEvent(eventHub, EVENT_TYPES[0], USER_IDS[3], DATES[4], ImmutableMap.of("foo1", "bar1"));
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[3], DATES[4], ImmutableMap.of("foo2", "bar2"));
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[3], DATES[4], ImmutableMap.of("foo2", "bar2"));
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[3], DATES[4], ImmutableMap.of("foo2", "bar2"));
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[3], DATES[5], ImmutableMap.of("foo2", "bar2"));
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[3], DATES[5], ImmutableMap.of("foo2", "bar2"));
addEvent(eventHub, EVENT_TYPES[0], USER_IDS[4], DATES[6], ImmutableMap.of("foo1", "bar1"));
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[4], DATES[6], ImmutableMap.of("foo2", "bar2"));
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[4], DATES[6], ImmutableMap.of("foo2", "bar2"));
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[4], DATES[6], ImmutableMap.of("foo2", "bar2"));
addEvent(eventHub, EVENT_TYPES[0], USER_IDS[4], DATES[6], ImmutableMap.of("foo1", "bar1"));
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[4], DATES[6], ImmutableMap.of("foo2", "bar2"));
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[4], DATES[6], ImmutableMap.of("foo2", "bar2"));
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[4], DATES[6], ImmutableMap.of("foo2", "bar2"));
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[4], DATES[6], ImmutableMap.of("foo2", "bar2"));
addEvent(eventHub, EVENT_TYPES[1], USER_IDS[4], DATES[6], ImmutableMap.of("foo2", "bar2"));
int[][] expectedCount = {
/*D0,1*/ { 3 /*0,1,2*/, 1 /*1*/ , 1 /*1*/, 0 /**/ },
/*D2,3*/ { 2 /*1,3*/ , 2 /*1,3*/, 1 /*3*/, 0 /**/ },
/*D4,5*/ { 1 /*3*/ , 1 /*3*/ , 0 /**/ , 0 /**/ }
};
int[][] retentionTable = eventHub.getRetentionTable(
"20130101", "20130106", 2, 3, EVENT_TYPES[0], EVENT_TYPES[1], TrueFilter.INSTANCE,
TrueFilter.INSTANCE);
for (int i = 0; i < expectedCount.length; i++) {
for (int j = 0; j < expectedCount[i].length; j++) {
Assert.assertEquals(expectedCount[i][j], retentionTable[i][j]);
}
}
retentionTable = eventHub.getRetentionTable(
"20130101", "20130106", 2, 3, EVENT_TYPES[0], EVENT_TYPES[1], new ExactMatch("foo1", "bar1"),
TrueFilter.INSTANCE);
for (int i = 0; i < expectedCount.length; i++) {
for (int j = 0; j < expectedCount[i].length; j++) {
Assert.assertEquals(expectedCount[i][j], retentionTable[i][j]);
}
}
retentionTable = eventHub.getRetentionTable(
"20130101", "20130106", 2, 3, EVENT_TYPES[0], EVENT_TYPES[1], TrueFilter.INSTANCE,
new ExactMatch("foo2", "bar2"));
for (int i = 0; i < expectedCount.length; i++) {
for (int j = 0; j < expectedCount[i].length; j++) {
Assert.assertEquals(expectedCount[i][j], retentionTable[i][j]);
}
}
retentionTable = eventHub.getRetentionTable(
"20130101", "20130106", 2, 3, EVENT_TYPES[0], EVENT_TYPES[1], new ExactMatch("foo1", "bar2"),
TrueFilter.INSTANCE);
for (int i = 0; i < expectedCount.length; i++) {
for (int j = 0; j < expectedCount[i].length; j++) {
Assert.assertEquals(0, retentionTable[i][j]);
}
}
}
private void addEvent(EventHub eventHub, String eventType, String externalUserId, String day,
Map<String, String> property) {
eventHub.addEvent(new Event.Builder(eventType, externalUserId, day, property).build());
}
private Provider<EventHub> getEventHubProvider() {
return getInjector().getProvider(EventHub.class);
}
private Injector getInjector() {
Properties prop = new Properties();
prop.put("eventhub.directory", getTempDirectory());
prop.put("eventhub.eventindex.initialNumEventIdsPerDay", "10");
prop.put("eventhub.usereventindex.numPointersPerIndexEntry", "2");
prop.put("eventhub.usereventindex.numIndexEntryPerFile", "2");
prop.put("eventhub.usereventindex.indexEntryFileCacheSize", "2");
prop.put("eventhub.usereventindex.numRecordsPerBlock", "2");
prop.put("eventhub.usereventindex.numBlocksPerFile", "2");
prop.put("eventhub.usereventindex.blockCacheSize", "2");
prop.put("eventhub.journaleventstorage.numMetaDataPerFile", "10");
prop.put("eventhub.journaleventstorage.metaDataFileCacheSize", "10");
prop.put("eventhub.journaleventstorage.journalFileSize", "1024");
prop.put("eventhub.journaleventstorage.journalWriteBatchSize", "1024");
prop.put("eventhub.cachedeventstorage.recordCacheSize", "10");
prop.put("eventhub.bloomfilteredeventstorage.bloomFilterSize", "64");
prop.put("eventhub.bloomfilteredeventstorage.numHashes", "1");
prop.put("eventhub.bloomfilteredeventstorage.numMetaDataPerFile", "10");
prop.put("eventhub.bloomfilteredeventstorage.metaDataFileCacheSize", "10");
prop.put("eventhub.journaluserstorage.numMetaDataPerFile", "10");
prop.put("eventhub.journaluserstorage.metaDataFileCacheSize", "10");
prop.put("eventhub.journaluserstorage.journalFileSize", "1024");
prop.put("eventhub.journaluserstorage.journalWriteBatchSize", "1024");
prop.put("eventhub.cacheduserstorage.recordCacheSize", "10");
prop.put("eventhub.bloomfiltereduserstorage.numMetaDataPerFile", "10");
prop.put("eventhub.bloomfiltereduserstorage.metaDataFileCacheSize", "10");
prop.put("eventhub.bloomfiltereduserstorage.bloomFilterSize", "64");
prop.put("eventhub.bloomfiltereduserstorage.numHashes", "1");
return createInjectorFor(new Properties(),
new EventHubModule(prop),
new DmaIdListModule(),
new ShardedEventIndexModule(),
new DatedEventIndexModule(),
new PropertiesIndexModule(),
new UserEventIndexModule(),
new EventStorageModule(),
new UserStorageModule());
}
}