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

Commit 373259f2 authored by Diego Perez's avatar Diego Perez
Browse files

Adds test to collect performance metrics

Test: Adds performance tests
Change-Id: I7d112ddad4efb2c1c84ac177d230225cc031f7f3
parent 66dc3640
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -30,7 +30,8 @@ LOCAL_JAVA_LIBRARIES := layoutlib \
			layoutlib_api-prebuilt \
			tools-common-prebuilt \
			sdk-common \
			junit-host
			junit-host \
			guavalib

include $(BUILD_HOST_JAVA_LIBRARY)

+55 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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.layoutlib.bridge.intensive;

import com.android.ide.common.rendering.api.SessionParams;
import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
import com.android.layoutlib.bridge.intensive.util.perf.PerformanceRunner;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import android.annotation.NonNull;

/**
 * Set of render tests
 */
@RunWith(PerformanceRunner.class)
public class PerformanceTests extends RenderTestBase {

    @Before
    public void setUp() {
        ignoreAllLogging();
    }


    private void render(@NonNull String layoutFileName) throws ClassNotFoundException {
        SessionParams params = createSessionParams(layoutFileName, ConfigGenerator.NEXUS_5);
        render(params, 250);
    }

    @Test
    public void testActivity() throws ClassNotFoundException {
        render("activity.xml");
    }

    @Test
    public void testAllWidgets() throws ClassNotFoundException {
        render("allwidgets.xml");
    }
}
+25 −19
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback;
import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
import com.android.layoutlib.bridge.intensive.util.ImageUtils;
import com.android.layoutlib.bridge.intensive.util.ModuleClassLoader;
import com.android.layoutlib.bridge.intensive.util.TestUtils;
import com.android.tools.layoutlib.java.System_Delegate;
import com.android.utils.ILogger;

@@ -50,7 +51,6 @@ import android.annotation.Nullable;

import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
@@ -272,7 +272,7 @@ public class RenderTestBase {
     * Initialize the bridge and the resource maps.
     */
    @BeforeClass
    public static void setUp() {
    public static void beforeClass() {
        File data_dir = new File(PLATFORM_DIR, "data");
        File res = new File(data_dir, "res");
        sFrameworkRepo = new FrameworkResources(new FolderWrapper(res));
@@ -304,21 +304,6 @@ public class RenderTestBase {
        }
    }

    private static void gc() {
        // See RuntimeUtil#gc in jlibs (http://jlibs.in/)
        Object obj = new Object();
        WeakReference ref = new WeakReference<>(obj);
        //noinspection UnusedAssignment
        obj = null;
        while (ref.get() != null) {
            System.gc();
            System.runFinalization();
        }

        System.gc();
        System.runFinalization();
    }

    @AfterClass
    public static void tearDown() {
        sLayoutLibLog = null;
@@ -327,7 +312,7 @@ public class RenderTestBase {
        sLogger = null;
        sBridge = null;

        gc();
        TestUtils.gc();

        System.out.println("Objects still linked from the DelegateManager:");
        DelegateManager.dump(System.out);
@@ -435,6 +420,27 @@ public class RenderTestBase {
        return sLayoutLibLog;
    }

    protected static void ignoreAllLogging() {
        sLayoutLibLog = new LayoutLog();
        sLogger = new ILogger() {
            @Override
            public void error(Throwable t, String msgFormat, Object... args) {
            }

            @Override
            public void warning(String msgFormat, Object... args) {
            }

            @Override
            public void info(String msgFormat, Object... args) {
            }

            @Override
            public void verbose(String msgFormat, Object... args) {
            }
        };
    }

    protected static ILogger getLogger() {
        if (sLogger == null) {
            sLogger = new ILogger() {
@@ -500,7 +506,7 @@ public class RenderTestBase {
        return renderAndVerify(params, goldenFileName);
    }

    private SessionParams createSessionParams(String layoutFileName, ConfigGenerator deviceConfig)
    protected SessionParams createSessionParams(String layoutFileName, ConfigGenerator deviceConfig)
            throws ClassNotFoundException {
        // Create the layout pull parser.
        LayoutPullParser parser = createLayoutPullParser(layoutFileName);
+36 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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.layoutlib.bridge.intensive.util;

import java.lang.ref.WeakReference;

public class TestUtils {
    public static void gc() {
        // See RuntimeUtil#gc in jlibs (http://jlibs.in/)
        Object obj = new Object();
        WeakReference ref = new WeakReference<>(obj);
        //noinspection UnusedAssignment
        obj = null;
        while (ref.get() != null) {
            System.gc();
            System.runFinalization();
        }

        System.gc();
        System.runFinalization();
    }
}
+97 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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.layoutlib.bridge.intensive.util.perf;

import android.annotation.NonNull;
import android.util.LongArray;

import java.util.Arrays;
import java.util.function.LongConsumer;

/**
 * Class that collect a series of longs and produces the median, min and max values.
 */
public class LongStatsCollector implements LongConsumer {
    private final LongArray mAllValues;
    private long mMin = Long.MAX_VALUE;
    private long mMax = Long.MIN_VALUE;
    public LongStatsCollector(int estimatedRuns) {
        mAllValues = new LongArray(estimatedRuns);
    }

    public int size() {
        return mAllValues.size();
    }

    @NonNull
    public Stats getStats() {
        if (mAllValues.size() == 0) {
            throw new IndexOutOfBoundsException("No data");
        }

        double median;
        int size = mAllValues.size();
        long[] buffer = new long[size];
        for (int i = 0; i < size; i++) {
            buffer[i] = mAllValues.get(i);
        }

        Arrays.sort(buffer);

        int midPoint = size / 2;
        median = (size % 2 == 0) ? (buffer[midPoint - 1] + buffer[midPoint]) / 2 : buffer[midPoint];

        return new Stats(mAllValues.size(), mMin, mMax, median);
    }

    @Override
    public void accept(long value) {
        mMin = Math.min(mMin, value);
        mMax = Math.max(mMax, value);
        mAllValues.add(value);
    }

    public static class Stats {
        private final int mSamples;
        private final long mMin;
        private final long mMax;
        private final double mMedian;

        private Stats(int samples, long min, long max, double median) {
            mSamples = samples;
            mMin = min;
            mMax = max;
            mMedian = median;
        }

        public int getSampleCount() {
            return mSamples;
        }

        public long getMin() {
            return mMin;
        }

        public long getMax() {
            return mMax;
        }

        public double getMedian() {
            return mMedian;
        }
    }
}
Loading