/*******************************************************************************
* This file is part of OpenNMS(R).
*
* Copyright (C) 2009-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.collectd;
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Method;
import org.apache.commons.io.IOUtils;
import org.opennms.netmgt.config.DataCollectionConfigFactory;
import org.opennms.netmgt.config.DatabaseSchemaConfigFactory;
import org.opennms.netmgt.config.HttpCollectionConfigFactory;
import org.opennms.netmgt.dao.DefaultDataCollectionConfigDao;
import org.opennms.netmgt.dao.support.RrdTestUtils;
import org.opennms.netmgt.rrd.RrdUtils;
import org.opennms.test.ConfigurationTestUtils;
import org.opennms.test.FileAnticipator;
import org.springframework.core.io.Resource;
import org.springframework.test.context.TestContext;
import org.springframework.test.context.TestExecutionListener;
import org.springframework.test.context.support.AbstractTestExecutionListener;
/**
* <p>This {@link TestExecutionListener} looks for the {@link JUnitCollector} annotation
* and uses attributes on it to:</p>
* <ul>
* <li>Load configuration files for the {@link ServiceCollector}</li>
* <li>Set up {@link FileAnticipator} checks for files created
* during the unit test execution</li>
* </ul>
*/
public class JUnitCollectorExecutionListener extends AbstractTestExecutionListener {
private File m_snmpRrdDirectory;
private FileAnticipator m_fileAnticipator;
@Override
public void beforeTestMethod(TestContext testContext) throws Exception {
JUnitCollector config = findCollectorAnnotation(testContext);
if (config == null) {
return;
}
// FIXME: Is there a better way to inject the instance into the test class?
if (testContext.getTestInstance() instanceof TestContextAware) {
System.err.println("injecting TestContext into TestContextAware test: "
+ testContext.getTestInstance().getClass().getSimpleName() + "."
+ testContext.getTestMethod().getName());
((TestContextAware) testContext.getTestInstance()).setTestContext(testContext);
}
RrdTestUtils.initialize();
// make a fake database schema with hibernate
InputStream is = ConfigurationTestUtils.getInputStreamForResource(testContext.getTestInstance(), config.schemaConfig());
DatabaseSchemaConfigFactory.setInstance(new DatabaseSchemaConfigFactory(is));
is.close();
// set up temporary directories for RRD files
m_fileAnticipator = new FileAnticipator();
m_snmpRrdDirectory = m_fileAnticipator.tempDir("snmp");
m_snmpRrdDirectory.mkdirs();
testContext.setAttribute("fileAnticipator", m_fileAnticipator);
testContext.setAttribute("rrdDirectory", m_snmpRrdDirectory);
// set up the collection configuration factory
if ("http".equalsIgnoreCase(config.datacollectionType()) || "https".equalsIgnoreCase(config.datacollectionType())) {
is = ConfigurationTestUtils.getInputStreamForResourceWithReplacements(testContext.getTestInstance(), config.datacollectionConfig(), new String[] { "%rrdRepository%", m_snmpRrdDirectory.getAbsolutePath() });
HttpCollectionConfigFactory factory = new HttpCollectionConfigFactory(is);
HttpCollectionConfigFactory.setInstance(factory);
HttpCollectionConfigFactory.init();
} else if ("snmp".equalsIgnoreCase(config.datacollectionType())) {
Resource r = ConfigurationTestUtils.getSpringResourceForResourceWithReplacements(testContext.getTestInstance(), config.datacollectionConfig(), new String[] { "%rrdRepository%", m_snmpRrdDirectory.getAbsolutePath() });
DefaultDataCollectionConfigDao dataCollectionDao = new DefaultDataCollectionConfigDao();
dataCollectionDao.setConfigResource(r);
dataCollectionDao.afterPropertiesSet();
DataCollectionConfigFactory.setInstance(dataCollectionDao);
} else {
throw new UnsupportedOperationException("data collection type '" + config.datacollectionType() + "' not supported");
}
IOUtils.closeQuietly(is);
}
@Override
public void afterTestMethod(TestContext testContext) throws Exception {
JUnitCollector config = findCollectorAnnotation(testContext);
if (config == null) {
return;
}
boolean shouldIgnoreNonExistent = testContext.getTestException() != null;
if (config.anticipateFiles().length > 0 ||
config.anticipateRrds().length > 0) {
// make sure any RRDs have time to get written
Thread.sleep(1000);
}
if (config.anticipateRrds().length > 0) {
for (String rrdFile : config.anticipateRrds()) {
m_fileAnticipator.expecting(m_snmpRrdDirectory, rrdFile + RrdUtils.getExtension());
}
}
if (config.anticipateFiles().length > 0) {
for (String file : config.anticipateFiles()) {
m_fileAnticipator.expecting(m_snmpRrdDirectory, file);
}
}
Exception e = null;
if (m_fileAnticipator.isInitialized()) {
try {
m_fileAnticipator.deleteExpected(shouldIgnoreNonExistent);
} catch (Throwable t) {
e = new RuntimeException(t);
}
}
deleteResursively(m_snmpRrdDirectory);
m_fileAnticipator.tearDown();
if (e != null) {
throw e;
}
}
private static void deleteResursively(File directory) {
if (!directory.exists()) return;
if (directory.isDirectory()) {
for (File f : directory.listFiles()) {
deleteResursively(f);
}
}
directory.delete();
}
private static JUnitCollector findCollectorAnnotation(TestContext testContext) {
Method testMethod = testContext.getTestMethod();
JUnitCollector config = testMethod.getAnnotation(JUnitCollector.class);
if (config != null) {
return config;
}
Class<?> testClass = testContext.getTestClass();
return testClass.getAnnotation(JUnitCollector.class);
}
}