@Test
public void testStickiness() {

    List<Integer> tasks;
    Map<Integer, ClientState<Integer>> states;
    Map<Integer, ClientState<Integer>> assignments;
    int i;
    // # of clients and # of tasks are equal.
    tasks = mkList(0, 1, 2, 3, 4, 5);
    Collections.shuffle(tasks);
    states = new HashMap<>();
    i = 0;
    for (int task : tasks) {
        ClientState<Integer> state = new ClientState<>(1d);
        state.prevActiveTasks.add(task);
        state.prevAssignedTasks.add(task);
        states.put(i++, state);
    }
    assignments = TaskAssignor.assign(states, mkSet(0, 1, 2, 3, 4, 5), 0);
    for (int client : states.keySet()) {
        Set<Integer> oldActive = states.get(client).prevActiveTasks;
        Set<Integer> oldAssigned = states.get(client).prevAssignedTasks;
        Set<Integer> newActive = assignments.get(client).activeTasks;
        Set<Integer> newAssigned = assignments.get(client).assignedTasks;
        assertEquals(oldActive, newActive);
        assertEquals(oldAssigned, newAssigned);
    }
    // # of clients > # of tasks
    tasks = mkList(0, 1, 2, 3, -1, -1);
    Collections.shuffle(tasks);
    states = new HashMap<>();
    i = 0;
    for (int task : tasks) {
        ClientState<Integer> state = new ClientState<>(1d);
        if (task >= 0) {
            state.prevActiveTasks.add(task);
            state.prevAssignedTasks.add(task);
        }
        states.put(i++, state);
    }
    assignments = TaskAssignor.assign(states, mkSet(0, 1, 2, 3), 0);
    for (int client : states.keySet()) {
        Set<Integer> oldActive = states.get(client).prevActiveTasks;
        Set<Integer> oldAssigned = states.get(client).prevAssignedTasks;
        Set<Integer> newActive = assignments.get(client).activeTasks;
        Set<Integer> newAssigned = assignments.get(client).assignedTasks;
        assertEquals(oldActive, newActive);
        assertEquals(oldAssigned, newAssigned);
    }
    // # of clients < # of tasks
    List<Set<Integer>> taskSets = mkList(mkSet(0, 1), mkSet(2, 3), mkSet(4, 5), mkSet(6, 7), mkSet(8, 9), mkSet(10, 11));
    Collections.shuffle(taskSets);
    states = new HashMap<>();
    i = 0;
    for (Set<Integer> taskSet : taskSets) {
        ClientState<Integer> state = new ClientState<>(1d);
        state.prevActiveTasks.addAll(taskSet);
        state.prevAssignedTasks.addAll(taskSet);
        states.put(i++, state);
    }
    assignments = TaskAssignor.assign(states, mkSet(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), 0);
    for (int client : states.keySet()) {
        Set<Integer> oldActive = states.get(client).prevActiveTasks;
        Set<Integer> oldAssigned = states.get(client).prevAssignedTasks;
        Set<Integer> newActive = assignments.get(client).activeTasks;
        Set<Integer> newAssigned = assignments.get(client).assignedTasks;
        Set<Integer> intersection = new HashSet<>();
        intersection.addAll(oldActive);
        intersection.retainAll(newActive);
        assertTrue(intersection.size() > 0);
        intersection.clear();
        intersection.addAll(oldAssigned);
        intersection.retainAll(newAssigned);
        assertTrue(intersection.size() > 0);
    }
}