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