Skip to content

Commit 81d8376

Browse files
committed
test for properties change detection from URL/http
Signed-off-by: Ceki Gulcu <[email protected]>
1 parent a496a04 commit 81d8376

File tree

3 files changed

+178
-139
lines changed

3 files changed

+178
-139
lines changed

logback-classic-blackbox/src/test/java/ch/qos/logback/classic/blackbox/joran/ReconfigureOnChangeTaskTest.java

+3-31
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,12 @@
4848
import static ch.qos.logback.classic.joran.ReconfigureOnChangeTask.*;
4949
import static org.junit.jupiter.api.Assertions.*;
5050

51-
public class ReconfigureOnChangeTaskTest {
51+
public class ReconfigureOnChangeTaskTest extends ReconfigureTaskTestSupport {
5252
final static int THREAD_COUNT = 5;
5353

5454
final static int TIMEOUT = 4;
5555
final static int TIMEOUT_LONG = 10;
5656

57-
int diff = RandomUtil.getPositiveInt();
58-
5957
// the space in the file name mandated by
6058
// http://jira.qos.ch/browse/LOGBACK-67
6159
final static String SCAN1_FILE_AS_STR = JORAN_INPUT_PREFIX + "roct/scan 1.xml";
@@ -72,7 +70,6 @@ public class ReconfigureOnChangeTaskTest {
7270

7371
private static final String SCAN_PERIOD_DEFAULT_FILE_AS_STR = JORAN_INPUT_PREFIX + "roct/scan_period_default.xml";
7472

75-
LoggerContext loggerContext = new LoggerContext();
7673
Logger logger = loggerContext.getLogger(this.getClass());
7774
StatusChecker statusChecker = new StatusChecker(loggerContext);
7875
StatusPrinter2 statusPrinter2 = new StatusPrinter2();
@@ -94,12 +91,6 @@ void configure(File file) throws JoranException {
9491
jc.doConfigure(file);
9592
}
9693

97-
protected void configure(InputStream is) throws JoranException {
98-
JoranConfigurator jc = new JoranConfigurator();
99-
jc.setContext(loggerContext);
100-
jc.doConfigure(is);
101-
}
102-
10394
@Test
10495
@Timeout(value = TIMEOUT, unit = TimeUnit.SECONDS)
10596
public void checkBasicLifecyle() throws JoranException, IOException, InterruptedException {
@@ -141,7 +132,7 @@ public void scanWithFileInclusion() throws JoranException, IOException, Interrup
141132
}
142133

143134
@Test
144-
//@Timeout(value = TIMEOUT, unit = TimeUnit.SECONDS)
135+
@Timeout(value = TIMEOUT, unit = TimeUnit.SECONDS)
145136
public void scanWithResourceInclusion() throws JoranException, IOException, InterruptedException {
146137
File topLevelFile = new File(INCLUSION_SCAN_TOP_BY_RESOURCE_AS_STR);
147138
File innerFile = new File(INCLUSION_SCAN_INNER1_AS_STR);
@@ -157,7 +148,7 @@ public void propertiesConfigurationTest() throws IOException, JoranException, In
157148
String loggerName = "abc";
158149
String propertiesFileStr = CoreTestConstants.OUTPUT_DIR_PREFIX + "roct-" + diff + ".properties";
159150
File propertiesFile = new File(propertiesFileStr);
160-
String configurationStr = "<configuration debug=\"true\" scan=\"true\" scanPeriod=\"1 millisecond\"><propertiesConfigurator file=\"" + propertiesFileStr + "\"/></configuration>";
151+
String configurationStr = "<configuration debug=\"true\" scan=\"true\" scanPeriod=\"10 millisecond\"><propertiesConfigurator file=\"" + propertiesFileStr + "\"/></configuration>";
161152
writeToFile(propertiesFile, PropertiesConfigurator.LOGBACK_LOGGER_PREFIX + loggerName+"=INFO");
162153
configure(asBAIS(configurationStr));
163154
Logger abcLogger = loggerContext.getLogger(loggerName);
@@ -171,7 +162,6 @@ public void propertiesConfigurationTest() throws IOException, JoranException, In
171162
configurationDoneLatch0.await();
172163
assertEquals(Level.WARN, abcLogger.getLevel());
173164

174-
175165
CountDownLatch changeDetectedLatch1 = registerChangeDetectedListener();
176166
CountDownLatch configurationDoneLatch1 = registerPartialConfigurationEndedSuccessfullyEventListener();
177167
writeToFile(propertiesFile, PropertiesConfigurator.LOGBACK_LOGGER_PREFIX + loggerName+"=ERROR");
@@ -222,10 +212,6 @@ public void reconfigurationIsNotPossibleInTheAbsenceOfATopFile() throws IOExcept
222212
assertEquals(0, loggerContext.getCopyOfScheduledFutures().size());
223213
}
224214

225-
private static ByteArrayInputStream asBAIS(String configurationStr) throws UnsupportedEncodingException {
226-
return new ByteArrayInputStream(configurationStr.getBytes("UTF-8"));
227-
}
228-
229215
@Test
230216
@Timeout(value = TIMEOUT, unit = TimeUnit.SECONDS)
231217
public void fallbackToSafe_FollowedByRecovery() throws IOException, JoranException, InterruptedException {
@@ -335,20 +321,6 @@ CountDownLatch registerNewReconfigurationDoneSuccessfullyListener(ReconfigureOnC
335321
return latch;
336322
}
337323

338-
CountDownLatch registerPartialConfigurationEndedSuccessfullyEventListener() {
339-
CountDownLatch latch = new CountDownLatch(1);
340-
PartialConfigurationEndedSuccessfullyEventListener listener = new PartialConfigurationEndedSuccessfullyEventListener(latch);
341-
loggerContext.addConfigurationEventListener(listener);
342-
return latch;
343-
}
344-
345-
CountDownLatch registerChangeDetectedListener() {
346-
CountDownLatch latch = new CountDownLatch(1);
347-
ChangeDetectedListener changeDetectedListener = new ChangeDetectedListener(latch);
348-
loggerContext.addConfigurationEventListener(changeDetectedListener);
349-
return latch;
350-
}
351-
352324
class RunMethodInvokedListener implements ConfigurationEventListener {
353325
CountDownLatch countDownLatch;
354326
ReconfigureOnChangeTask reconfigureOnChangeTask;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Logback: the reliable, generic, fast and flexible logging framework.
3+
* Copyright (C) 1999-2024, QOS.ch. All rights reserved.
4+
*
5+
* This program and the accompanying materials are dual-licensed under
6+
* either the terms of the Eclipse Public License v1.0 as published by
7+
* the Eclipse Foundation
8+
*
9+
* or (per the licensee's choosing)
10+
*
11+
* under the terms of the GNU Lesser General Public License version 2.1
12+
* as published by the Free Software Foundation.
13+
*/
14+
15+
package ch.qos.logback.classic.blackbox.joran;
16+
17+
import ch.qos.logback.classic.LoggerContext;
18+
import ch.qos.logback.classic.blackbox.joran.spi.ConfigFileServlet;
19+
import ch.qos.logback.classic.joran.JoranConfigurator;
20+
import ch.qos.logback.core.CoreConstants;
21+
import ch.qos.logback.core.joran.spi.HttpUtil;
22+
import ch.qos.logback.core.joran.spi.JoranException;
23+
import ch.qos.logback.core.testUtil.RandomUtil;
24+
25+
import java.io.ByteArrayInputStream;
26+
import java.io.InputStream;
27+
import java.io.UnsupportedEncodingException;
28+
import java.net.HttpURLConnection;
29+
import java.net.MalformedURLException;
30+
import java.util.concurrent.CountDownLatch;
31+
32+
public class ReconfigureTaskTestSupport {
33+
34+
protected int diff = RandomUtil.getPositiveInt();
35+
protected LoggerContext loggerContext = new LoggerContext();
36+
37+
protected void configure(InputStream is) throws JoranException {
38+
JoranConfigurator jc = new JoranConfigurator();
39+
jc.setContext(loggerContext);
40+
jc.doConfigure(is);
41+
}
42+
43+
protected CountDownLatch registerChangeDetectedListener() {
44+
CountDownLatch latch = new CountDownLatch(1);
45+
ChangeDetectedListener changeDetectedListener = new ChangeDetectedListener(latch);
46+
loggerContext.addConfigurationEventListener(changeDetectedListener);
47+
return latch;
48+
}
49+
50+
protected static ByteArrayInputStream asBAIS(String configurationStr) throws UnsupportedEncodingException {
51+
return new ByteArrayInputStream(configurationStr.getBytes("UTF-8"));
52+
}
53+
54+
protected String get(String urlString) throws MalformedURLException {
55+
HttpUtil httpGetUtil = new HttpUtil(HttpUtil.RequestMethod.GET, urlString);
56+
HttpURLConnection getConnection = httpGetUtil.connectTextTxt();
57+
String response = httpGetUtil.readResponse(getConnection);
58+
return response;
59+
}
60+
61+
protected String post(String urlString, String val) throws MalformedURLException {
62+
HttpUtil httpPostUtil1 = new HttpUtil(HttpUtil.RequestMethod.POST, urlString);
63+
HttpURLConnection postConnection1 = httpPostUtil1.connectTextTxt();
64+
httpPostUtil1.post(postConnection1, ConfigFileServlet.CONTENT_KEY+ CoreConstants.EQUALS_CHAR+val);
65+
String response = httpPostUtil1.readResponse(postConnection1);
66+
return response;
67+
}
68+
69+
protected CountDownLatch registerPartialConfigurationEndedSuccessfullyEventListener() {
70+
CountDownLatch latch = new CountDownLatch(1);
71+
PartialConfigurationEndedSuccessfullyEventListener listener = new PartialConfigurationEndedSuccessfullyEventListener(latch);
72+
loggerContext.addConfigurationEventListener(listener);
73+
return latch;
74+
}
75+
}

logback-classic-blackbox/src/test/java/ch/qos/logback/classic/blackbox/joran/spi/ConfigurationWatchListTest.java

+100-108
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@
1717
import ch.qos.logback.classic.Level;
1818
import ch.qos.logback.classic.Logger;
1919
import ch.qos.logback.classic.LoggerContext;
20-
import ch.qos.logback.classic.joran.JoranConfigurator;
21-
//import ch.qos.logback.classic.blackbox.joran.ReconfigureOnChangeTaskTest;
22-
//import ch.qos.logback.classic.blackbox.joran.ReconfigureOnChangeTaskTest;
20+
import ch.qos.logback.classic.blackbox.joran.ReconfigureOnChangeTaskTest;
21+
import ch.qos.logback.classic.blackbox.joran.ReconfigureTaskTestSupport;
2322
import ch.qos.logback.core.CoreConstants;
2423
import ch.qos.logback.core.joran.spi.ConfigurationWatchList;
2524
import ch.qos.logback.core.joran.spi.HttpUtil;
@@ -32,118 +31,111 @@
3231
import org.junit.jupiter.api.Test;
3332
import org.slf4j.LoggerFactory;
3433

35-
import java.io.ByteArrayInputStream;
36-
import java.io.InputStream;
3734
import java.io.UnsupportedEncodingException;
3835
import java.net.HttpURLConnection;
3936
import java.net.MalformedURLException;
4037
import java.net.URL;
4138
import java.util.concurrent.CountDownLatch;
39+
import java.util.concurrent.TimeUnit;
4240

4341
import static org.junit.jupiter.api.Assertions.*;
4442

45-
public class ConfigurationWatchListTest {
46-
47-
48-
// static String BAZINGA_LOGGER_0 = "logback.logger.com.bazinga=WARN";
49-
// static String BAZINGA_LOGGER_1 = "logback.logger.com.bazinga=ERROR"
50-
//
51-
// int randomPort = RandomUtil.getRandomServerPort();
52-
// ConfigEmbeddedJetty configEmbeddedJetty;
53-
// LoggerContext loggerContext = new LoggerContext();
54-
// ConfigurationWatchList cwl = new ConfigurationWatchList();
55-
// String urlString = "http://127.0.0.1:"+randomPort+"/";
56-
//
57-
// @BeforeEach
58-
// public void setUp() throws Exception {
59-
// Logger rootLogger = (Logger) LoggerFactory.getLogger( Logger.ROOT_LOGGER_NAME );
60-
// rootLogger.setLevel(Level.INFO);
61-
//
62-
// configEmbeddedJetty = new ConfigEmbeddedJetty(randomPort);
63-
//
64-
// cwl.setContext(loggerContext);
65-
//
66-
// HttpServlet configServlet = new ConfigFileServlet();
67-
// configEmbeddedJetty.getServletMap().put("/", configServlet);
68-
// //configEmbeddedJetty.getServletMap().put("/mod", configServlet);
69-
//
70-
// configEmbeddedJetty.init();
71-
//
72-
// }
73-
//
74-
// @AfterEach
75-
// public void tearDown() throws Exception {
76-
// configEmbeddedJetty.stop();
77-
// }
78-
//
79-
// @Test
80-
// public void testInfrastructure() throws MalformedURLException {
81-
// HttpUtil httpGetUtil0 = new HttpUtil(HttpUtil.RequestMethod.GET, urlString);
82-
//
83-
// HttpURLConnection getConnection0 = httpGetUtil0.connectTextTxt();
84-
// String response = httpGetUtil0.readResponse(getConnection0);
85-
// assertNotNull(response);
86-
// Assertions.assertEquals(ConfigFileServlet.DEFAULT_CONTENT, response);
87-
//
88-
// HttpUtil httpPostUtil1 = new HttpUtil(HttpUtil.RequestMethod.POST, urlString);
89-
// HttpURLConnection postConnection1 = httpPostUtil1.connectTextTxt();
90-
// String setResponse1 = "bla bla";
91-
// httpPostUtil1.post(postConnection1, ConfigFileServlet.CONTENT_KEY+ CoreConstants.EQUALS_CHAR+setResponse1);
92-
//
93-
// String response1 = httpPostUtil1.readResponse(postConnection1);
94-
// assertEquals(response1, setResponse1);
95-
// //System.out.println( "POST response1="+response1);
96-
// HttpUtil httpGetUtil2 = new HttpUtil(HttpUtil.RequestMethod.GET, urlString);
97-
//
98-
// HttpURLConnection getConnection2 = httpGetUtil2.connectTextTxt();
99-
// String response2 = httpGetUtil2.readResponse(getConnection2);
100-
// assertEquals(response1, response2);
101-
//
102-
// }
103-
//
104-
// @Test
105-
// public void smoke() throws MalformedURLException {
106-
// URL url = new URL(urlString);
107-
// cwl.addToWatchList(url);
108-
// URL changedURL0 = cwl.changeDetectedInURL();
109-
// assertNull(changedURL0);
110-
// HttpUtil httpPostUtil1 = new HttpUtil(HttpUtil.RequestMethod.POST, urlString);
111-
// HttpURLConnection postConnection1 = httpPostUtil1.connectTextTxt();
112-
// String setResponse1 = "bla bla";
113-
// httpPostUtil1.post(postConnection1, ConfigFileServlet.CONTENT_KEY+ CoreConstants.EQUALS_CHAR+setResponse1);
114-
//
115-
// String response1 = httpPostUtil1.readResponse(postConnection1);
116-
// assertEquals(response1, setResponse1);
117-
// URL changedURL1 = cwl.changeDetectedInURL();
118-
// assertEquals(urlString, changedURL1.toString());
119-
//
120-
// URL changedURL2 = cwl.changeDetectedInURL();
121-
// assertNull(changedURL2);
122-
//
123-
// URL changedURL3 = cwl.changeDetectedInURL();
124-
// assertNull(changedURL3);
125-
// }
126-
//
127-
//
128-
// @Test
129-
// public void propertiesFromHTTP() throws UnsupportedEncodingException, JoranException {
130-
// String loggerName = "com.bazinga";
131-
// String propertiesURLStr = "https://127.0.0.1:"+randomPort+"/";
132-
// Logger aLogger = loggerContext.getLogger(loggerName);
133-
// String configurationStr = "<configuration debug=\"true\" scan=\"true\" scanPeriod=\"10 millisecond\"><propertiesConfigurator url=\"" + propertiesURLStr + "\"/></configuration>";
134-
//
135-
// configure(asBAIS(configurationStr));
136-
//
137-
// assertEquals(Level.WARN, aLogger.getLevel());
138-
// System.out.println("first phase OK");
139-
// CountDownLatch changeDetectedLatch0 = registerChangeDetectedListener();
140-
// CountDownLatch configurationDoneLatch0 = registerPartialConfigurationEndedSuccessfullyEventListener();
141-
//
142-
// changeDetectedLatch0.await();
143-
// System.out.println("after changeDetectedLatch0.await();");
144-
// configurationDoneLatch0.await();
145-
// assertEquals(Level.ERROR, aLogger.getLevel());
146-
// }
147-
//
43+
public class ConfigurationWatchListTest extends ReconfigureTaskTestSupport {
44+
45+
static String BAZINGA_LOGGER_NAME = "com.bazinga";
46+
static String BAZINGA_LOGGER_SETUP_0 = "logback.logger."+BAZINGA_LOGGER_NAME+"=WARN";
47+
static String BAZINGA_LOGGER_SETUP_1 = "logback.logger."+BAZINGA_LOGGER_NAME+"=ERROR";
48+
49+
int randomPort = RandomUtil.getRandomServerPort();
50+
ConfigEmbeddedJetty configEmbeddedJetty;
51+
ConfigurationWatchList cwl = new ConfigurationWatchList();
52+
static String FOO_PROPERTIES = "/foo.properties";
53+
String urlString = "http://127.0.0.1:"+randomPort+FOO_PROPERTIES;
54+
55+
@BeforeEach
56+
public void setUp() throws Exception {
57+
Logger rootLogger = (Logger) LoggerFactory.getLogger( Logger.ROOT_LOGGER_NAME );
58+
rootLogger.setLevel(Level.INFO);
59+
60+
configEmbeddedJetty = new ConfigEmbeddedJetty(randomPort);
61+
62+
cwl.setContext(loggerContext);
63+
64+
HttpServlet configServlet = new ConfigFileServlet(BAZINGA_LOGGER_SETUP_0);
65+
configEmbeddedJetty.getServletMap().put(FOO_PROPERTIES, configServlet);
66+
67+
configEmbeddedJetty.init();
68+
69+
}
70+
71+
@AfterEach
72+
public void tearDown() throws Exception {
73+
configEmbeddedJetty.stop();
74+
}
75+
76+
77+
78+
@Test
79+
public void testInfrastructure() throws MalformedURLException {
80+
String response = get(urlString);
81+
assertNotNull(response);
82+
Assertions.assertEquals(BAZINGA_LOGGER_SETUP_0, response);
83+
84+
String setResponse1 = "bla bla";
85+
String response1 = post(urlString, setResponse1);
86+
assertEquals(response1, setResponse1);
87+
88+
String response2 = get(urlString);
89+
assertEquals(response1, response2);
90+
}
91+
92+
@Test
93+
public void smoke() throws MalformedURLException {
94+
URL url = new URL(urlString);
95+
cwl.addToWatchList(url);
96+
URL changedURL0 = cwl.changeDetectedInURL();
97+
assertNull(changedURL0);
98+
99+
String setResponse1 = "bla bla";
100+
String response1 = post(urlString, setResponse1);
101+
assertEquals(response1, setResponse1);
102+
103+
URL changedURL1 = cwl.changeDetectedInURL();
104+
assertEquals(urlString, changedURL1.toString());
105+
106+
URL changedURL2 = cwl.changeDetectedInURL();
107+
assertNull(changedURL2);
108+
109+
URL changedURL3 = cwl.changeDetectedInURL();
110+
assertNull(changedURL3);
111+
}
112+
113+
@Test
114+
public void propertiesFromHTTP() throws UnsupportedEncodingException, JoranException, InterruptedException, MalformedURLException {
115+
116+
String propertiesURLStr = urlString;
117+
Logger bazingaLogger = loggerContext.getLogger(BAZINGA_LOGGER_NAME);
118+
119+
assertEquals(BAZINGA_LOGGER_SETUP_0, get(urlString));
120+
121+
String configurationStr = "<configuration debug=\"true\" scan=\"true\" scanPeriod=\"1 millisecond\"><propertiesConfigurator url=\"" + propertiesURLStr + "\"/></configuration>";
122+
123+
configure(asBAIS(configurationStr));
124+
125+
// allow for the first update
126+
Thread.sleep(50);
127+
assertEquals(Level.WARN, bazingaLogger.getLevel());
128+
System.out.println("first test passed with success");
129+
130+
CountDownLatch changeDetectedLatch0 = registerChangeDetectedListener();
131+
CountDownLatch configurationDoneLatch0 = registerPartialConfigurationEndedSuccessfullyEventListener();
132+
133+
String response1 = post(urlString, BAZINGA_LOGGER_SETUP_1);
134+
assertEquals(BAZINGA_LOGGER_SETUP_1, get(urlString));
135+
136+
changeDetectedLatch0.await(100, TimeUnit.MICROSECONDS);
137+
configurationDoneLatch0.await(100, TimeUnit.MICROSECONDS);
138+
assertEquals(Level.ERROR, bazingaLogger.getLevel());
139+
}
148140

149141
}

0 commit comments

Comments
 (0)