/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2006-2011 The OpenNMS Group, Inc. * OpenNMS(R) is Copyright (C) 1999-2011 The OpenNMS Group, Inc. * * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. * * OpenNMS(R) is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * OpenNMS(R) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenNMS(R). If not, see: * http://www.gnu.org/licenses/ * * For more information contact: * OpenNMS(R) Licensing <license@opennms.org> * http://www.opennms.org/ * http://www.opennms.com/ *******************************************************************************/ package org.opennms.netmgt.notifd.mock; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import junit.framework.Assert; import org.opennms.test.mock.MockUtil; /** * @author brozow */ public class NotificationAnticipator { List<MockNotification> m_anticipated = new ArrayList<MockNotification>(); List<MockNotification> m_unanticipated = new ArrayList<MockNotification>(); List<MockNotification[]> m_earlyArrival = new ArrayList<MockNotification[]>(); List<MockNotification[]> m_lateBloomers = new ArrayList<MockNotification[]>(); long m_expectedDiff = 1000; /** */ public NotificationAnticipator() { } /** * @param expectedDiff */ public void setExpectedDifference(long expectedDiff) { m_expectedDiff = expectedDiff; } /** * * @return */ public long getExpectedDifference() { return m_expectedDiff; } /** * @param event * */ public void anticipateNotification(MockNotification mn) { MockUtil.println("Anticipating notification: " + mn); m_anticipated.add(mn); } /** * @param event */ public synchronized void notificationReceived(MockNotification mn) { int i = m_anticipated.indexOf(mn); if (i != -1) { MockNotification notification = m_anticipated.get(i); long receivedTime = mn.getExpectedTime(); long expectedTime = notification.getExpectedTime(); long difference = expectedTime - receivedTime; if (Math.abs(difference) < m_expectedDiff) { MockUtil.println("Received expected notification: " + mn); m_anticipated.remove(mn); notifyAll(); } else { MockNotification[] n = new MockNotification[] { notification, mn }; if (difference > 0) { MockUtil.println("Received early notification: " + mn); m_earlyArrival.add(n); } else { MockUtil.println("Received late notification: " + mn); m_lateBloomers.add(n); } } } else { MockUtil.println("Received unexpected notification: " + mn); m_unanticipated.add(mn); } } public Collection<MockNotification> getAnticipatedNotifications() { return Collections.unmodifiableCollection(m_anticipated); } public void reset() { m_anticipated = new ArrayList<MockNotification>(); m_unanticipated = new ArrayList<MockNotification>(); } /** * @return */ public Collection<MockNotification> getUnanticipated() { return Collections.unmodifiableCollection(m_unanticipated); } /** * @param i * @return */ public synchronized Collection<MockNotification> waitForAnticipated(long millis) { long waitTime = millis; long start = System.currentTimeMillis(); long now = start; while (waitTime > 0) { if (m_anticipated.isEmpty()) return new ArrayList<MockNotification>(0); try { wait(waitTime); } catch (InterruptedException e) { } now = System.currentTimeMillis(); waitTime -= (now - start); } return getAnticipatedNotifications(); } public void verifyAnticipated(long lastNotifyTime, long waitTime, long sleepTime) { StringBuffer problems = new StringBuffer(); long totalWaitTime = Math.max(0, lastNotifyTime + waitTime - System.currentTimeMillis()); Collection<MockNotification> missingNotifications = waitForAnticipated(totalWaitTime); // make sure that we didn't start before we should have long now = System.currentTimeMillis(); try { Thread.sleep(sleepTime); } catch (InterruptedException e) { } if (missingNotifications.size() != 0) { problems.append(missingNotifications.size() + " expected notifications still outstanding:\n"); problems.append(listNotifications("\t", missingNotifications)); } if (getUnanticipated().size() != 0) { problems.append(getUnanticipated().size() + " unanticipated notifications received:\n"); problems.append(listNotifications("\t", getUnanticipated())); } if (m_earlyArrival.size() != 0) { problems.append(m_earlyArrival.size() + " early notifications received:\n"); problems.append(listNotifications("\t", m_earlyArrival)); } if (m_lateBloomers.size() != 0) { problems.append(m_lateBloomers.size() + " late notifications received:\n"); problems.append(listNotifications("\t", m_lateBloomers)); } if (lastNotifyTime > now) { problems.append("Anticipated notifications received at " + lastNotifyTime + ", later than the last expected time of " + now + "\n"); } if (problems.length() > 0) { problems.deleteCharAt(problems.length() - 1); Assert.fail(problems.toString()); } } private static String listNotifications(String prefix, Collection<?> notifications) { StringBuffer b = new StringBuffer(); for (Object o : notifications) { MockNotification notification; MockNotification received = null; if (o instanceof MockNotification[]) { notification = ((MockNotification[]) o)[0]; received = ((MockNotification[]) o)[1]; } else { notification = (MockNotification) o; } b.append(prefix); b.append(notification); if (received != null) { b.append(" (received: "); b.append(received.getExpectedTime()); b.append(")"); } b.append("\n"); } return b.toString(); } }