2323import static org .junit .Assert .assertTrue ;
2424import static org .junit .Assert .fail ;
2525import java .io .File ;
26+ import java .io .IOException ;
2627import java .net .BindException ;
2728import java .net .SocketException ;
2829import java .net .URI ;
2930import java .security .PrivilegedExceptionAction ;
3031import java .util .Properties ;
3132import javax .net .ssl .SSLException ;
33+ import javax .servlet .http .HttpServletResponse ;
3234import org .apache .commons .io .FileUtils ;
3335import org .apache .hadoop .HadoopIllegalArgumentException ;
3436import org .apache .hadoop .conf .Configuration ;
@@ -75,6 +77,8 @@ public class TestLogLevel {
7577 private static Configuration clientConf ;
7678 private static Configuration sslConf ;
7779 private static final String logName = TestLogLevel .class .getName ();
80+ private static final String protectedPrefix = "protected" ;
81+ private static final String protectedLogName = protectedPrefix + "." + logName ;
7882 private static final Logger log = LogManager .getLogger (logName );
7983 private final static String PRINCIPAL = "loglevel.principal" ;
8084 private final static String KEYTAB = "loglevel.keytab" ;
@@ -90,6 +94,7 @@ public class TestLogLevel {
9094 @ BeforeClass
9195 public static void setUp () throws Exception {
9296 serverConf = new Configuration ();
97+ serverConf .setStrings (LogLevel .READONLY_LOGGERS_CONF_KEY , protectedPrefix );
9398 HTU = new HBaseCommonTestingUtility (serverConf );
9499
95100 File keystoreDir = new File (HTU .getDataTestDir ("keystore" ).toString ());
@@ -276,7 +281,13 @@ private HttpServer createServer(String protocol, boolean isSpnego)
276281 private void testDynamicLogLevel (final String bindProtocol , final String connectProtocol ,
277282 final boolean isSpnego )
278283 throws Exception {
279- testDynamicLogLevel (bindProtocol , connectProtocol , isSpnego , Level .DEBUG .toString ());
284+ testDynamicLogLevel (bindProtocol , connectProtocol , isSpnego , logName , Level .DEBUG .toString ());
285+ }
286+
287+ private void testDynamicLogLevel (final String bindProtocol , final String connectProtocol ,
288+ final boolean isSpnego , final String newLevel )
289+ throws Exception {
290+ testDynamicLogLevel (bindProtocol , connectProtocol , isSpnego , logName , newLevel );
280291 }
281292
282293 /**
@@ -288,15 +299,16 @@ private void testDynamicLogLevel(final String bindProtocol, final String connect
288299 * @throws Exception if client can't accesss server.
289300 */
290301 private void testDynamicLogLevel (final String bindProtocol , final String connectProtocol ,
291- final boolean isSpnego , final String newLevel )
302+ final boolean isSpnego , final String loggerName , final String newLevel )
292303 throws Exception {
293304 if (!LogLevel .isValidProtocol (bindProtocol )) {
294305 throw new Exception ("Invalid server protocol " + bindProtocol );
295306 }
296307 if (!LogLevel .isValidProtocol (connectProtocol )) {
297308 throw new Exception ("Invalid client protocol " + connectProtocol );
298309 }
299- Level oldLevel = log .getEffectiveLevel ();
310+ Logger log = LogManager .getLogger (loggerName );
311+ Level oldLevel = log .getLevel ();
300312 assertNotEquals ("Get default Log Level which shouldn't be ERROR." ,
301313 Level .ERROR , oldLevel );
302314
@@ -324,8 +336,8 @@ private void testDynamicLogLevel(final String bindProtocol, final String connect
324336 try {
325337 clientUGI .doAs ((PrivilegedExceptionAction <Void >) () -> {
326338 // client command line
327- getLevel (connectProtocol , authority );
328- setLevel (connectProtocol , authority , newLevel );
339+ getLevel (connectProtocol , authority , loggerName );
340+ setLevel (connectProtocol , authority , loggerName , newLevel );
329341 return null ;
330342 });
331343 } finally {
@@ -345,7 +357,7 @@ private void testDynamicLogLevel(final String bindProtocol, final String connect
345357 * @param authority daemon's web UI address
346358 * @throws Exception if unable to connect
347359 */
348- private void getLevel (String protocol , String authority ) throws Exception {
360+ private void getLevel (String protocol , String authority , String logName ) throws Exception {
349361 String [] getLevelArgs = {"-getlevel" , authority , logName , "-protocol" , protocol };
350362 CLI cli = new CLI (protocol .equalsIgnoreCase ("https" ) ? sslConf : clientConf );
351363 cli .run (getLevelArgs );
@@ -359,16 +371,30 @@ private void getLevel(String protocol, String authority) throws Exception {
359371 * @param authority daemon's web UI address
360372 * @throws Exception if unable to run or log level does not change as expected
361373 */
362- private void setLevel (String protocol , String authority , String newLevel )
374+ private void setLevel (String protocol , String authority , String logName , String newLevel )
363375 throws Exception {
364376 String [] setLevelArgs = {"-setlevel" , authority , logName , newLevel , "-protocol" , protocol };
365377 CLI cli = new CLI (protocol .equalsIgnoreCase ("https" ) ? sslConf : clientConf );
366378 cli .run (setLevelArgs );
367379
380+ Logger log = LogManager .getLogger (logName );
381+
368382 assertEquals ("new level not equal to expected: " , newLevel .toUpperCase (),
369383 log .getEffectiveLevel ().toString ());
370384 }
371385
386+ @ Test
387+ public void testSettingProtectedLogLevel () throws Exception {
388+ try {
389+ testDynamicLogLevel (LogLevel .PROTOCOL_HTTP , LogLevel .PROTOCOL_HTTP , true , protectedLogName ,
390+ "DEBUG" );
391+ fail ("Expected IO exception due to protected logger" );
392+ } catch (IOException e ) {
393+ assertTrue (e .getMessage ().contains ("" + HttpServletResponse .SC_PRECONDITION_FAILED ));
394+ assertTrue (e .getMessage ().contains ("Modification of logger " + protectedLogName + " is disallowed in configuration." ));
395+ }
396+ }
397+
372398 /**
373399 * Test setting log level to "Info".
374400 *
0 commit comments