1 /*
2  * Copyright (C) 2022 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.server.utils;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import androidx.test.filters.SmallTest;
22 
23 import org.junit.Before;
24 import org.junit.Test;
25 import org.junit.experimental.runners.Enclosed;
26 import org.junit.runner.RunWith;
27 import org.junit.runners.JUnit4;
28 import org.junit.runners.Parameterized;
29 
30 import java.io.PrintWriter;
31 import java.io.StringWriter;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.Collection;
35 import java.util.List;
36 
37 @SmallTest
38 @RunWith(Enclosed.class)
39 public class EventLoggerTest {
40 
41     private static final int EVENTS_LOGGER_SIZE = 3;
42     private static final String EVENTS_LOGGER_TAG = "TestLogger";
43 
44     private static final TestEvent TEST_EVENT_1 = new TestEvent();
45     private static final TestEvent TEST_EVENT_2 = new TestEvent();
46     private static final TestEvent TEST_EVENT_3 = new TestEvent();
47     private static final TestEvent TEST_EVENT_4 = new TestEvent();
48     private static final TestEvent TEST_EVENT_5 = new TestEvent();
49 
50     @RunWith(JUnit4.class)
51     public static class BasicOperationsTest {
52 
53         private StringWriter mTestStringWriter;
54         private PrintWriter mTestPrintWriter;
55 
56         private TestDumpSink mTestConsumer;
57         private EventLogger mEventLogger;
58 
59         @Before
setUp()60         public void setUp() {
61             mTestStringWriter = new StringWriter();
62             mTestPrintWriter = new PrintWriter(mTestStringWriter);
63             mTestConsumer = new TestDumpSink();
64             mEventLogger = new EventLogger(EVENTS_LOGGER_SIZE, EVENTS_LOGGER_TAG);
65         }
66 
67         @Test
testThatConsumerProducesEmptyListFromEmptyLog()68         public void testThatConsumerProducesEmptyListFromEmptyLog() {
69             mEventLogger.dump(mTestConsumer);
70             assertThat(mTestConsumer.getLastKnownConsumedEvents()).isEmpty();
71         }
72 
73         @Test
testThatPrintWriterProducesOnlyTitleFromEmptyLog()74         public void testThatPrintWriterProducesOnlyTitleFromEmptyLog() {
75             mEventLogger.dump(mTestPrintWriter);
76             assertThat(mTestStringWriter.toString())
77                     .isEqualTo(mEventLogger.getDumpTitle() + "\n");
78         }
79     }
80 
81     @RunWith(Parameterized.class)
82     public static class LoggingOperationTest {
83 
84         @Parameterized.Parameters
data()85         public static Collection<Object[]> data() {
86             return Arrays.asList(new Object[][] {
87                     {
88                         // insertion order, max size is 3
89                         new EventLogger.Event[] { TEST_EVENT_1, TEST_EVENT_2 },
90                         // expected events
91                         new EventLogger.Event[] { TEST_EVENT_1, TEST_EVENT_2 }
92                     },
93                     {
94                         // insertion order, max size is 3
95                         new EventLogger.Event[] { TEST_EVENT_1, TEST_EVENT_3, TEST_EVENT_2 },
96                         // expected events
97                         new EventLogger.Event[] { TEST_EVENT_1, TEST_EVENT_3, TEST_EVENT_2 }
98                     },
99                     {
100                         // insertion order, max size is 3
101                         new EventLogger.Event[] { TEST_EVENT_1, TEST_EVENT_2, TEST_EVENT_3,
102                             TEST_EVENT_4 },
103                         // expected events
104                         new EventLogger.Event[] { TEST_EVENT_2, TEST_EVENT_3, TEST_EVENT_4 }
105                     },
106                     {
107                         // insertion order, max size is 3
108                         new EventLogger.Event[] { TEST_EVENT_1, TEST_EVENT_2, TEST_EVENT_3,
109                             TEST_EVENT_4, TEST_EVENT_5 },
110                         // expected events
111                         new EventLogger.Event[] { TEST_EVENT_3, TEST_EVENT_4, TEST_EVENT_5 }
112                     }
113             });
114         }
115 
116         private TestDumpSink mTestConsumer;
117         private EventLogger mEventLogger;
118 
119         private final StringWriter mTestStringWriter;
120         private final PrintWriter mTestPrintWriter;
121 
122         private final EventLogger.Event[] mEventsToInsert;
123         private final EventLogger.Event[] mExpectedEvents;
124 
LoggingOperationTest(EventLogger.Event[] eventsToInsert, EventLogger.Event[] expectedEvents)125         public LoggingOperationTest(EventLogger.Event[] eventsToInsert,
126                 EventLogger.Event[] expectedEvents) {
127             mTestStringWriter = new StringWriter();
128             mTestPrintWriter = new PrintWriter(mTestStringWriter);
129             mEventsToInsert = eventsToInsert;
130             mExpectedEvents = expectedEvents;
131         }
132 
133         @Before
setUp()134         public void setUp() {
135             mTestConsumer = new TestDumpSink();
136             mEventLogger = new EventLogger(EVENTS_LOGGER_SIZE, EVENTS_LOGGER_TAG);
137         }
138 
139         @Test
testThatConsumerDumpsEventsAsExpected()140         public void testThatConsumerDumpsEventsAsExpected() {
141             for (EventLogger.Event event: mEventsToInsert) {
142                 mEventLogger.enqueue(event);
143             }
144 
145             mEventLogger.dump(mTestConsumer);
146 
147             assertThat(mTestConsumer.getLastKnownConsumedEvents())
148                     .containsExactlyElementsIn(mExpectedEvents);
149         }
150 
151 
152         @Test
testThatPrintWriterDumpsEventsAsExpected()153         public void testThatPrintWriterDumpsEventsAsExpected() {
154             for (EventLogger.Event event: mEventsToInsert) {
155                 mEventLogger.enqueue(event);
156             }
157 
158             mEventLogger.dump(mTestPrintWriter);
159 
160             assertThat(mTestStringWriter.toString())
161                     .isEqualTo(convertEventsToString(mExpectedEvents));
162         }
163 
164     }
165 
convertEventsToString(EventLogger.Event[] events)166     private static String convertEventsToString(EventLogger.Event[] events) {
167         StringWriter stringWriter = new StringWriter();
168         PrintWriter printWriter = new PrintWriter(stringWriter);
169 
170         printWriter.println("Events log: " + EVENTS_LOGGER_TAG);
171 
172         for (EventLogger.Event event: events) {
173             printWriter.println(event.toString());
174         }
175 
176         return stringWriter.toString();
177     }
178 
179 
180     private static final class TestEvent extends EventLogger.Event {
181 
182         @Override
eventToString()183         public String eventToString() {
184             return getClass().getName() + "@" + Integer.toHexString(hashCode());
185         }
186     }
187 
188     private static final class TestDumpSink implements EventLogger.DumpSink {
189 
190         private final ArrayList<EventLogger.Event> mEvents = new ArrayList<>();
191 
192         @Override
sink(String tag, List<EventLogger.Event> events)193         public void sink(String tag, List<EventLogger.Event> events) {
194             mEvents.clear();
195             mEvents.addAll(events);
196         }
197 
getLastKnownConsumedEvents()198         public ArrayList<EventLogger.Event> getLastKnownConsumedEvents() {
199             return new ArrayList<>(mEvents);
200         }
201     }
202 }
203