Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f20a6169 authored by Alex Dadukin's avatar Alex Dadukin
Browse files

Change LinkedList to ArrayDeque in EventLogger and implement tests

Bug: b/243116883
Test: atest EventLogger
Change-Id: I70fb1f8e31fb703518b1cb1d40bb23fe0292e82b
parent 1c8f780d
Loading
Loading
Loading
Loading
+10 −6
Original line number Diff line number Diff line
@@ -23,8 +23,8 @@ import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.text.SimpleDateFormat;
import java.util.ArrayDeque;
import java.util.Date;
import java.util.LinkedList;
import java.util.Locale;

/**
@@ -36,7 +36,7 @@ public class EventLogger {
    private final String mTag;

    /** Stores the events using a ring buffer. */
    private final LinkedList<Event> mEvents;
    private final ArrayDeque<Event> mEvents;

    /**
     * The maximum number of events to keep in {@code mEvents}.
@@ -52,16 +52,18 @@ public class EventLogger {
     * @param tag the string displayed before the recorded log
     */
    public EventLogger(int size, String tag) {
        mEvents = new LinkedList<Event>();
        mEvents = new ArrayDeque<>(size);
        mMemSize = size;
        mTag = tag;
    }

    public synchronized void log(Event evt) {
    /** Enqueues {@code event} to be logged. */
    public synchronized void log(Event event) {
        if (mEvents.size() >= mMemSize) {
            mEvents.removeFirst();
            mEvents.removeLast();
        }
        mEvents.add(evt);

        mEvents.addFirst(event);
    }

    /**
@@ -85,8 +87,10 @@ public class EventLogger {
        log(event.printLog(logType, tag));
    }

    /** Dumps events using {@link PrintWriter} */
    public synchronized void dump(PrintWriter pw) {
        pw.println("Events log: " + mTag);

        for (Event evt : mEvents) {
            pw.println(evt.toString());
        }
+1 −0
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ android_test {
        // TODO: remove once Android migrates to JUnit 4.12,
        // which provides assertThrows
        "testng",
        "truth-prebuilt",
        "junit",
        "junit-params",
        "platform-compat-test-rules",
+159 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.utils;

import static com.google.common.truth.Truth.assertThat;

import androidx.test.filters.SmallTest;

import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.runners.Enclosed;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.junit.runners.Parameterized;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.Collection;

@SmallTest
@RunWith(Enclosed.class)
public class EventLoggerTest {

    private static final int EVENTS_LOGGER_SIZE = 3;
    private static final String EVENTS_LOGGER_TAG = "TestLogger";

    private static final TestEvent TEST_EVENT_1 = new TestEvent();
    private static final TestEvent TEST_EVENT_2 = new TestEvent();
    private static final TestEvent TEST_EVENT_3 = new TestEvent();
    private static final TestEvent TEST_EVENT_4 = new TestEvent();
    private static final TestEvent TEST_EVENT_5 = new TestEvent();

    @RunWith(JUnit4.class)
    public static class BasicOperationsTest {

        private StringWriter mTestStringWriter;
        private PrintWriter mTestPrintWriter;

        private EventLogger mEventLogger;

        @Before
        public void setUp() {
            mTestStringWriter = new StringWriter();
            mTestPrintWriter = new PrintWriter(mTestStringWriter);
            mEventLogger = new EventLogger(EVENTS_LOGGER_SIZE, EVENTS_LOGGER_TAG);
        }

        @Test
        public void testThatConsumeOfEmptyLoggerProducesEmptyList() {
            mEventLogger.dump(mTestPrintWriter);
            assertThat(mTestStringWriter.toString()).isEmpty();
        }
    }

    @RunWith(Parameterized.class)
    public static class LoggingOperationTest {

        @Parameterized.Parameters
        public static Collection<Object[]> data() {
            return Arrays.asList(new Object[][] {
                    {
                        // insertion order, max size is 3
                        new EventLogger.Event[] { TEST_EVENT_1, TEST_EVENT_2 },
                        // expected events
                        new EventLogger.Event[] { TEST_EVENT_2, TEST_EVENT_1 }
                    },
                    {
                        // insertion order, max size is 3
                        new EventLogger.Event[] { TEST_EVENT_1, TEST_EVENT_3, TEST_EVENT_2 },
                        // expected events
                        new EventLogger.Event[] { TEST_EVENT_2, TEST_EVENT_3, TEST_EVENT_1 }
                    },
                    {
                        // insertion order, max size is 3
                        new EventLogger.Event[] { TEST_EVENT_1, TEST_EVENT_2, TEST_EVENT_3,
                            TEST_EVENT_4 },
                        // expected events
                        new EventLogger.Event[] { TEST_EVENT_4, TEST_EVENT_3, TEST_EVENT_2 }
                    },
                    {
                        // insertion order, max size is 3
                        new EventLogger.Event[] { TEST_EVENT_1, TEST_EVENT_2, TEST_EVENT_3,
                            TEST_EVENT_4, TEST_EVENT_5 },
                        // expected events
                        new EventLogger.Event[] { TEST_EVENT_5, TEST_EVENT_4, TEST_EVENT_3 }
                    }
            });
        }

        private EventLogger mEventLogger;

        private final StringWriter mTestStringWriter;
        private final PrintWriter mTestPrintWriter;
        private final EventLogger.Event[] mEventsToInsert;
        private final EventLogger.Event[] mExpectedEvents;

        public LoggingOperationTest(EventLogger.Event[] eventsToInsert,
                EventLogger.Event[] expectedEvents) {
            mTestStringWriter = new StringWriter();
            mTestPrintWriter = new PrintWriter(mTestStringWriter);
            mEventsToInsert = eventsToInsert;
            mExpectedEvents = expectedEvents;
        }

        @Before
        public void setUp() {
            mEventLogger = new EventLogger(EVENTS_LOGGER_SIZE, EVENTS_LOGGER_TAG);
        }

        @Test
        public void testThatLoggingWorksAsExpected() {
            for (EventLogger.Event event: mEventsToInsert) {
                mEventLogger.log(event);
            }

            mEventLogger.dump(mTestPrintWriter);

            assertThat(mTestStringWriter.toString())
                    .isEqualTo(convertEventsToString(mExpectedEvents));
        }

    }

    private static String convertEventsToString(EventLogger.Event[] events) {
        StringWriter stringWriter = new StringWriter();
        PrintWriter printWriter = new PrintWriter(stringWriter);

        printWriter.println("Events log: " + EVENTS_LOGGER_TAG);

        for (EventLogger.Event event: events) {
            printWriter.println(event.toString());
        }

        return stringWriter.toString();
    }

    private static class TestEvent extends EventLogger.Event {

        @Override
        public String eventToString() {
            return getClass().getName() + "@" + Integer.toHexString(hashCode());
        }
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -2,3 +2,5 @@ per-file WatchableTester.java = file:/services/core/java/com/android/server/pm/O
per-file WatchableTester.java = shombert@google.com
per-file WatcherTest.java = file:/services/core/java/com/android/server/pm/OWNERS
per-file WatcherTest.java = shombert@google.com
per-file EventLoggerTest.java = file:/platform/frameworks/av:/media/janitors/media_solutions_OWNERS
per-file EventLoggerTest.java = jmtrivi@google.com