1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.dump
18 
19 import androidx.test.filters.SmallTest
20 import com.android.systemui.Dumpable
21 import com.android.systemui.SysuiTestCase
22 import com.android.systemui.log.LogBuffer
23 import com.android.systemui.log.table.TableLogBuffer
24 import com.google.common.truth.Truth.assertThat
25 import org.junit.Assert.assertThrows
26 import org.junit.Before
27 import org.junit.Test
28 import org.mockito.Mock
29 import org.mockito.MockitoAnnotations
30 
31 @SmallTest
32 class DumpManagerTest : SysuiTestCase() {
33 
34     @Mock private lateinit var dumpable1: Dumpable
35     @Mock private lateinit var dumpable2: Dumpable
36     @Mock private lateinit var dumpable3: Dumpable
37 
38     @Mock private lateinit var buffer1: LogBuffer
39     @Mock private lateinit var buffer2: LogBuffer
40 
41     @Mock private lateinit var table1: TableLogBuffer
42     @Mock private lateinit var table2: TableLogBuffer
43 
44     private val dumpManager = DumpManager()
45 
46     @Before
47     fun setUp() {
48         MockitoAnnotations.initMocks(this)
49     }
50 
51     @Test
52     fun testRegisterUnregister_dumpables() {
53         // GIVEN a variety of registered dumpables
54         dumpManager.registerCriticalDumpable("dumpable1", dumpable1)
55         dumpManager.registerCriticalDumpable("dumpable2", dumpable2)
56         dumpManager.registerNormalDumpable("dumpable3", dumpable3)
57 
58         // WHEN the collection is requested
59         var dumpables = dumpManager.getDumpables().map { it.dumpable }
60 
61         // THEN it contains the registered entries
62         assertThat(dumpables).containsExactly(dumpable1, dumpable2, dumpable3)
63 
64         // WHEN the dumpables are unregistered
65         dumpManager.unregisterDumpable("dumpable2")
66         dumpManager.unregisterDumpable("dumpable3")
67 
68         // WHEN the dumpable collection is requests
69         dumpables = dumpManager.getDumpables().map { it.dumpable }
70 
71         // THEN it contains only the currently-registered entry
72         assertThat(dumpables).containsExactly(dumpable1)
73     }
74 
75     @Test
76     fun testRegister_buffers() {
77         // GIVEN a set of registered buffers
78         dumpManager.registerBuffer("buffer1", buffer1)
79         dumpManager.registerBuffer("buffer2", buffer2)
80 
81         // WHEN the collection is requested
82         val dumpables = dumpManager.getLogBuffers().map { it.buffer }
83 
84         // THEN it contains the registered entries
85         assertThat(dumpables).containsExactly(buffer1, buffer2)
86     }
87 
88     @Test
89     fun testRegister_tableLogBuffers() {
90         // GIVEN a set of registered buffers
91         dumpManager.registerTableLogBuffer("table1", table1)
92         dumpManager.registerTableLogBuffer("table2", table2)
93 
94         // WHEN the collection is requested
95         val tables = dumpManager.getTableLogBuffers().map { it.table }
96 
97         // THEN it contains the registered entries
98         assertThat(tables).containsExactly(table1, table2)
99     }
100 
101     @Test
102     fun registerDumpable_throwsWhenNameCannotBeAssigned() {
103         // GIVEN dumpable1 and buffer1 and table1 are registered
104         dumpManager.registerCriticalDumpable("dumpable1", dumpable1)
105         dumpManager.registerBuffer("buffer1", buffer1)
106         dumpManager.registerTableLogBuffer("table1", table1)
107 
108         // THEN an exception is thrown when trying to re-register a new dumpable under the same key
109         assertThrows(IllegalArgumentException::class.java) {
110             dumpManager.registerCriticalDumpable("dumpable1", dumpable2)
111         }
112         assertThrows(IllegalArgumentException::class.java) {
113             dumpManager.registerBuffer("buffer1", buffer2)
114         }
115         assertThrows(IllegalArgumentException::class.java) {
116             dumpManager.registerTableLogBuffer("table1", table2)
117         }
118     }
119 
120     @Test
121     fun registerDumpable_doesNotThrowWhenReRegistering() {
122         // GIVEN dumpable1 and buffer1 are registered
123         dumpManager.registerCriticalDumpable("dumpable1", dumpable1)
124         dumpManager.registerBuffer("buffer1", buffer1)
125 
126         // THEN no exception is thrown when trying to re-register a new dumpable under the same key
127         dumpManager.registerCriticalDumpable("dumpable1", dumpable1)
128         dumpManager.registerBuffer("buffer1", buffer1)
129 
130         // No exception thrown
131     }
132 
133     @Test
134     fun getDumpables_returnsSafeCollection() {
135         // GIVEN a variety of registered dumpables
136         dumpManager.registerCriticalDumpable("dumpable1", dumpable1)
137         dumpManager.registerCriticalDumpable("dumpable2", dumpable2)
138         dumpManager.registerNormalDumpable("dumpable3", dumpable3)
139 
140         // WHEN the collection is retrieved
141         val dumpables = dumpManager.getDumpables()
142 
143         // WHEN the collection changes from underneath
144         dumpManager.unregisterDumpable("dumpable1")
145         dumpManager.unregisterDumpable("dumpable2")
146         dumpManager.unregisterDumpable("dumpable3")
147 
148         // THEN new collections are empty
149         assertThat(dumpManager.getDumpables()).isEmpty()
150 
151         // AND the collection is still safe to use
152         assertThat(dumpables).hasSize(3)
153     }
154 
155     @Test
156     fun getBuffers_returnsSafeCollection() {
157         // GIVEN a set of registered buffers
158         dumpManager.registerBuffer("buffer1", buffer1)
159         dumpManager.registerBuffer("buffer2", buffer2)
160 
161         // WHEN the collection is requested
162         val buffers = dumpManager.getLogBuffers()
163 
164         // WHEN the collection changes
165         dumpManager.registerBuffer("buffer3", buffer1)
166 
167         // THEN the new entry is represented
168         assertThat(dumpManager.getLogBuffers()).hasSize(3)
169 
170         // AND the previous collection is unchanged
171         assertThat(buffers).hasSize(2)
172     }
173 
174     @Test
175     fun getTableBuffers_returnsSafeCollection() {
176         // GIVEN a set of registered buffers
177         dumpManager.registerTableLogBuffer("table1", table1)
178         dumpManager.registerTableLogBuffer("table2", table2)
179 
180         // WHEN the collection is requested
181         val tables = dumpManager.getTableLogBuffers()
182 
183         // WHEN the collection changes
184         dumpManager.registerTableLogBuffer("table3", table1)
185 
186         // THEN the new entry is represented
187         assertThat(dumpManager.getTableLogBuffers()).hasSize(3)
188 
189         // AND the previous collection is unchanged
190         assertThat(tables).hasSize(2)
191     }
192 }
193