diff --git a/logback-classic-blackbox/src/test/java/ch/qos/logback/classic/blackbox/joran/ReconfigureOnChangeTaskTest.java b/logback-classic-blackbox/src/test/java/ch/qos/logback/classic/blackbox/joran/ReconfigureOnChangeTaskTest.java index 60490a03c4..da14d3cb9b 100644 --- a/logback-classic-blackbox/src/test/java/ch/qos/logback/classic/blackbox/joran/ReconfigureOnChangeTaskTest.java +++ b/logback-classic-blackbox/src/test/java/ch/qos/logback/classic/blackbox/joran/ReconfigureOnChangeTaskTest.java @@ -48,14 +48,12 @@ import static ch.qos.logback.classic.joran.ReconfigureOnChangeTask.*; import static org.junit.jupiter.api.Assertions.*; -public class ReconfigureOnChangeTaskTest { +public class ReconfigureOnChangeTaskTest extends ReconfigureTaskTestSupport { final static int THREAD_COUNT = 5; final static int TIMEOUT = 4; final static int TIMEOUT_LONG = 10; - int diff = RandomUtil.getPositiveInt(); - // the space in the file name mandated by // http://jira.qos.ch/browse/LOGBACK-67 final static String SCAN1_FILE_AS_STR = JORAN_INPUT_PREFIX + "roct/scan 1.xml"; @@ -72,7 +70,6 @@ public class ReconfigureOnChangeTaskTest { private static final String SCAN_PERIOD_DEFAULT_FILE_AS_STR = JORAN_INPUT_PREFIX + "roct/scan_period_default.xml"; - LoggerContext loggerContext = new LoggerContext(); Logger logger = loggerContext.getLogger(this.getClass()); StatusChecker statusChecker = new StatusChecker(loggerContext); StatusPrinter2 statusPrinter2 = new StatusPrinter2(); @@ -94,12 +91,6 @@ void configure(File file) throws JoranException { jc.doConfigure(file); } - protected void configure(InputStream is) throws JoranException { - JoranConfigurator jc = new JoranConfigurator(); - jc.setContext(loggerContext); - jc.doConfigure(is); - } - @Test @Timeout(value = TIMEOUT, unit = TimeUnit.SECONDS) public void checkBasicLifecyle() throws JoranException, IOException, InterruptedException { @@ -141,7 +132,7 @@ public void scanWithFileInclusion() throws JoranException, IOException, Interrup } @Test - //@Timeout(value = TIMEOUT, unit = TimeUnit.SECONDS) + @Timeout(value = TIMEOUT, unit = TimeUnit.SECONDS) public void scanWithResourceInclusion() throws JoranException, IOException, InterruptedException { File topLevelFile = new File(INCLUSION_SCAN_TOP_BY_RESOURCE_AS_STR); File innerFile = new File(INCLUSION_SCAN_INNER1_AS_STR); @@ -157,7 +148,7 @@ public void propertiesConfigurationTest() throws IOException, JoranException, In String loggerName = "abc"; String propertiesFileStr = CoreTestConstants.OUTPUT_DIR_PREFIX + "roct-" + diff + ".properties"; File propertiesFile = new File(propertiesFileStr); - String configurationStr = ""; + String configurationStr = ""; writeToFile(propertiesFile, PropertiesConfigurator.LOGBACK_LOGGER_PREFIX + loggerName+"=INFO"); configure(asBAIS(configurationStr)); Logger abcLogger = loggerContext.getLogger(loggerName); @@ -171,7 +162,6 @@ public void propertiesConfigurationTest() throws IOException, JoranException, In configurationDoneLatch0.await(); assertEquals(Level.WARN, abcLogger.getLevel()); - CountDownLatch changeDetectedLatch1 = registerChangeDetectedListener(); CountDownLatch configurationDoneLatch1 = registerPartialConfigurationEndedSuccessfullyEventListener(); writeToFile(propertiesFile, PropertiesConfigurator.LOGBACK_LOGGER_PREFIX + loggerName+"=ERROR"); @@ -222,10 +212,6 @@ public void reconfigurationIsNotPossibleInTheAbsenceOfATopFile() throws IOExcept assertEquals(0, loggerContext.getCopyOfScheduledFutures().size()); } - private static ByteArrayInputStream asBAIS(String configurationStr) throws UnsupportedEncodingException { - return new ByteArrayInputStream(configurationStr.getBytes("UTF-8")); - } - @Test @Timeout(value = TIMEOUT, unit = TimeUnit.SECONDS) public void fallbackToSafe_FollowedByRecovery() throws IOException, JoranException, InterruptedException { @@ -335,20 +321,6 @@ CountDownLatch registerNewReconfigurationDoneSuccessfullyListener(ReconfigureOnC return latch; } - CountDownLatch registerPartialConfigurationEndedSuccessfullyEventListener() { - CountDownLatch latch = new CountDownLatch(1); - PartialConfigurationEndedSuccessfullyEventListener listener = new PartialConfigurationEndedSuccessfullyEventListener(latch); - loggerContext.addConfigurationEventListener(listener); - return latch; - } - - CountDownLatch registerChangeDetectedListener() { - CountDownLatch latch = new CountDownLatch(1); - ChangeDetectedListener changeDetectedListener = new ChangeDetectedListener(latch); - loggerContext.addConfigurationEventListener(changeDetectedListener); - return latch; - } - class RunMethodInvokedListener implements ConfigurationEventListener { CountDownLatch countDownLatch; ReconfigureOnChangeTask reconfigureOnChangeTask; diff --git a/logback-classic-blackbox/src/test/java/ch/qos/logback/classic/blackbox/joran/ReconfigureTaskTestSupport.java b/logback-classic-blackbox/src/test/java/ch/qos/logback/classic/blackbox/joran/ReconfigureTaskTestSupport.java new file mode 100644 index 0000000000..1dac55d916 --- /dev/null +++ b/logback-classic-blackbox/src/test/java/ch/qos/logback/classic/blackbox/joran/ReconfigureTaskTestSupport.java @@ -0,0 +1,75 @@ +/* + * Logback: the reliable, generic, fast and flexible logging framework. + * Copyright (C) 1999-2024, QOS.ch. All rights reserved. + * + * This program and the accompanying materials are dual-licensed under + * either the terms of the Eclipse Public License v1.0 as published by + * the Eclipse Foundation + * + * or (per the licensee's choosing) + * + * under the terms of the GNU Lesser General Public License version 2.1 + * as published by the Free Software Foundation. + */ + +package ch.qos.logback.classic.blackbox.joran; + +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.blackbox.joran.spi.ConfigFileServlet; +import ch.qos.logback.classic.joran.JoranConfigurator; +import ch.qos.logback.core.CoreConstants; +import ch.qos.logback.core.joran.spi.HttpUtil; +import ch.qos.logback.core.joran.spi.JoranException; +import ch.qos.logback.core.testUtil.RandomUtil; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.util.concurrent.CountDownLatch; + +public class ReconfigureTaskTestSupport { + + protected int diff = RandomUtil.getPositiveInt(); + protected LoggerContext loggerContext = new LoggerContext(); + + protected void configure(InputStream is) throws JoranException { + JoranConfigurator jc = new JoranConfigurator(); + jc.setContext(loggerContext); + jc.doConfigure(is); + } + + protected CountDownLatch registerChangeDetectedListener() { + CountDownLatch latch = new CountDownLatch(1); + ChangeDetectedListener changeDetectedListener = new ChangeDetectedListener(latch); + loggerContext.addConfigurationEventListener(changeDetectedListener); + return latch; + } + + protected static ByteArrayInputStream asBAIS(String configurationStr) throws UnsupportedEncodingException { + return new ByteArrayInputStream(configurationStr.getBytes("UTF-8")); + } + + protected String get(String urlString) throws MalformedURLException { + HttpUtil httpGetUtil = new HttpUtil(HttpUtil.RequestMethod.GET, urlString); + HttpURLConnection getConnection = httpGetUtil.connectTextTxt(); + String response = httpGetUtil.readResponse(getConnection); + return response; + } + + protected String post(String urlString, String val) throws MalformedURLException { + HttpUtil httpPostUtil1 = new HttpUtil(HttpUtil.RequestMethod.POST, urlString); + HttpURLConnection postConnection1 = httpPostUtil1.connectTextTxt(); + httpPostUtil1.post(postConnection1, ConfigFileServlet.CONTENT_KEY+ CoreConstants.EQUALS_CHAR+val); + String response = httpPostUtil1.readResponse(postConnection1); + return response; + } + + protected CountDownLatch registerPartialConfigurationEndedSuccessfullyEventListener() { + CountDownLatch latch = new CountDownLatch(1); + PartialConfigurationEndedSuccessfullyEventListener listener = new PartialConfigurationEndedSuccessfullyEventListener(latch); + loggerContext.addConfigurationEventListener(listener); + return latch; + } +} diff --git a/logback-classic-blackbox/src/test/java/ch/qos/logback/classic/blackbox/joran/spi/ConfigurationWatchListTest.java b/logback-classic-blackbox/src/test/java/ch/qos/logback/classic/blackbox/joran/spi/ConfigurationWatchListTest.java index 98c6365fb1..dd9faecef3 100644 --- a/logback-classic-blackbox/src/test/java/ch/qos/logback/classic/blackbox/joran/spi/ConfigurationWatchListTest.java +++ b/logback-classic-blackbox/src/test/java/ch/qos/logback/classic/blackbox/joran/spi/ConfigurationWatchListTest.java @@ -17,9 +17,8 @@ import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.LoggerContext; -import ch.qos.logback.classic.joran.JoranConfigurator; -//import ch.qos.logback.classic.blackbox.joran.ReconfigureOnChangeTaskTest; -//import ch.qos.logback.classic.blackbox.joran.ReconfigureOnChangeTaskTest; +import ch.qos.logback.classic.blackbox.joran.ReconfigureOnChangeTaskTest; +import ch.qos.logback.classic.blackbox.joran.ReconfigureTaskTestSupport; import ch.qos.logback.core.CoreConstants; import ch.qos.logback.core.joran.spi.ConfigurationWatchList; import ch.qos.logback.core.joran.spi.HttpUtil; @@ -32,118 +31,111 @@ import org.junit.jupiter.api.Test; import org.slf4j.LoggerFactory; -import java.io.ByteArrayInputStream; -import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import static org.junit.jupiter.api.Assertions.*; -public class ConfigurationWatchListTest { - - -// static String BAZINGA_LOGGER_0 = "logback.logger.com.bazinga=WARN"; -// static String BAZINGA_LOGGER_1 = "logback.logger.com.bazinga=ERROR" -// -// int randomPort = RandomUtil.getRandomServerPort(); -// ConfigEmbeddedJetty configEmbeddedJetty; -// LoggerContext loggerContext = new LoggerContext(); -// ConfigurationWatchList cwl = new ConfigurationWatchList(); -// String urlString = "http://127.0.0.1:"+randomPort+"/"; -// -// @BeforeEach -// public void setUp() throws Exception { -// Logger rootLogger = (Logger) LoggerFactory.getLogger( Logger.ROOT_LOGGER_NAME ); -// rootLogger.setLevel(Level.INFO); -// -// configEmbeddedJetty = new ConfigEmbeddedJetty(randomPort); -// -// cwl.setContext(loggerContext); -// -// HttpServlet configServlet = new ConfigFileServlet(); -// configEmbeddedJetty.getServletMap().put("/", configServlet); -// //configEmbeddedJetty.getServletMap().put("/mod", configServlet); -// -// configEmbeddedJetty.init(); -// -// } -// -// @AfterEach -// public void tearDown() throws Exception { -// configEmbeddedJetty.stop(); -// } -// -// @Test -// public void testInfrastructure() throws MalformedURLException { -// HttpUtil httpGetUtil0 = new HttpUtil(HttpUtil.RequestMethod.GET, urlString); -// -// HttpURLConnection getConnection0 = httpGetUtil0.connectTextTxt(); -// String response = httpGetUtil0.readResponse(getConnection0); -// assertNotNull(response); -// Assertions.assertEquals(ConfigFileServlet.DEFAULT_CONTENT, response); -// -// HttpUtil httpPostUtil1 = new HttpUtil(HttpUtil.RequestMethod.POST, urlString); -// HttpURLConnection postConnection1 = httpPostUtil1.connectTextTxt(); -// String setResponse1 = "bla bla"; -// httpPostUtil1.post(postConnection1, ConfigFileServlet.CONTENT_KEY+ CoreConstants.EQUALS_CHAR+setResponse1); -// -// String response1 = httpPostUtil1.readResponse(postConnection1); -// assertEquals(response1, setResponse1); -// //System.out.println( "POST response1="+response1); -// HttpUtil httpGetUtil2 = new HttpUtil(HttpUtil.RequestMethod.GET, urlString); -// -// HttpURLConnection getConnection2 = httpGetUtil2.connectTextTxt(); -// String response2 = httpGetUtil2.readResponse(getConnection2); -// assertEquals(response1, response2); -// -// } -// -// @Test -// public void smoke() throws MalformedURLException { -// URL url = new URL(urlString); -// cwl.addToWatchList(url); -// URL changedURL0 = cwl.changeDetectedInURL(); -// assertNull(changedURL0); -// HttpUtil httpPostUtil1 = new HttpUtil(HttpUtil.RequestMethod.POST, urlString); -// HttpURLConnection postConnection1 = httpPostUtil1.connectTextTxt(); -// String setResponse1 = "bla bla"; -// httpPostUtil1.post(postConnection1, ConfigFileServlet.CONTENT_KEY+ CoreConstants.EQUALS_CHAR+setResponse1); -// -// String response1 = httpPostUtil1.readResponse(postConnection1); -// assertEquals(response1, setResponse1); -// URL changedURL1 = cwl.changeDetectedInURL(); -// assertEquals(urlString, changedURL1.toString()); -// -// URL changedURL2 = cwl.changeDetectedInURL(); -// assertNull(changedURL2); -// -// URL changedURL3 = cwl.changeDetectedInURL(); -// assertNull(changedURL3); -// } -// -// -// @Test -// public void propertiesFromHTTP() throws UnsupportedEncodingException, JoranException { -// String loggerName = "com.bazinga"; -// String propertiesURLStr = "https://127.0.0.1:"+randomPort+"/"; -// Logger aLogger = loggerContext.getLogger(loggerName); -// String configurationStr = ""; -// -// configure(asBAIS(configurationStr)); -// -// assertEquals(Level.WARN, aLogger.getLevel()); -// System.out.println("first phase OK"); -// CountDownLatch changeDetectedLatch0 = registerChangeDetectedListener(); -// CountDownLatch configurationDoneLatch0 = registerPartialConfigurationEndedSuccessfullyEventListener(); -// -// changeDetectedLatch0.await(); -// System.out.println("after changeDetectedLatch0.await();"); -// configurationDoneLatch0.await(); -// assertEquals(Level.ERROR, aLogger.getLevel()); -// } -// +public class ConfigurationWatchListTest extends ReconfigureTaskTestSupport { + + static String BAZINGA_LOGGER_NAME = "com.bazinga"; + static String BAZINGA_LOGGER_SETUP_0 = "logback.logger."+BAZINGA_LOGGER_NAME+"=WARN"; + static String BAZINGA_LOGGER_SETUP_1 = "logback.logger."+BAZINGA_LOGGER_NAME+"=ERROR"; + + int randomPort = RandomUtil.getRandomServerPort(); + ConfigEmbeddedJetty configEmbeddedJetty; + ConfigurationWatchList cwl = new ConfigurationWatchList(); + static String FOO_PROPERTIES = "/foo.properties"; + String urlString = "http://127.0.0.1:"+randomPort+FOO_PROPERTIES; + + @BeforeEach + public void setUp() throws Exception { + Logger rootLogger = (Logger) LoggerFactory.getLogger( Logger.ROOT_LOGGER_NAME ); + rootLogger.setLevel(Level.INFO); + + configEmbeddedJetty = new ConfigEmbeddedJetty(randomPort); + + cwl.setContext(loggerContext); + + HttpServlet configServlet = new ConfigFileServlet(BAZINGA_LOGGER_SETUP_0); + configEmbeddedJetty.getServletMap().put(FOO_PROPERTIES, configServlet); + + configEmbeddedJetty.init(); + + } + + @AfterEach + public void tearDown() throws Exception { + configEmbeddedJetty.stop(); + } + + + + @Test + public void testInfrastructure() throws MalformedURLException { + String response = get(urlString); + assertNotNull(response); + Assertions.assertEquals(BAZINGA_LOGGER_SETUP_0, response); + + String setResponse1 = "bla bla"; + String response1 = post(urlString, setResponse1); + assertEquals(response1, setResponse1); + + String response2 = get(urlString); + assertEquals(response1, response2); + } + + @Test + public void smoke() throws MalformedURLException { + URL url = new URL(urlString); + cwl.addToWatchList(url); + URL changedURL0 = cwl.changeDetectedInURL(); + assertNull(changedURL0); + + String setResponse1 = "bla bla"; + String response1 = post(urlString, setResponse1); + assertEquals(response1, setResponse1); + + URL changedURL1 = cwl.changeDetectedInURL(); + assertEquals(urlString, changedURL1.toString()); + + URL changedURL2 = cwl.changeDetectedInURL(); + assertNull(changedURL2); + + URL changedURL3 = cwl.changeDetectedInURL(); + assertNull(changedURL3); + } + + @Test + public void propertiesFromHTTP() throws UnsupportedEncodingException, JoranException, InterruptedException, MalformedURLException { + + String propertiesURLStr = urlString; + Logger bazingaLogger = loggerContext.getLogger(BAZINGA_LOGGER_NAME); + + assertEquals(BAZINGA_LOGGER_SETUP_0, get(urlString)); + + String configurationStr = ""; + + configure(asBAIS(configurationStr)); + + // allow for the first update + Thread.sleep(50); + assertEquals(Level.WARN, bazingaLogger.getLevel()); + System.out.println("first test passed with success"); + + CountDownLatch changeDetectedLatch0 = registerChangeDetectedListener(); + CountDownLatch configurationDoneLatch0 = registerPartialConfigurationEndedSuccessfullyEventListener(); + + String response1 = post(urlString, BAZINGA_LOGGER_SETUP_1); + assertEquals(BAZINGA_LOGGER_SETUP_1, get(urlString)); + + changeDetectedLatch0.await(100, TimeUnit.MICROSECONDS); + configurationDoneLatch0.await(100, TimeUnit.MICROSECONDS); + assertEquals(Level.ERROR, bazingaLogger.getLevel()); + } }