<lambda>null1 package com.android.systemui.log
2 
3 import androidx.test.filters.SmallTest
4 import com.android.systemui.SysuiTestCase
5 import com.android.systemui.log.core.Logger
6 import com.google.common.truth.Truth.assertThat
7 import java.io.PrintWriter
8 import java.io.StringWriter
9 import org.junit.Before
10 import org.junit.Test
11 import org.junit.runner.RunWith
12 import org.mockito.Mock
13 import org.mockito.junit.MockitoJUnitRunner
14 
15 @SmallTest
16 @RunWith(MockitoJUnitRunner::class)
17 class LogBufferTest : SysuiTestCase() {
18     private lateinit var buffer: LogBuffer
19 
20     private lateinit var outputWriter: StringWriter
21 
22     @Mock private lateinit var logcatEchoTracker: LogcatEchoTracker
23 
24     @Before
25     fun setup() {
26         outputWriter = StringWriter()
27         buffer = createBuffer()
28     }
29 
30     private fun createBuffer(): LogBuffer {
31         return LogBuffer("TestBuffer", 1, logcatEchoTracker, false)
32     }
33 
34     @Test
35     fun log_shouldSaveLogToBuffer() {
36         val logger = Logger(buffer, "Test")
37         logger.i("Some test message")
38 
39         val dumpedString = dumpBuffer()
40 
41         assertThat(dumpedString).contains("Some test message")
42     }
43 
44     @Test
45     fun log_shouldRotateIfLogBufferIsFull() {
46         val logger = Logger(buffer, "Test")
47         logger.i("This should be rotated")
48         logger.i("New test message")
49 
50         val dumpedString = dumpBuffer()
51 
52         assertThat(dumpedString).contains("New test message")
53     }
54 
55     @Test
56     fun dump_writesExceptionAndStacktrace() {
57         buffer = createBuffer()
58         val exception = createTestException("Exception message", "TestClass")
59         val logger = Logger(buffer, "Test")
60         logger.e("Extra message", exception)
61 
62         val dumpedString = dumpBuffer()
63 
64         assertThat(dumpedString).contains("Extra message")
65         assertThat(dumpedString).contains("java.lang.RuntimeException: Exception message")
66         assertThat(dumpedString).contains("at TestClass.TestMethod(TestClass.java:1)")
67         assertThat(dumpedString).contains("at TestClass.TestMethod(TestClass.java:2)")
68     }
69 
70     @Test
71     fun dump_writesCauseAndStacktrace() {
72         buffer = createBuffer()
73         val exception =
74             createTestException(
75                 "Exception message",
76                 "TestClass",
77                 cause = createTestException("The real cause!", "TestClass")
78             )
79         val logger = Logger(buffer, "Test")
80         logger.e("Extra message", exception)
81 
82         val dumpedString = dumpBuffer()
83 
84         assertThat(dumpedString).contains("Caused by: java.lang.RuntimeException: The real cause!")
85         assertThat(dumpedString).contains("at TestClass.TestMethod(TestClass.java:1)")
86         assertThat(dumpedString).contains("at TestClass.TestMethod(TestClass.java:2)")
87     }
88 
89     @Test
90     fun dump_writesSuppressedExceptionAndStacktrace() {
91         buffer = createBuffer()
92         val exception = RuntimeException("Root exception message")
93         exception.addSuppressed(
94             createTestException(
95                 "First suppressed exception",
96                 "FirstClass",
97                 createTestException("Cause of suppressed exp", "ThirdClass")
98             )
99         )
100         exception.addSuppressed(createTestException("Second suppressed exception", "SecondClass"))
101         val logger = Logger(buffer, "Test")
102         logger.e("Extra message", exception)
103 
104         val dumpedStr = dumpBuffer()
105 
106         // first suppressed exception
107         assertThat(dumpedStr)
108             .contains("Suppressed: " + "java.lang.RuntimeException: First suppressed exception")
109         assertThat(dumpedStr).contains("at FirstClass.TestMethod(FirstClass.java:1)")
110         assertThat(dumpedStr).contains("at FirstClass.TestMethod(FirstClass.java:2)")
111 
112         assertThat(dumpedStr)
113             .contains("Caused by: java.lang.RuntimeException: Cause of suppressed exp")
114         assertThat(dumpedStr).contains("at ThirdClass.TestMethod(ThirdClass.java:1)")
115         assertThat(dumpedStr).contains("at ThirdClass.TestMethod(ThirdClass.java:2)")
116 
117         // second suppressed exception
118         assertThat(dumpedStr)
119             .contains("Suppressed: " + "java.lang.RuntimeException: Second suppressed exception")
120         assertThat(dumpedStr).contains("at SecondClass.TestMethod(SecondClass.java:1)")
121         assertThat(dumpedStr).contains("at SecondClass.TestMethod(SecondClass.java:2)")
122     }
123 
124     private fun createTestException(
125         message: String,
126         errorClass: String,
127         cause: Throwable? = null,
128     ): Exception {
129         val exception = RuntimeException(message, cause)
130         exception.stackTrace =
131             (1..5)
132                 .map { lineNumber ->
133                     StackTraceElement(errorClass, "TestMethod", "$errorClass.java", lineNumber)
134                 }
135                 .toTypedArray()
136         return exception
137     }
138 
139     private fun dumpBuffer(): String {
140         buffer.dump(PrintWriter(outputWriter), tailLength = 100)
141         return outputWriter.toString()
142     }
143 }
144