/*******************************************************************************
* 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.threshd;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.io.IOUtils;
import org.easymock.EasyMock;
import org.jrobin.core.RrdDb;
import org.jrobin.core.RrdDef;
import org.jrobin.core.Sample;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.opennms.core.utils.InetAddressUtils;
import org.opennms.netmgt.config.ThresholdingConfigFactory;
import org.opennms.netmgt.config.threshd.Basethresholddef;
import org.opennms.netmgt.rrd.RrdUtils;
import org.opennms.netmgt.xml.event.Event;
import org.opennms.netmgt.xml.event.Events;
import org.opennms.test.FileAnticipator;
import org.opennms.test.ThrowableAnticipator;
import org.opennms.test.mock.EasyMockUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
/**
*
* @author <a href="mailto:dj@opennms.org">DJ Gregor</a>
* @author <a href="mailto:jeffg@opennms.org">Jeff Gehlbach</a>
* @author <a href="mailto:cmiskell@opennms.org">Craig Miskell</a>
* @author <a href="mailto:agalue@opennms.org">Alejandro Galue</a>
*/
public class SnmpThresholderTest {
@SuppressWarnings("deprecation")
private SnmpThresholder m_snmpThresholder;
private ThresholdNetworkInterface m_iface;
private SnmpThresholdNetworkInterface m_thresholdInterface;
private Map<String, String> m_params;
private DefaultThresholdsDao m_thresholdsDao;
private FileAnticipator m_fileAnticipator;
private IfInfoGetter m_ifInfoGetter;
private EasyMockUtils m_mocks = new EasyMockUtils();
private FileOutputStream m_out = null;
@SuppressWarnings("deprecation")
@Before
public void setUp() throws Exception {
m_fileAnticipator = new FileAnticipator();
int nodeId = 1;
String ipAddress = "192.168.1.1";
setUpThresholdingConfig();
m_thresholdsDao = new DefaultThresholdsDao();
m_thresholdsDao.setThresholdingConfigFactory(ThresholdingConfigFactory.getInstance());
m_thresholdsDao.afterPropertiesSet();
m_snmpThresholder = new SnmpThresholder();
m_snmpThresholder.setThresholdsDao(m_thresholdsDao);
m_ifInfoGetter = m_mocks.createMock(IfInfoGetter.class);
m_snmpThresholder.setIfInfoGetter(m_ifInfoGetter);
m_iface = new ThresholderTestCase.ThresholdNetworkInterfaceImpl(nodeId, InetAddressUtils.addr(ipAddress));
m_params = new HashMap<String, String>();
m_params.put("thresholding-group", "default-snmp");
m_thresholdInterface = new SnmpThresholdNetworkInterface(m_thresholdsDao, m_iface, m_params);
}
@After
public void tearDown() {
IOUtils.closeQuietly(m_out);
m_out = null;
System.gc();
m_fileAnticipator.tearDown();
}
private void setUpThresholdingConfig() throws Exception {
Resource config = new ClassPathResource("/test-thresholds.xml");
ThresholdingConfigFactory.setInstance(new ThresholdingConfigFactory(config.getInputStream()));
}
@SuppressWarnings("deprecation")
@Test
public void testCheckNodeDirNullDirectory() {
ThrowableAnticipator ta = new ThrowableAnticipator();
ta.anticipate(new IllegalArgumentException("directory argument cannot be null"));
try {
m_snmpThresholder.checkNodeDir(null, m_thresholdInterface, new Date(), new Events());
} catch (Throwable t) {
ta.throwableReceived(t);
}
ta.verifyAnticipated();
}
@SuppressWarnings("deprecation")
@Test
public void testCheckNodeDirNullThresholdNetworkInterface() {
ThrowableAnticipator ta = new ThrowableAnticipator();
ta.anticipate(new IllegalArgumentException("thresholdNetworkInterface argument cannot be null"));
try {
m_snmpThresholder.checkNodeDir(new File(""), null, new Date(), new Events());
} catch (Throwable t) {
ta.throwableReceived(t);
}
ta.verifyAnticipated();
}
// FIXME: This doesn't work now that config has been moved into SnmpThresholdNetworkInterface
@SuppressWarnings("deprecation")
@Test
public void testCheckNodeDirNullThresholdConfiguration() {
ThrowableAnticipator ta = new ThrowableAnticipator();
ta.anticipate(new IllegalArgumentException("thresholdNetworkInterface argument cannot be null"));
try {
m_snmpThresholder.checkNodeDir(new File(""), null, new Date(), new Events());
} catch (Throwable t) {
ta.throwableReceived(t);
}
ta.verifyAnticipated();
}
@SuppressWarnings("deprecation")
@Test
public void testCheckNodeDirNullDate() {
ThrowableAnticipator ta = new ThrowableAnticipator();
ta.anticipate(new IllegalArgumentException("date argument cannot be null"));
try {
m_snmpThresholder.checkNodeDir(new File(""), m_thresholdInterface, null, new Events());
} catch (Throwable t) {
ta.throwableReceived(t);
}
ta.verifyAnticipated();
}
@SuppressWarnings("deprecation")
@Test
public void testCheckNodeDirNullEvents() {
ThrowableAnticipator ta = new ThrowableAnticipator();
ta.anticipate(new IllegalArgumentException("events argument cannot be null"));
try {
m_snmpThresholder.checkNodeDir(new File(""), m_thresholdInterface, new Date(), null);
} catch (Throwable t) {
ta.throwableReceived(t);
}
ta.verifyAnticipated();
}
@SuppressWarnings("deprecation")
@Test
public void testCheckNodeDirNullSnmpIfaceInetAddress() {
ThresholdNetworkInterface intf = new ThresholderTestCase.ThresholdNetworkInterfaceImpl(1, null);
SnmpThresholdNetworkInterface snmpIface = new SnmpThresholdNetworkInterface(m_thresholdsDao, intf, m_params);
ThrowableAnticipator ta = new ThrowableAnticipator();
ta.anticipate(new IllegalArgumentException("getInetAddress() of thresholdNetworkInterface argument cannot be null"));
try {
m_snmpThresholder.checkNodeDir(new File(""), snmpIface, new Date(), new Events());
} catch (Throwable t) {
ta.throwableReceived(t);
}
ta.verifyAnticipated();
}
@SuppressWarnings("deprecation")
@Test
public void testCheckNodeDirNullFoo() throws Exception {
/*
ThrowableAnticipator ta = new ThrowableAnticipator();
ta.anticipate(new IllegalArgumentException("directory argument cannot be null"));
try {
*/
m_snmpThresholder.checkNodeDir(new File(""), m_thresholdInterface, new Date(), new Events());
/*
} catch (Throwable t) {
ta.throwableReceived(t);
}
ta.verifyAnticipated();
*/
}
@SuppressWarnings("deprecation")
@Test
public void testStripRrdExtensionWithValidExtension() throws Exception {
String strippedName = m_snmpThresholder.stripRrdExtension("foo" + RrdUtils.getExtension());
assertNotNull("stripped file name should not be null", strippedName);
assertEquals("stripped file name", "foo", strippedName);
}
@SuppressWarnings("deprecation")
@Test
public void testStripRrdExtensionWithNoExtension() throws Exception {
String strippedName = m_snmpThresholder.stripRrdExtension("foo");
assertNull("stripped file name should be null, but was: " + strippedName, strippedName);
}
@SuppressWarnings("deprecation")
@Test
public void testStripRrdExtensionWithValidExtensionTwice() throws Exception {
String strippedName = m_snmpThresholder.stripRrdExtension("foo" + RrdUtils.getExtension() + RrdUtils.getExtension());
assertNotNull("stripped file name should not be null", strippedName);
assertEquals("stripped file name", "foo" + RrdUtils.getExtension(), strippedName);
}
@SuppressWarnings("deprecation")
@Test
public void testStripRrdExtensionWithValidExtensionNotAtEnd() throws Exception {
String strippedName = m_snmpThresholder.stripRrdExtension("foo" + RrdUtils.getExtension() + ".bar");
assertNull("stripped file name should be null, but was: " + strippedName, strippedName);
}
@Test
public void testThresholdFilters() throws Exception {
System.err.println("--------------------------------------------------------");
ThresholdGroup group = m_thresholdsDao.get("generic-snmp");
m_thresholdInterface.getThresholdConfiguration().setThresholdGroup(group);
Collection<Basethresholddef> thresholds = m_thresholdsDao.getThresholdingConfigFactory().getThresholds("generic-snmp");
int count = 0;
for (Basethresholddef threshold: thresholds) {
count += threshold.getResourceFilterCount();
}
assertEquals(5, count); // Count how many resource-filter entries are defined on test-thresholods.xml
}
@SuppressWarnings("deprecation")
@Test
public void testInterfaces() throws Exception {
System.err.println("--------------------------------------------------------");
// Set storeByGroup, because JRBs will be created with this feature
System.setProperty("org.opennms.rrd.storeByGroup", "true");
// Get ThresholdGroup and validate data
ThresholdGroup group = m_thresholdsDao.get("generic-snmp");
// Common Variables
File path = m_fileAnticipator.getTempDir();
File nodeDir = m_fileAnticipator.tempDir(path, "1");
long start = System.currentTimeMillis();
List<String> sources = new ArrayList<String>();
sources.add("ifInOctets");
sources.add("ifOutOctets");
sources.add("ifInPackets");
sources.add("ifOutPackets");
// Create JRB File for Resource 1
File intf1Dir = m_fileAnticipator.tempDir(nodeDir, "eth0");
File rrd1 = m_fileAnticipator.tempFile(intf1Dir, "mib2-stats.jrb");
createDsProperties(intf1Dir, sources, "mib2-stats");
List<String> data1 = new ArrayList<String>();
data1.add("100:200:300:350"); // TRIGGERED:TRIGGERED:NONE:NONE
createAndUpdateRrd(rrd1, start, sources, data1);
// Create Temporal Files for Resource 2
File intf2Dir = m_fileAnticipator.tempDir(nodeDir, "wlan0");
File rrd2 = m_fileAnticipator.tempFile(intf2Dir, "mib2-stats.jrb");
createDsProperties(intf2Dir, sources, "mib2-stats");
List<String> data2 = new ArrayList<String>();
data2.add("50:150:400:300"); // NO_CHANGE:TRIGGERED:NONE:NONE
createAndUpdateRrd(rrd2, start, sources, data2);
// Run Thresholds Check and Validate. It must generate 3 events
m_thresholdInterface.getThresholdConfiguration().setThresholdGroup(group);
Events events = new Events();
// Creating Mock ifInfo Data for eth0
Map<String,String> ifInfoEth0 = new HashMap<String,String>();
ifInfoEth0.put("snmpifindex", "1");
ifInfoEth0.put("snmpifdesc", "eth0");
ifInfoEth0.put("snmpifalias", "ethernet interface");
// 3 times because there are 2 thresholds instances, one with two filters and one without filter (a total of 3) on test-thresholds.xml
EasyMock.expect(m_ifInfoGetter.getIfInfoForNodeAndLabel(1, "eth0")).andReturn(ifInfoEth0).times(3);
// Creating Mock ifInfo Data for wlan0
Map<String,String> ifInfoWlan0 = new HashMap<String,String>();
ifInfoWlan0.put("snmpifindex", "2");
ifInfoWlan0.put("snmpifdesc", "wlan0");
ifInfoWlan0.put("snmpifalias", "wireless interface");
// 3 times because there are 2 thresholds instances, one with two filters and one without filter (a total of 3) on test-thresholds.xml
EasyMock.expect(m_ifInfoGetter.getIfInfoForNodeAndLabel(1, "wlan0")).andReturn(ifInfoWlan0).times(3);
m_mocks.replayAll();
m_snmpThresholder.checkIfDir(intf1Dir, m_thresholdInterface, new Date(start), events);
m_snmpThresholder.checkIfDir(intf2Dir, m_thresholdInterface, new Date(start), events);
m_mocks.verifyAll();
//assertEquals(3, events.getEventCount()); // with no Filters. See test-thresholds.xml
assertEquals(2, events.getEventCount()); // with Filters Enabled. See test-thresholds.xml
}
@SuppressWarnings("deprecation")
@Test
public void testThresholdWithGenericResourceTypes() throws Exception {
System.err.println("--------------------------------------------------------");
// Set storeByGroup, because JRBs will be created with this feature
System.setProperty("org.opennms.rrd.storeByGroup", "true");
// Get ThresholdGroup and validate data
ThresholdGroup group = m_thresholdsDao.get("generic-snmp");
assertEquals(2, group.getGenericResourceTypeMap().get("frCircuitIfIndex").getThresholdMap().size());
// Common Variables
File path = m_fileAnticipator.getTempDir();
File nodeDir = m_fileAnticipator.tempDir(path, "1");
File rtDir = m_fileAnticipator.tempDir(nodeDir, "frCircuitIfIndex");
Properties strings = new Properties();
long start = System.currentTimeMillis();
List<String> sources = new ArrayList<String>();
sources.add("frSentFrames");
sources.add("frSentOctets");
sources.add("frReceivedFrames");
sources.add("frReceivedOctets");
// Create JRB File for Resource 1
File r1Dir = m_fileAnticipator.tempDir(rtDir, "Se0.100");
File rrd1 = m_fileAnticipator.tempFile(r1Dir, "rfc1315-frame-relay.jrb");
createDsProperties(r1Dir, sources, "rfc1315-frame-relay");
// Creating strings.properties for Resource 1
strings.setProperty("frName", "caracas");
strings.setProperty("frDlci", "100");
strings.setProperty("frIntf", "0");
File sFile1 = m_fileAnticipator.tempFile(r1Dir, "strings.properties");
m_out = new FileOutputStream(sFile1);
strings.store(m_out, null);
m_out.close();
// Creating JRB content for Resource 1
List<String> data1 = new ArrayList<String>();
data1.add("100:200:300:350"); // TRIGGERED:TRIGGERED:NONE:NONE
createAndUpdateRrd(rrd1, start, sources, data1);
// Create Temporal Files for Resource 2
File r2Dir = m_fileAnticipator.tempDir(rtDir, "Se1.200");
File rrd2 = m_fileAnticipator.tempFile(r2Dir, "rfc1315-frame-relay.jrb");
createDsProperties(r2Dir, sources, "rfc1315-frame-relay");
// Creating strings.properties for Resource 2
strings.setProperty("frDlci", "200");
strings.setProperty("frIntf", "1");
File sFile2 = m_fileAnticipator.tempFile(r2Dir, "strings.properties");
m_out = new FileOutputStream(sFile2);
strings.store(m_out, null);
m_out.close();
// Creating JRB content for Resource 2
List<String> data2 = new ArrayList<String>();
data2.add("50:150:400:300"); // RE_ARMED:NO_CHANGE:NONE:NONE
createAndUpdateRrd(rrd2, start, sources, data2);
// Run Thresholds Check and Validate. It must generate 3 events
m_thresholdInterface.getThresholdConfiguration().setThresholdGroup(group);
Events events = new Events();
m_snmpThresholder.checkResourceDir(rtDir, m_thresholdInterface, new Date(start), events);
//assertEquals(3, events.getEventCount()); // with no Filters. See test-thresholds.xml
assertEquals(2, events.getEventCount()); // with Filters Enabled. See test-thresholds.xml
// Validating ds-value for bug 2129
for (Event e : events.getEvent()) {
assertEquals("label", e.getParmCollection().get(7).getParmName());
assertEquals("caracas", e.getParmCollection().get(7).getValue().getContent());
}
}
@SuppressWarnings("deprecation")
@Test
public void testExpressionWithGenericResourceTypes() throws Exception {
System.err.println("--------------------------------------------------------");
// Set storeByGroup, because JRBs will be created with this feature
System.setProperty("org.opennms.rrd.storeByGroup", "true");
// Get ThresholdGroup and validate data
ThresholdGroup group = m_thresholdsDao.get("generic-snmp");
assertEquals(1, group.getGenericResourceTypeMap().get("hrStorageIndex").getThresholdMap().size());
// Common Variables
File path = m_fileAnticipator.getTempDir();
File nodeDir = m_fileAnticipator.tempDir(path, "1");
File rtDir = m_fileAnticipator.tempDir(nodeDir, "hrStorageIndex");
Properties strings = new Properties();
long start = System.currentTimeMillis();
List<String> sources = new ArrayList<String>();
sources.add("hrStorageAllocUnits");
sources.add("hrStorageSize");
sources.add("hrStorageUsed");
// Create JRB File for Resource 1
File r1Dir = m_fileAnticipator.tempDir(rtDir, "opt");
File rrd1 = m_fileAnticipator.tempFile(r1Dir, "mib2-host-resources-storage.jrb");
createDsProperties(r1Dir, sources, "mib2-host-resources-storage");
// Creating strings.properties for Resource 1
strings.setProperty("hrStorageDescr", "/opt");
File sFile1 = m_fileAnticipator.tempFile(r1Dir, "strings.properties");
m_out = new FileOutputStream(sFile1);
strings.store(m_out, null);
m_out.close();
// Creating JRB content for Resource 1
List<String> data1 = new ArrayList<String>();
data1.add("2:200:80");
createAndUpdateRrd(rrd1, start, sources, data1);
// Run Thresholds Check and Validate. It must generate 3 events
m_thresholdInterface.getThresholdConfiguration().setThresholdGroup(group);
Events events = new Events();
m_snmpThresholder.checkResourceDir(rtDir, m_thresholdInterface, new Date(start), events);
// with no Filters. See test-thresholds.xml
assertEquals(1, events.getEventCount());
// Validating ds-value for bug 2129
for (Event e : events.getEvent()) {
assertEquals("label", e.getParmCollection().get(7).getParmName());
assertEquals("/opt", e.getParmCollection().get(7).getValue().getContent());
}
}
private void createDsProperties(File dir, List<String> sources, String group) throws Exception {
Properties ds = new Properties();
for (String source : sources) {
ds.setProperty(source, group);
}
File dsFile = m_fileAnticipator.tempFile(dir, "ds.properties");
m_out = new FileOutputStream(dsFile);
ds.store(m_out, null);
m_out.close();
}
private void createAndUpdateRrd(File rrdPath, long start, List<String> sources, List<String> values) throws Exception {
// Creating RRD
long ts = start/1000;
RrdDef rrdDef = new RrdDef(rrdPath.getAbsolutePath(), ts - 300, 300);
for (String source : sources) {
rrdDef.addDatasource(source, "GAUGE", 600, 0, Double.NaN);
}
rrdDef.addArchive("AVERAGE", 0.5, 1, 600);
System.err.println(rrdDef.dump());
RrdDb rrdDb = new RrdDb(rrdDef);
rrdDb.close();
// Updating RRD
rrdDb = new RrdDb(rrdPath.getAbsolutePath());
Sample sample = rrdDb.createSample();
for (String value : values) {
sample.setAndUpdate(Long.toString(ts) + ":" + value);
System.err.println(sample.dump());
ts += 300;
}
rrdDb.close();
}
}