/*
* Copyright (c) 2016 Saugo360 and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.tsdr.restconf.collector;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Hashtable;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.slf4j.Logger;
/**
* This class is responsible for testing the TSDRRestconfCollectorConfig class.
*
* @author <a href="mailto:a.alhamali93@gmail.com">AbdulRahman AlHamali</a>
*
* Created: Dec 16th, 2016
*
*/
public class TSDRRestconfCollectorConfigTest {
/**
* the restconf collector config instance that we want to run our tests on.
*/
private TSDRRestconfCollectorConfig configObject;
/**
* the logger to be passed to the config instance.
* This is important because we want to check that the class is outputting the correct errors when invalid
* configuration is inserted
*/
private Logger logger;
/**
* an array list with that saves the messages generated by the logger to inspect them later on.
*/
private ArrayList<String> logMessages = new ArrayList<String>();
/**
* called before each test. It creates a mock logger that would add the logged message to logMessages list
* everytime the logger.error function is called.
* Also, the logMessages array is cleared, and the configObject is initialized
*/
@Before
public void setup() {
logger = Mockito.mock(Logger.class);
logMessages.clear();
Mockito.doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocationOnMock) throws Throwable {
Object[] args = invocationOnMock.getArguments();
logMessages.add((String)args[0]);
return null;
}
}).when(logger).error(Mockito.anyString());
configObject = TSDRRestconfCollectorConfig.getInstance();
TSDRRestconfCollectorConfig.setLogger(logger);
}
/**
* Tests the case when correct values are supplied in the configuration.
* the values should be cached, and no error logs should be generated
*/
@Test
public void testCorrectValues() throws Exception {
Dictionary properties = new Hashtable<String, String>();
properties.put("METHODS_TO_LOG", "GET,PUT");
properties.put("PATHS_TO_LOG", "/operations/.*");
properties.put("REMOTE_ADDRESSES_TO_LOG", "127\\.0\\.0\\.1");
properties.put("CONTENT_TO_LOG", ".*loggable.*");
configObject.updated(properties);
Assert.assertEquals("GET,PUT", configObject.getProperty("METHODS_TO_LOG"));
Assert.assertEquals("/operations/.*", configObject.getProperty("PATHS_TO_LOG"));
Assert.assertEquals("127\\.0\\.0\\.1", configObject.getProperty("REMOTE_ADDRESSES_TO_LOG"));
Assert.assertEquals(".*loggable.*", configObject.getProperty("CONTENT_TO_LOG"));
Assert.assertEquals(0, logMessages.size());
}
/**
* Tests the case when invalid http methods are supplied in the configuration.
* the default value should be used instead, and 2 meaningful error logs should be generated
*/
@Test
public void testUnrecognizedMethod() throws Exception {
Dictionary properties = new Hashtable<String, String>();
properties.put("METHODS_TO_LOG", "GERT,PUT");
properties.put("PATHS_TO_LOG", "/operations/.*");
properties.put("REMOTE_ADDRESSES_TO_LOG", "127\\.0\\.0\\.1");
properties.put("CONTENT_TO_LOG", ".*loggable.*");
configObject.updated(properties);
Assert.assertEquals("POST,PUT,DELETE", configObject.getProperty("METHODS_TO_LOG"));
Assert.assertEquals("HTTP method GERT is not recognized", logMessages.get(0));
Assert.assertEquals("Value specified for METHODS_TO_LOG: GERT,PUT is "
+ "invalid. Will use default value of POST,PUT,DELETE", logMessages.get(1));
Assert.assertEquals(2, logMessages.size());
}
/**
* Tests the case when repeated http methods are supplied in the configuration.
* the default value should be used instead, and 2 meaningful error logs should be generated
*/
@Test
public void testRepeatedMethod() throws Exception {
Dictionary properties = new Hashtable<String, String>();
properties.put("METHODS_TO_LOG", "GET,PUT,GET");
properties.put("PATHS_TO_LOG", "/operations/.*");
properties.put("REMOTE_ADDRESSES_TO_LOG", "127\\.0\\.0\\.1");
properties.put("CONTENT_TO_LOG", ".*loggable.*");
configObject.updated(properties);
Assert.assertEquals("POST,PUT,DELETE", configObject.getProperty("METHODS_TO_LOG"));
Assert.assertEquals("HTTP method GET is repeated multiple times", logMessages.get(0));
Assert.assertEquals("Value specified for METHODS_TO_LOG: GET,PUT,GET is "
+ "invalid. Will use default value of POST,PUT,DELETE", logMessages.get(1));
Assert.assertEquals(2, logMessages.size());
}
/**
* Tests the case when no http methods are supplied in the configuration.
* the default value should be used instead, and 2 meaningful error logs should be generated
*/
@Test
public void testMethodsEmpty() throws Exception {
Dictionary properties = new Hashtable<String, String>();
properties.put("METHODS_TO_LOG", "");
properties.put("PATHS_TO_LOG", "/operations/.*");
properties.put("REMOTE_ADDRESSES_TO_LOG", "127\\.0\\.0\\.1");
properties.put("CONTENT_TO_LOG", ".*loggable.*");
configObject.updated(properties);
Assert.assertEquals("POST,PUT,DELETE", configObject.getProperty("METHODS_TO_LOG"));
Assert.assertEquals("HTTP_METHODS_TO_LOG is either empty or non-existent", logMessages.get(0));
Assert.assertEquals("Value specified for METHODS_TO_LOG: is "
+ "invalid. Will use default value of POST,PUT,DELETE", logMessages.get(1));
Assert.assertEquals(2, logMessages.size());
}
/**
* Tests the case when METHODS_TO_LOG property is removed from the configuration.
* the default value should be used instead, and 2 meaningful error logs should be generated
*/
@Test
public void testMethodsNonExistent() throws Exception {
Dictionary properties = new Hashtable<String, String>();
properties.put("PATHS_TO_LOG", "/operations/.*");
properties.put("REMOTE_ADDRESSES_TO_LOG", "127\\.0\\.0\\.1");
properties.put("CONTENT_TO_LOG", ".*loggable.*");
configObject.updated(properties);
Assert.assertEquals("POST,PUT,DELETE", configObject.getProperty("METHODS_TO_LOG"));
Assert.assertEquals("HTTP_METHODS_TO_LOG is either empty or non-existent", logMessages.get(0));
Assert.assertEquals("Value specified for METHODS_TO_LOG: null is "
+ "invalid. Will use default value of POST,PUT,DELETE", logMessages.get(1));
Assert.assertEquals(2, logMessages.size());
}
/**
* Tests the case when an invalid regular expression is supplied for the paths in the configuration.
* the default value should be used instead, and 2 meaningful error logs should be generated
*/
@Test
public void testInvalidPathRegex() throws Exception {
Dictionary properties = new Hashtable<String, String>();
properties.put("METHODS_TO_LOG", "GET,PUT");
properties.put("PATHS_TO_LOG", "(");
properties.put("REMOTE_ADDRESSES_TO_LOG", "127\\.0\\.0\\.1");
properties.put("CONTENT_TO_LOG", ".*loggable.*");
configObject.updated(properties);
Assert.assertEquals(".*", configObject.getProperty("PATHS_TO_LOG"));
Assert.assertEquals(true, logMessages.get(0).startsWith("Pattern ( is not parsable"));
Assert.assertEquals("Value specified for PATHS_TO_LOG: ( is invalid. Will use default value of .*",
logMessages.get(1));
Assert.assertEquals(2, logMessages.size());
}
/**
* Tests the case when an empty paths expression is supplied in the configuration.
* the default value should be used instead, and 2 meaningful error logs should be generated
*/
@Test
public void testEmptyPath() throws Exception {
Dictionary properties = new Hashtable<String, String>();
properties.put("METHODS_TO_LOG", "GET,PUT");
properties.put("PATHS_TO_LOG", "");
properties.put("REMOTE_ADDRESSES_TO_LOG", "127\\.0\\.0\\.1");
properties.put("CONTENT_TO_LOG", ".*loggable.*");
configObject.updated(properties);
Assert.assertEquals(".*", configObject.getProperty("PATHS_TO_LOG"));
Assert.assertEquals("PATHS_TO_LOG is either empty or non-existent", logMessages.get(0));
Assert.assertEquals("Value specified for PATHS_TO_LOG: is invalid. Will use default value of .*",
logMessages.get(1));
Assert.assertEquals(2, logMessages.size());
}
/**
* Tests the case when no paths expression is supplied in the configuration.
* the default value should be used instead, and 2 meaningful error logs should be generated
*/
@Test
public void testNonExistentPath() throws Exception {
Dictionary properties = new Hashtable<String, String>();
properties.put("METHODS_TO_LOG", "GET,PUT");
properties.put("REMOTE_ADDRESSES_TO_LOG", "127\\.0\\.0\\.1");
properties.put("CONTENT_TO_LOG", ".*loggable.*");
configObject.updated(properties);
Assert.assertEquals(".*", configObject.getProperty("PATHS_TO_LOG"));
Assert.assertEquals("PATHS_TO_LOG is either empty or non-existent", logMessages.get(0));
Assert.assertEquals("Value specified for PATHS_TO_LOG: null is invalid. Will use default value of .*",
logMessages.get(1));
Assert.assertEquals(2, logMessages.size());
}
/**
* Tests the case when an invalid regular expression is supplied for the remote addresses in the configuration.
* the default value should be used instead, and 2 meaningful error logs should be generated
*/
@Test
public void testInvalidRemoteAddressesRegex() throws Exception {
Dictionary properties = new Hashtable<String, String>();
properties.put("METHODS_TO_LOG", "GET,PUT");
properties.put("PATHS_TO_LOG", "/operations/*");
properties.put("REMOTE_ADDRESSES_TO_LOG", "(");
properties.put("CONTENT_TO_LOG", ".*loggable.*");
configObject.updated(properties);
Assert.assertEquals(".*", configObject.getProperty("REMOTE_ADDRESSES_TO_LOG"));
Assert.assertEquals(true, logMessages.get(0).startsWith("Pattern ( is not parsable"));
Assert.assertEquals("Value specified for REMOTE_ADDRESSES_TO_LOG: ( is invalid. Will use default value of .*",
logMessages.get(1));
Assert.assertEquals(2, logMessages.size());
}
/**
* Tests the case when an empty remote addresses expression is supplied in the configuration.
* the default value should be used instead, and 2 meaningful error logs should be generated
*/
@Test
public void testEmptyRemoteAddresses() throws Exception {
Dictionary properties = new Hashtable<String, String>();
properties.put("METHODS_TO_LOG", "GET,PUT");
properties.put("PATHS_TO_LOG", "/operations/.*");
properties.put("REMOTE_ADDRESSES_TO_LOG", "");
properties.put("CONTENT_TO_LOG", ".*loggable.*");
configObject.updated(properties);
Assert.assertEquals(".*", configObject.getProperty("REMOTE_ADDRESSES_TO_LOG"));
Assert.assertEquals("REMOTE_ADDRESSES_TO_LOG is either empty or non-existent", logMessages.get(0));
Assert.assertEquals("Value specified for REMOTE_ADDRESSES_TO_LOG: is invalid. Will use default value of .*",
logMessages.get(1));
Assert.assertEquals(2, logMessages.size());
}
/**
* Tests the case when no remote addresses expression is supplied in the configuration.
* the default value should be used instead, and 2 meaningful error logs should be generated
*/
@Test
public void testNonExistentRemoteAddresses() throws Exception {
Dictionary properties = new Hashtable<String, String>();
properties.put("METHODS_TO_LOG", "GET,PUT");
properties.put("PATHS_TO_LOG", "/operations/.*");
properties.put("CONTENT_TO_LOG", ".*loggable.*");
configObject.updated(properties);
Assert.assertEquals(".*", configObject.getProperty("REMOTE_ADDRESSES_TO_LOG"));
Assert.assertEquals("REMOTE_ADDRESSES_TO_LOG is either empty or non-existent", logMessages.get(0));
Assert.assertEquals("Value specified for REMOTE_ADDRESSES_TO_LOG: null "
+ "is invalid. Will use default value of .*", logMessages.get(1));
Assert.assertEquals(2, logMessages.size());
}
/**
* Tests the case when an invalid regular expression is supplied for the content in the configuration.
* the default value should be used instead, and 2 meaningful error logs should be generated
*/
@Test
public void testInvalidContentRegex() throws Exception {
Dictionary properties = new Hashtable<String, String>();
properties.put("METHODS_TO_LOG", "GET,PUT");
properties.put("PATHS_TO_LOG", "/operations/*");
properties.put("REMOTE_ADDRESSES_TO_LOG", "127\\.0\\.0\\.1");
properties.put("CONTENT_TO_LOG", "(");
configObject.updated(properties);
Assert.assertEquals(".*", configObject.getProperty("CONTENT_TO_LOG"));
Assert.assertEquals(true, logMessages.get(0).startsWith("Pattern ( is not parsable"));
Assert.assertEquals("Value specified for CONTENT_TO_LOG: ( is invalid. Will use default value of .*",
logMessages.get(1));
Assert.assertEquals(2, logMessages.size());
}
/**
* Tests the case when an empty content expression is supplied in the configuration.
* the default value should be used instead, and 2 meaningful error logs should be generated
*/
@Test
public void testEmptyContent() throws Exception {
Dictionary properties = new Hashtable<String, String>();
properties.put("METHODS_TO_LOG", "GET,PUT");
properties.put("PATHS_TO_LOG", "/operations/.*");
properties.put("REMOTE_ADDRESSES_TO_LOG", "127\\.0\\.0\\.1");
properties.put("CONTENT_TO_LOG", "");
configObject.updated(properties);
Assert.assertEquals(".*", configObject.getProperty("CONTENT_TO_LOG"));
Assert.assertEquals("CONTENT_TO_LOG is either empty or non-existent", logMessages.get(0));
Assert.assertEquals("Value specified for CONTENT_TO_LOG: is invalid. Will use default value of .*",
logMessages.get(1));
Assert.assertEquals(2, logMessages.size());
}
/**
* Tests the case when no content expression is supplied in the configuration.
* the default value should be used instead, and 2 meaningful error logs should be generated
*/
@Test
public void testNonExistentContent() throws Exception {
Dictionary properties = new Hashtable<String, String>();
properties.put("METHODS_TO_LOG", "GET,PUT");
properties.put("PATHS_TO_LOG", "/operations/.*");
properties.put("REMOTE_ADDRESSES_TO_LOG", "127\\.0\\.0\\.1");
configObject.updated(properties);
Assert.assertEquals(".*", configObject.getProperty("CONTENT_TO_LOG"));
Assert.assertEquals("CONTENT_TO_LOG is either empty or non-existent", logMessages.get(0));
Assert.assertEquals("Value specified for CONTENT_TO_LOG: null is invalid. Will use default value of .*",
logMessages.get(1));
Assert.assertEquals(2, logMessages.size());
}
/**
* Tests the case when no properties at all are supplied in the configuration.
* the default value should be used instead, and 1 meaningful error log should be generated
*/
@Test
public void testEmptyProperties() throws Exception {
Dictionary properties = new Hashtable<String, String>();
configObject.updated(properties);
Assert.assertEquals("POST,PUT,DELETE", configObject.getProperty("METHODS_TO_LOG"));
Assert.assertEquals(".*", configObject.getProperty("PATHS_TO_LOG"));
Assert.assertEquals(".*", configObject.getProperty("REMOTE_ADDRESSES_TO_LOG"));
Assert.assertEquals(".*", configObject.getProperty("CONTENT_TO_LOG"));
Assert.assertEquals("The configuration properties are either empty or "
+ "non-existent will use default values of: METHODS_TO_LOG=POST,PUT,"
+ "DELETE PATHS_TO_LOG=.* REMOTE_ADDRESSES_TO_LOG=.* CONTENT_TO_LOG=.*", logMessages.get(0));
Assert.assertEquals(1, logMessages.size());
}
/**
* Tests the case when no configuration is supplied.
* the default value should be used instead, and 1 meaningful error log should be generated
*/
@Test
public void testNonExistentProperties() throws Exception {
configObject.updated(null);
Assert.assertEquals("POST,PUT,DELETE", configObject.getProperty("METHODS_TO_LOG"));
Assert.assertEquals(".*", configObject.getProperty("PATHS_TO_LOG"));
Assert.assertEquals(".*", configObject.getProperty("REMOTE_ADDRESSES_TO_LOG"));
Assert.assertEquals(".*", configObject.getProperty("CONTENT_TO_LOG"));
Assert.assertEquals("The configuration properties are either empty or "
+ "non-existent will use default values of: METHODS_TO_LOG=POST,PUT,"
+ "DELETE PATHS_TO_LOG=.* REMOTE_ADDRESSES_TO_LOG=.* CONTENT_TO_LOG=.*", logMessages.get(0));
Assert.assertEquals(1, logMessages.size());
}
/**
* tests the cases of getInstance, when an instance doesn't already exist, a new instance should be created.
* When an instance exists, we retrieve the same instance.
*/
@Test
public void getInstanceTest() {
TSDRRestconfCollectorConfig oldInstance = TSDRRestconfCollectorConfig.getInstance();
TSDRRestconfCollectorConfig.setInstance(null);
TSDRRestconfCollectorConfig newInstance = TSDRRestconfCollectorConfig.getInstance();
// Assert that a new instance has actually been created
Assert.assertNotSame(oldInstance, newInstance);
TSDRRestconfCollectorConfig sameInstance = TSDRRestconfCollectorConfig.getInstance();
// Assert that the same old instance was used
Assert.assertSame(newInstance, sameInstance);
}
/**
* called after each test to make sure that the TSDRRestconfCollectorConfig instance is cleaned.
*/
@After
public void teardown() {
TSDRRestconfCollectorConfig.setInstance(null);
}
}