1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.puppycrawl.tools.checkstyle;
21
22 import static com.google.common.truth.Truth.assertWithMessage;
23
24 import java.io.ByteArrayOutputStream;
25 import java.io.IOException;
26 import java.io.PrintWriter;
27 import java.nio.charset.StandardCharsets;
28
29 import org.junit.jupiter.api.Test;
30
31 import com.puppycrawl.tools.checkstyle.AbstractAutomaticBean.OutputStreamOptions;
32 import com.puppycrawl.tools.checkstyle.api.AuditEvent;
33 import com.puppycrawl.tools.checkstyle.api.SeverityLevel;
34 import com.puppycrawl.tools.checkstyle.api.Violation;
35 import com.puppycrawl.tools.checkstyle.internal.utils.CloseAndFlushTestByteArrayOutputStream;
36
37 public class SarifLoggerTest extends AbstractModuleTestSupport {
38
39
40
41
42
43
44 private final CloseAndFlushTestByteArrayOutputStream outStream =
45 new CloseAndFlushTestByteArrayOutputStream();
46
47 @Override
48 protected String getPackageLocation() {
49 return "com/puppycrawl/tools/checkstyle/sariflogger";
50 }
51
52 @Test
53 public void testEscape() {
54 final String[][] encodings = {
55 {"\"", "\\\""},
56 {"\\", "\\\\"},
57 {"\b", "\\b"},
58 {"\f", "\\f"},
59 {"\n", "\\n"},
60 {"\r", "\\r"},
61 {"\t", "\\t"},
62 {"/", "\\/"},
63 {"\u0010", "\\u0010"},
64 {"\u001E", "\\u001E"},
65 {"\u001F", "\\u001F"},
66 {" ", " "},
67 {"bar1234", "bar1234"},
68 };
69 for (String[] encoding : encodings) {
70 final String encoded = SarifLogger.escape(encoding[0]);
71 assertWithMessage("\"" + encoding[0] + "\"")
72 .that(encoded)
73 .isEqualTo(encoding[1]);
74 }
75 }
76
77 @Test
78 public void testAddError() throws IOException {
79 final SarifLogger logger = new SarifLogger(outStream,
80 OutputStreamOptions.CLOSE);
81 logger.auditStarted(null);
82 final Violation violation =
83 new Violation(1, 1,
84 "messages.properties", "ruleId", null, SeverityLevel.ERROR, null,
85 getClass(), "found an error");
86 final AuditEvent ev = new AuditEvent(this, "Test.java", violation);
87 logger.fileStarted(ev);
88 logger.addError(ev);
89 logger.fileFinished(ev);
90 logger.auditFinished(null);
91 verifyContent(getPath("ExpectedSarifLoggerSingleError.sarif"), outStream);
92 }
93
94 @Test
95 public void testAddErrorWithWarningLevel() throws IOException {
96 final SarifLogger logger = new SarifLogger(outStream,
97 OutputStreamOptions.CLOSE);
98 logger.auditStarted(null);
99 final Violation violation =
100 new Violation(1, 1,
101 "messages.properties", "ruleId", null, SeverityLevel.WARNING, null,
102 getClass(), "found an error");
103 final AuditEvent ev = new AuditEvent(this, "Test.java", violation);
104 logger.fileStarted(ev);
105 logger.addError(ev);
106 logger.fileFinished(ev);
107 logger.auditFinished(null);
108 verifyContent(getPath("ExpectedSarifLoggerSingleWarning.sarif"), outStream);
109 }
110
111 @Test
112 public void testAddErrors() throws IOException {
113 final SarifLogger logger = new SarifLogger(outStream,
114 OutputStreamOptions.CLOSE);
115 logger.auditStarted(null);
116 final Violation violation =
117 new Violation(1, 1,
118 "messages.properties", "ruleId", null, SeverityLevel.INFO, null,
119 getClass(), "found an error");
120 final AuditEvent ev = new AuditEvent(this, "Test.java", violation);
121 final Violation violation2 =
122 new Violation(1, 1,
123 "messages.properties", "ruleId2", null, SeverityLevel.IGNORE, null,
124 getClass(), "found another error");
125 final AuditEvent ev2 = new AuditEvent(this, "Test.java", violation2);
126 logger.fileStarted(ev);
127 logger.addError(ev);
128 logger.fileFinished(ev);
129 logger.fileStarted(ev2);
130 logger.addError(ev2);
131 logger.fileFinished(ev2);
132 logger.auditFinished(null);
133 verifyContent(getPath("ExpectedSarifLoggerDoubleError.sarif"), outStream);
134 }
135
136 @Test
137 public void testAddException() throws IOException {
138 final SarifLogger logger = new SarifLogger(outStream,
139 OutputStreamOptions.CLOSE);
140 logger.auditStarted(null);
141 final Violation message =
142 new Violation(1, 1,
143 "messages.properties", "null", null, null,
144 getClass(), "found an error");
145 final AuditEvent ev = new AuditEvent(this, null, message);
146 logger.fileStarted(ev);
147 logger.addException(ev, new TestException("msg", new RuntimeException("msg")));
148 logger.fileFinished(ev);
149 logger.auditFinished(null);
150 verifyContent(getPath("ExpectedSarifLoggerSingleException.sarif"), outStream);
151 }
152
153 @Test
154 public void testAddExceptions() throws IOException {
155 final SarifLogger logger = new SarifLogger(outStream,
156 OutputStreamOptions.CLOSE);
157 logger.auditStarted(null);
158 final Violation violation =
159 new Violation(1, 1,
160 "messages.properties", "null", null, null,
161 getClass(), "found an error");
162 final AuditEvent ev = new AuditEvent(this, null, violation);
163 final Violation violation2 =
164 new Violation(1, 1,
165 "messages.properties", "null", null, null,
166 getClass(), "found an error");
167 final AuditEvent ev2 = new AuditEvent(this, "Test.java", violation2);
168 logger.fileStarted(ev);
169 logger.addException(ev, new TestException("msg", new RuntimeException("msg")));
170 logger.fileFinished(ev);
171 logger.fileStarted(ev2);
172 logger.addException(ev2, new TestException("msg2", new RuntimeException("msg2")));
173 logger.fileFinished(ev);
174 logger.auditFinished(null);
175 verifyContent(getPath("ExpectedSarifLoggerDoubleException.sarif"), outStream);
176 }
177
178 @Test
179 public void testLineOnly() throws IOException {
180 final SarifLogger logger = new SarifLogger(outStream,
181 OutputStreamOptions.CLOSE);
182 logger.auditStarted(null);
183 final Violation violation =
184 new Violation(1, 0,
185 "messages.properties", "ruleId", null, null,
186 getClass(), "found an error");
187 final AuditEvent ev = new AuditEvent(this, "Test.java", violation);
188 logger.fileStarted(ev);
189 logger.addError(ev);
190 logger.fileFinished(ev);
191 logger.auditFinished(null);
192 verifyContent(getPath("ExpectedSarifLoggerLineOnly.sarif"), outStream);
193 }
194
195 @Test
196 public void testEmpty() throws IOException {
197 final SarifLogger logger = new SarifLogger(outStream,
198 OutputStreamOptions.CLOSE);
199 logger.auditStarted(null);
200 final Violation violation =
201 new Violation(1, 1,
202 "messages.properties", "null", null, null,
203 getClass(), "found an error");
204 final AuditEvent ev = new AuditEvent(this, null, violation);
205 logger.fileStarted(ev);
206 logger.fileFinished(ev);
207 logger.auditFinished(null);
208 verifyContent(getPath("ExpectedSarifLoggerEmpty.sarif"), outStream);
209 }
210
211 @Test
212 public void testNullOutputStreamOptions() {
213 try {
214 final SarifLogger logger = new SarifLogger(outStream, null);
215
216 assertWithMessage("Null instance")
217 .that(logger)
218 .isNotNull();
219 assertWithMessage("Exception was expected").fail();
220 }
221 catch (IllegalArgumentException | IOException exception) {
222 assertWithMessage("Invalid error message")
223 .that(exception.getMessage())
224 .isEqualTo("Parameter outputStreamOptions can not be null");
225 }
226 }
227
228 @Test
229 public void testCloseStream() throws IOException {
230 final SarifLogger logger = new SarifLogger(outStream,
231 OutputStreamOptions.CLOSE);
232 logger.auditStarted(null);
233 logger.auditFinished(null);
234
235 assertWithMessage("Invalid close count")
236 .that(outStream.getCloseCount())
237 .isEqualTo(1);
238
239 verifyContent(getPath("ExpectedSarifLoggerEmpty.sarif"), outStream);
240 }
241
242 @Test
243 public void testNoCloseStream() throws IOException {
244 final SarifLogger logger = new SarifLogger(outStream,
245 OutputStreamOptions.NONE);
246 logger.auditStarted(null);
247 logger.auditFinished(null);
248
249 assertWithMessage("Invalid close count")
250 .that(outStream.getCloseCount())
251 .isEqualTo(0);
252 assertWithMessage("Invalid flush count")
253 .that(outStream.getFlushCount())
254 .isEqualTo(1);
255
256 outStream.close();
257 verifyContent(getPath("ExpectedSarifLoggerEmpty.sarif"), outStream);
258 }
259
260 @Test
261 public void testFinishLocalSetup() throws IOException {
262 final SarifLogger logger = new SarifLogger(outStream,
263 OutputStreamOptions.CLOSE);
264 logger.finishLocalSetup();
265 logger.auditStarted(null);
266 logger.auditFinished(null);
267 assertWithMessage("instance should not be null")
268 .that(logger)
269 .isNotNull();
270 }
271
272 @Test
273 public void testReadResourceWithInvalidName() {
274 try {
275 SarifLogger.readResource("random");
276 assertWithMessage("Exception expected").fail();
277 }
278 catch (IOException exception) {
279 assertWithMessage("Exception message must match")
280 .that(exception.getMessage())
281 .isEqualTo("Cannot find the resource random");
282 }
283 }
284
285 private static void verifyContent(
286 String expectedOutputFile,
287 ByteArrayOutputStream actualOutputStream) throws IOException {
288 final String expectedContent = readFile(expectedOutputFile);
289 final String actualContent =
290 toLfLineEnding(actualOutputStream.toString(StandardCharsets.UTF_8));
291 assertWithMessage("sarif content should match")
292 .that(actualContent)
293 .isEqualTo(expectedContent);
294 }
295
296 private static final class TestException extends RuntimeException {
297
298 private static final long serialVersionUID = 1L;
299
300 private TestException(String msg, Throwable cause) {
301 super(msg, cause);
302 }
303
304 @Override
305 public void printStackTrace(PrintWriter printWriter) {
306 printWriter.print("stackTrace\nexample");
307 }
308 }
309 }