package org.peerbox.notifications; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import java.util.Random; import net.engio.mbassy.listener.Handler; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.peerbox.app.manager.file.FileInfo; import org.peerbox.app.manager.file.messages.RemoteFileAddedMessage; import org.peerbox.app.manager.file.messages.RemoteFileDeletedMessage; import org.peerbox.app.manager.file.messages.RemoteFileMovedMessage; import org.peerbox.app.manager.file.messages.RemoteFileUpdatedMessage; import org.peerbox.events.MessageBus; import org.peerbox.presenter.tray.TrayException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class FileEventAggregatorTest { private static final Logger logger = LoggerFactory.getLogger(FileEventAggregatorTest.class); private FileEventAggregator aggregator; private MessageBus messageBus = new MessageBus(); private TrayNotificationsStub notifications; private static Random rnd; @BeforeClass public static void setup() { rnd = new Random(7); } @Before public void initialization() { notifications = new TrayNotificationsStub(); aggregator = new FileEventAggregator(messageBus); messageBus.subscribe(aggregator); messageBus.subscribe(notifications); } private AggregatedFileEventStatus sendEvents(long timeToSendEvents) throws InterruptedException { int totalAdded = 0; int totalModified = 0; int totalDeleted = 0; int totalMoved = 0; long startTime = System.currentTimeMillis(); int numFile = 0; while(System.currentTimeMillis() < (startTime + timeToSendEvents)) { Path p = Paths.get(String.valueOf(numFile)); Thread.sleep(rnd.nextInt(5)); FileInfo file = new FileInfo(p, false); FileInfo dstFile = new FileInfo(Paths.get("my/path"), false); switch (rnd.nextInt(4)) { case 0: aggregator.onFileAdded(new RemoteFileAddedMessage(file)); ++totalAdded; break; case 1: aggregator.onFileUpdated(new RemoteFileUpdatedMessage(file)); ++totalModified; break; case 2: aggregator.onFileDeleted(new RemoteFileDeletedMessage(file)); ++totalDeleted; break; case 3: aggregator.onFileMoved(new RemoteFileMovedMessage(file, dstFile)); ++totalMoved; default: break; } ++numFile; } return new AggregatedFileEventStatus(totalAdded, totalModified, totalDeleted, totalMoved); } @Test public void testRandomFileEventAggregation() throws InterruptedException { long timeToSendEvents = (long) (1.5 * FileEventAggregator.AGGREGATION_TIMESPAN); AggregatedFileEventStatus sent = sendEvents(timeToSendEvents); // wait some time to complete the aggregation Thread.sleep((long) (1.1*FileEventAggregator.AGGREGATION_TIMESPAN)); logger.info("Expected - Added: {}, Modified: {}, Deleted: {}", sent.getNumFilesAdded(), sent.getNumFilesModified(), sent.getNumFilesDeleted()); List<AggregatedFileEventStatus> events = notifications.getAggregatedFileEvents(); assertFalse(events.isEmpty()); int receivedAdds = 0; int receivedModifieds = 0; int receivedDeletes = 0; for(AggregatedFileEventStatus e : events) { receivedAdds += e.getNumFilesAdded(); receivedModifieds += e.getNumFilesModified(); receivedDeletes += e.getNumFilesDeleted(); } logger.info("Actual - Added: {}, Modified: {}, Deleted: {}", receivedAdds, receivedModifieds, receivedDeletes); assertTrue(receivedAdds == sent.getNumFilesAdded()); assertTrue(receivedModifieds == sent.getNumFilesModified()); assertTrue(receivedDeletes == sent.getNumFilesDeleted()); } @Test public void testRandomFileEventAggregationWaitTime() throws InterruptedException { long timeToSendEvents = (long) (1.5 * FileEventAggregator.AGGREGATION_TIMESPAN); AggregatedFileEventStatus sent = sendEvents(timeToSendEvents); // wait not enough long to complete the aggregation -> Should NOT receive all events! Thread.sleep((long) (0.1*FileEventAggregator.AGGREGATION_TIMESPAN)); logger.info("Expected - Added: {}, Modified: {}, Deleted: {}", sent.getNumFilesAdded(), sent.getNumFilesModified(), sent.getNumFilesDeleted()); List<AggregatedFileEventStatus> events = notifications.getAggregatedFileEvents(); assertFalse(events.isEmpty()); int receivedAdds = 0; int receivedModifieds = 0; int receivedDeletes = 0; for(AggregatedFileEventStatus e : events) { receivedAdds += e.getNumFilesAdded(); receivedModifieds += e.getNumFilesModified(); receivedDeletes += e.getNumFilesDeleted(); } logger.info("Actual - Added: {}, Modified: {}, Deleted: {}", receivedAdds, receivedModifieds, receivedDeletes); assertTrue(receivedAdds < sent.getNumFilesAdded()); assertTrue(receivedModifieds < sent.getNumFilesModified()); assertTrue(receivedDeletes < sent.getNumFilesDeleted()); } private class TrayNotificationsStub implements ITrayNotifications { private List<InformationNotification> informationNotification; private List<AggregatedFileEventStatus> aggregatedFileEvents; public TrayNotificationsStub() { informationNotification = new ArrayList<InformationNotification>(); aggregatedFileEvents = new ArrayList<AggregatedFileEventStatus>(); } public List<InformationNotification> getInformationNotification() { return informationNotification; } public List<AggregatedFileEventStatus> getAggregatedFileEvents() { return aggregatedFileEvents; } @Override @Handler public void showInformation(InformationNotification in) { informationNotification.add(in); } @Override @Handler public void showFileEvents(AggregatedFileEventStatus event) { aggregatedFileEvents.add(event); } @Override public void showSuccessIcon() throws TrayException { } } }