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

Commit b8498173 authored by Kean Mariotti's avatar Kean Mariotti Committed by Android (Google) Code Review
Browse files

Merge "wm tracing: add tests for WindowTracingPerfetto" into main

parents 2263c369 4d002c80
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.util.Log;
import android.util.proto.ProtoOutputStream;
import android.view.Choreographer;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.TraceBuffer;

import java.io.File;
@@ -66,6 +67,7 @@ class WindowTracingLegacy extends WindowTracing {
                service.mGlobalLock, BUFFER_CAPACITY_TRIM);
    }

    @VisibleForTesting
    WindowTracingLegacy(File traceFile, WindowManagerService service, Choreographer choreographer,
            WindowManagerGlobalLock globalLock, int bufferSize) {
        super(service, choreographer, globalLock);
+9 −1
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@ import android.util.Log;
import android.util.proto.ProtoOutputStream;
import android.view.Choreographer;

import com.android.internal.annotations.VisibleForTesting;

import java.io.PrintWriter;
import java.util.concurrent.atomic.AtomicInteger;

@@ -37,7 +39,13 @@ class WindowTracingPerfetto extends WindowTracing {
            this::onStart, this::onStop);

    WindowTracingPerfetto(WindowManagerService service, Choreographer choreographer) {
        super(service, choreographer, service.mGlobalLock);
        this(service, choreographer, service.mGlobalLock);
    }

    @VisibleForTesting
    WindowTracingPerfetto(WindowManagerService service, Choreographer choreographer,
            WindowManagerGlobalLock globalLock) {
        super(service, choreographer, globalLock);
    }

    @Override
+1 −0
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ android_test {
        "service-permission.stubs.system_server",
        "androidx.test.runner",
        "androidx.test.rules",
        "flickerlib",
        "junit-params",
        "mockito-target-extended-minus-junit4",
        "platform-test-annotations",
+141 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.wm;

import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verifyZeroInteractions;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;

import static java.io.File.createTempFile;
import static java.nio.file.Files.createTempDirectory;

import android.platform.test.annotations.Presubmit;
import android.tools.ScenarioBuilder;
import android.tools.traces.io.ResultWriter;
import android.tools.traces.monitors.PerfettoTraceMonitor;
import android.view.Choreographer;

import androidx.test.filters.SmallTest;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import perfetto.protos.PerfettoConfig.WindowManagerConfig.LogFrequency;

/**
 * Test class for {@link WindowTracingPerfetto}.
 */
@SmallTest
@Presubmit
public class WindowTracingPerfettoTest {
    @Mock
    private WindowManagerService mWmMock;
    @Mock
    private Choreographer mChoreographer;
    private WindowTracing mWindowTracing;
    private PerfettoTraceMonitor mTraceMonitor;
    private ResultWriter mWriter;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);

        mWindowTracing = new WindowTracingPerfetto(mWmMock, mChoreographer,
                new WindowManagerGlobalLock());

        mWriter = new ResultWriter()
            .forScenario(new ScenarioBuilder()
                    .forClass(createTempFile("temp", "").getName()).build())
            .withOutputDir(createTempDirectory("temp").toFile())
            .setRunComplete();
    }

    @After
    public void tearDown() throws Exception {
        stopTracing();
    }

    @Test
    public void isEnabled_returnsFalseByDefault() {
        assertFalse(mWindowTracing.isEnabled());
    }

    @Test
    public void isEnabled_returnsTrueAfterStartThenFalseAfterStop() {
        startTracing(false);
        assertTrue(mWindowTracing.isEnabled());

        stopTracing();
        assertFalse(mWindowTracing.isEnabled());
    }

    @Test
    public void trace_ignoresLogStateCalls_ifTracingIsDisabled() {
        mWindowTracing.logState("where");
        verifyZeroInteractions(mWmMock);
    }

    @Test
    public void trace_writesInitialStateSnapshot_whenTracingStarts() throws Exception {
        startTracing(false);
        verify(mWmMock, times(1)).dumpDebugLocked(any(), eq(WindowTraceLogLevel.ALL));
    }

    @Test
    public void trace_writesStateSnapshot_onLogStateCall() throws Exception {
        startTracing(false);
        mWindowTracing.logState("where");
        verify(mWmMock, times(2)).dumpDebugLocked(any(), eq(WindowTraceLogLevel.ALL));
    }

    @Test
    public void dump_writesOneSingleStateSnapshot() throws Exception {
        startTracing(true);
        mWindowTracing.logState("where");
        verify(mWmMock, times(1)).dumpDebugLocked(any(), eq(WindowTraceLogLevel.ALL));
    }

    private void startTracing(boolean isDump) {
        if (isDump) {
            mTraceMonitor = PerfettoTraceMonitor
                    .newBuilder()
                    .enableWindowManagerDump()
                    .build();
        } else {
            mTraceMonitor = PerfettoTraceMonitor
                    .newBuilder()
                    .enableWindowManagerTrace(LogFrequency.LOG_FREQUENCY_TRANSACTION)
                    .build();
        }
        mTraceMonitor.start();
    }

    private void stopTracing() {
        if (mTraceMonitor == null || !mTraceMonitor.isEnabled()) {
            return;
        }
        mTraceMonitor.stop(mWriter);
    }
}