/* * 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); } }