View Javadoc
1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2015, 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  package ch.qos.logback.core.appender;
15  
16  import ch.qos.logback.core.Appender;
17  import ch.qos.logback.core.ConsoleAppender;
18  import ch.qos.logback.core.CoreConstants;
19  import ch.qos.logback.core.testUtil.DummyEncoder;
20  import ch.qos.logback.core.encoder.EchoEncoder;
21  import ch.qos.logback.core.encoder.NopEncoder;
22  import ch.qos.logback.core.layout.DummyLayout;
23  import ch.qos.logback.core.status.Status;
24  import ch.qos.logback.core.status.testUtil.StatusChecker;
25  
26  import ch.qos.logback.core.testUtil.XTeeOutputStream;
27  import org.junit.jupiter.api.AfterEach;
28  import org.junit.jupiter.api.Assertions;
29  import org.junit.jupiter.api.BeforeEach;
30  import org.junit.jupiter.api.Test;
31  
32  import java.io.PrintStream;
33  import java.nio.charset.Charset;
34  import java.nio.charset.StandardCharsets;
35  
36  /**
37   * Redirecting System.out is quite messy. Disable this test in Maven but not in
38   * Package.class
39   */
40  public class ConsoleAppenderTest extends AbstractAppenderTest<Object> {
41  
42      XTeeOutputStream teeOut;
43      XTeeOutputStream teeErr;
44      PrintStream originalOut;
45      PrintStream originalErr;
46  
47      @BeforeEach
48      public void setUp() {
49          originalOut = System.out;
50          originalErr = System.err;
51          // teeOut will output bytes on System out but it will also
52          // collect them so that the output can be compared against
53    
54          // keep the console quiet
55          teeOut = new XTeeOutputStream(null);
56          teeErr = new XTeeOutputStream(null);
57  
58          // redirect System.out to teeOut and System.err to teeErr
59          System.setOut(new PrintStream(teeOut));
60          System.setErr(new PrintStream(teeErr));
61      }
62  
63      @AfterEach
64      public void tearDown() {
65          System.setOut(originalOut);
66          System.setErr(originalErr);
67      }
68  
69      @Override
70      public Appender<Object> getAppender() {
71          return new ConsoleAppender<>();
72      }
73  
74      protected Appender<Object> getConfiguredAppender() {
75          ConsoleAppender<Object> ca = new ConsoleAppender<>();
76          ca.setEncoder(new NopEncoder<>());
77          ca.start();
78          return ca;
79      }
80  
81      @Test
82      public void smoke() {
83          ConsoleAppender<Object> ca = (ConsoleAppender<Object>) getAppender();
84          ca.setEncoder(new DummyEncoder<>());
85          ca.start();
86          ca.doAppend(new Object());
87          Assertions.assertEquals(DummyLayout.DUMMY, teeOut.toString());
88      }
89  
90      @Test
91      public void open() {
92          ConsoleAppender<Object> ca = (ConsoleAppender<Object>) getAppender();
93          DummyEncoder<Object> dummyEncoder = new DummyEncoder<>();
94          dummyEncoder.setFileHeader("open");
95          ca.setEncoder(dummyEncoder);
96          ca.start();
97          ca.doAppend(new Object());
98          ca.stop();
99          Assertions.assertEquals("open" + CoreConstants.LINE_SEPARATOR + DummyLayout.DUMMY, teeOut.toString());
100     }
101 
102     @Test
103     public void testClose() {
104         ConsoleAppender<Object> ca = (ConsoleAppender<Object>) getAppender();
105         DummyEncoder<Object> dummyEncoder = new DummyEncoder<>();
106         dummyEncoder.setFileFooter("CLOSED");
107         ca.setEncoder(dummyEncoder);
108         ca.start();
109         ca.doAppend(new Object());
110         ca.stop();
111         // ConsoleAppender must keep the underlying stream open.
112         // The console is not ours to close.
113         Assertions.assertFalse(teeOut.isClosed());
114         Assertions.assertEquals(DummyLayout.DUMMY + "CLOSED", teeOut.toString());
115     }
116 
117     // See http://jira.qos.ch/browse/LBCORE-143
118     @Test
119     public void changeInConsole() {
120         ConsoleAppender<Object> ca = (ConsoleAppender<Object>) getAppender();
121         EchoEncoder<Object> encoder = new EchoEncoder<>();
122         ca.setEncoder(encoder);
123         ca.start();
124         ca.doAppend("a");
125         Assertions.assertEquals("a" + CoreConstants.LINE_SEPARATOR, teeOut.toString());
126 
127         XTeeOutputStream newTee = new XTeeOutputStream(null);
128         System.setOut(new PrintStream(newTee));
129         ca.doAppend("b");
130         Assertions.assertEquals("b" + CoreConstants.LINE_SEPARATOR, newTee.toString());
131     }
132 
133     @Test
134     public void testUTF16BE()  {
135         ConsoleAppender<Object> ca = (ConsoleAppender<Object>) getAppender();
136         DummyEncoder<Object> dummyEncoder = new DummyEncoder<>();
137         Charset utf16BE = StandardCharsets.UTF_16BE;
138         dummyEncoder.setCharset(utf16BE);
139         ca.setEncoder(dummyEncoder);
140         ca.start();
141         ca.doAppend(new Object());
142         Assertions.assertEquals(DummyLayout.DUMMY, new String(teeOut.toByteArray(), utf16BE));
143     }
144 
145     @Test
146     public void wrongTarget() {
147         ConsoleAppender<Object> ca = (ConsoleAppender<Object>) getAppender();
148         EchoEncoder<Object> encoder = new EchoEncoder<>();
149         encoder.setContext(context);
150         ca.setContext(context);
151         ca.setTarget("foo");
152         ca.setEncoder(encoder);
153         ca.start();
154         ca.doAppend("a");
155         StatusChecker checker = new StatusChecker(context);
156         // 21:28:01,246 + WARN in ch.qos.logback.core.ConsoleAppender[null] - [foo]
157         // should be one of [System.out,
158         // System.err]
159         // 21:28:01,246 |-WARN in ch.qos.logback.core.ConsoleAppender[null] - Using
160         // previously set target, System.out by
161         // default.
162         // StatusPrinter.print(context);
163 
164         checker.assertContainsMatch(Status.WARN, "\\[foo\\] should be one of \\[System.out, System.err\\]");
165 
166     }
167 }