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

Commit aff7c3c7 authored by Sudheer Shanka's avatar Sudheer Shanka Committed by Android (Google) Code Review
Browse files

Merge "More unit tests for classes needed in reading uid times per cpu freq." into oc-dev

parents e4f48491 59f5c00b
Loading
Loading
Loading
Loading
+63 −60
Original line number Diff line number Diff line
@@ -967,14 +967,15 @@ public class BatteryStatsImpl extends BatteryStats {
        }
    }

    @VisibleForTesting
    public static class LongSamplingCounterArray extends LongCounterArray implements TimeBaseObs {
        final TimeBase mTimeBase;
        long[] mCounts;
        long[] mLoadedCounts;
        long[] mUnpluggedCounts;
        long[] mPluggedCounts;
        public long[] mCounts;
        public long[] mLoadedCounts;
        public long[] mUnpluggedCounts;
        public long[] mPluggedCounts;

        LongSamplingCounterArray(TimeBase timeBase, Parcel in) {
        private LongSamplingCounterArray(TimeBase timeBase, Parcel in) {
            mTimeBase = timeBase;
            mPluggedCounts = in.createLongArray();
            mCounts = copyArray(mPluggedCounts, mCounts);
@@ -983,12 +984,12 @@ public class BatteryStatsImpl extends BatteryStats {
            timeBase.add(this);
        }

        LongSamplingCounterArray(TimeBase timeBase) {
        public LongSamplingCounterArray(TimeBase timeBase) {
            mTimeBase = timeBase;
            timeBase.add(this);
        }

        public void writeToParcel(Parcel out) {
        private void writeToParcel(Parcel out) {
            out.writeLongArray(mCounts);
            out.writeLongArray(mLoadedCounts);
            out.writeLongArray(mUnpluggedCounts);
@@ -1024,7 +1025,7 @@ public class BatteryStatsImpl extends BatteryStats {
                    + " mPluggedCounts=" + Arrays.toString(mPluggedCounts));
        }

        void addCountLocked(long[] counts) {
        public void addCountLocked(long[] counts) {
            if (counts == null) {
                return;
            }
@@ -1039,7 +1040,7 @@ public class BatteryStatsImpl extends BatteryStats {
        /**
         * Clear state of this counter.
         */
        void reset(boolean detachIfReset) {
        public void reset(boolean detachIfReset) {
            fillArray(mCounts, 0);
            fillArray(mLoadedCounts, 0);
            fillArray(mPluggedCounts, 0);
@@ -1049,21 +1050,60 @@ public class BatteryStatsImpl extends BatteryStats {
            }
        }

        void detach() {
        public void detach() {
            mTimeBase.remove(this);
        }

        void writeSummaryFromParcelLocked(Parcel out) {
        private void writeSummaryToParcelLocked(Parcel out) {
            out.writeLongArray(mCounts);
        }

        void readSummaryFromParcelLocked(Parcel in) {
        private void readSummaryFromParcelLocked(Parcel in) {
            mCounts = in.createLongArray();
            mLoadedCounts = copyArray(mCounts, mLoadedCounts);
            mUnpluggedCounts = copyArray(mCounts, mUnpluggedCounts);
            mPluggedCounts = copyArray(mCounts, mPluggedCounts);
        }

        public static void writeToParcel(Parcel out, LongSamplingCounterArray counterArray) {
            if (counterArray != null) {
                out.writeInt(1);
                counterArray.writeToParcel(out);
            } else {
                out.writeInt(0);
            }
        }

        public static LongSamplingCounterArray readFromParcel(Parcel in, TimeBase timeBase) {
            if (in.readInt() != 0) {
                return new LongSamplingCounterArray(timeBase, in);
            } else {
                return null;
            }
        }

        public static void writeSummaryToParcelLocked(Parcel out,
                LongSamplingCounterArray counterArray) {
            if (counterArray != null) {
                out.writeInt(1);
                counterArray.writeSummaryToParcelLocked(out);
            } else {
                out.writeInt(0);
            }
        }

        public static LongSamplingCounterArray readSummaryFromParcelLocked(Parcel in,
                TimeBase timeBase) {
            if (in.readInt() != 0) {
                final LongSamplingCounterArray counterArray
                        = new LongSamplingCounterArray(timeBase);
                counterArray.readSummaryFromParcelLocked(in);
                return counterArray;
            } else {
                return null;
            }
        }

        private void fillArray(long[] a, long val) {
            if (a != null) {
                Arrays.fill(a, val);
@@ -6927,18 +6967,8 @@ public class BatteryStatsImpl extends BatteryStats {
                out.writeInt(0);
            }

            if (mCpuFreqTimeMs != null) {
                out.writeInt(1);
                mCpuFreqTimeMs.writeToParcel(out);
            } else {
                out.writeInt(0);
            }
            if (mScreenOffCpuFreqTimeMs != null) {
                out.writeInt(1);
                mScreenOffCpuFreqTimeMs.writeToParcel(out);
            } else {
                out.writeInt(0);
            }
            LongSamplingCounterArray.writeToParcel(out, mCpuFreqTimeMs);
            LongSamplingCounterArray.writeToParcel(out, mScreenOffCpuFreqTimeMs);

            if (mMobileRadioApWakeupCount != null) {
                out.writeInt(1);
@@ -7187,17 +7217,9 @@ public class BatteryStatsImpl extends BatteryStats {
                mCpuClusterSpeed = null;
            }

            if (in.readInt() != 0) {
                mCpuFreqTimeMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase, in);
            } else {
                mCpuFreqTimeMs = null;
            }
            if (in.readInt() != 0) {
                mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray(
                        mBsi.mOnBatteryScreenOffTimeBase, in);
            } else {
                mScreenOffCpuFreqTimeMs = null;
            }
            mCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel(in, mBsi.mOnBatteryTimeBase);
            mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel(
                    in, mBsi.mOnBatteryScreenOffTimeBase);

            if (in.readInt() != 0) {
                mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
@@ -11355,19 +11377,10 @@ public class BatteryStatsImpl extends BatteryStats {
                u.mCpuClusterSpeed = null;
            }

            if (in.readInt() != 0) {
                u.mCpuFreqTimeMs = new LongSamplingCounterArray(mOnBatteryTimeBase);
                u.mCpuFreqTimeMs.readSummaryFromParcelLocked(in);
            } else {
                u.mCpuFreqTimeMs = null;
            }
            if (in.readInt() != 0) {
                u.mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray(
                        mOnBatteryScreenOffTimeBase);
                u.mScreenOffCpuFreqTimeMs.readSummaryFromParcelLocked(in);
            } else {
                u.mScreenOffCpuFreqTimeMs = null;
            }
            u.mCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked(
                    in, mOnBatteryTimeBase);
            u.mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked(
                    in, mOnBatteryScreenOffTimeBase);

            if (in.readInt() != 0) {
                u.mMobileRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase);
@@ -11765,18 +11778,8 @@ public class BatteryStatsImpl extends BatteryStats {
                out.writeInt(0);
            }

            if (u.mCpuFreqTimeMs != null) {
                out.writeInt(1);
                u.mCpuFreqTimeMs.writeSummaryFromParcelLocked(out);
            } else {
                out.writeInt(0);
            }
            if (u.mScreenOffCpuFreqTimeMs != null) {
                out.writeInt(1);
                u.mScreenOffCpuFreqTimeMs.writeSummaryFromParcelLocked(out);
            } else {
                out.writeInt(0);
            }
            LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mCpuFreqTimeMs);
            LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mScreenOffCpuFreqTimeMs);

            if (u.mMobileRadioApWakeupCount != null) {
                out.writeInt(1);
+61 −6
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.internal.os;

import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;

import android.support.test.filters.SmallTest;
@@ -27,6 +28,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;

import java.io.BufferedReader;
@@ -70,18 +72,70 @@ public class KernelUidCpuFreqTimeReaderTest {
                times[i][j] = uids[i] * freqs[j] * 10;
            }
        }
        final String[] uidsTimesLines = getUidTimesLines(uids, times);
        final String[] lines = new String[uidsTimesLines.length + 1];
        System.arraycopy(uidsTimesLines, 0, lines, 0, uidsTimesLines.length);
        lines[uidsTimesLines.length] = null;
        when(mBufferedReader.readLine())
                .thenReturn(getFreqsLine(freqs), lines);
                .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, times));
        mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, mCallback);
        verify(mCallback).onCpuFreqs(freqs);
        for (int i = 0; i < uids.length; ++i) {
            verify(mCallback).onUidCpuFreqTime(uids[i], times[i]);
        }
        verifyNoMoreInteractions(mCallback);

        // Verify that a second call will only return deltas.
        Mockito.reset(mCallback, mBufferedReader);
        final long[][] newTimes1 = new long[uids.length][freqs.length];
        for (int i = 0; i < uids.length; ++i) {
            for (int j = 0; j < freqs.length; ++j) {
                newTimes1[i][j] = (times[i][j] + uids[i] + freqs[j]) * 10;
            }
        }
        when(mBufferedReader.readLine())
                .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, newTimes1));
        mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, mCallback);
        verify(mCallback).onCpuFreqs(freqs);
        for (int i = 0; i < uids.length; ++i) {
            verify(mCallback).onUidCpuFreqTime(uids[i], subtract(newTimes1[i], times[i]));
        }
        verifyNoMoreInteractions(mCallback);

        // Verify that calling with a null callback doesn't result in any crashes
        Mockito.reset(mCallback, mBufferedReader);
        final long[][] newTimes2 = new long[uids.length][freqs.length];
        for (int i = 0; i < uids.length; ++i) {
            for (int j = 0; j < freqs.length; ++j) {
                newTimes2[i][j] = (newTimes1[i][j] + uids[i] * freqs[j]) * 10;
            }
        }
        when(mBufferedReader.readLine())
                .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, newTimes2));
        mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, null);
        verifyZeroInteractions(mCallback);

        // Verify that the readDelta call will only return deltas when
        // the previous call had null callback.
        Mockito.reset(mCallback, mBufferedReader);
        final long[][] newTimes3 = new long[uids.length][freqs.length];
        for (int i = 0; i < uids.length; ++i) {
            for (int j = 0; j < freqs.length; ++j) {
                newTimes3[i][j] = (newTimes2[i][j] * (uids[i] + freqs[j])) * 10;
            }
        }
        when(mBufferedReader.readLine())
                .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, newTimes3));
        mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, mCallback);
        verify(mCallback).onCpuFreqs(freqs);
        for (int i = 0; i < uids.length; ++i) {
            verify(mCallback).onUidCpuFreqTime(uids[i], subtract(newTimes3[i], newTimes2[i]));
        }
        verifyNoMoreInteractions(mCallback);
    }

    private long[] subtract(long[] a1, long[] a2) {
        long[] val = new long[a1.length];
        for (int i = 0; i < val.length; ++i) {
            val[i] = a1[i] - a2[i];
        }
        return val;
    }

    private String getFreqsLine(long[] freqs) {
@@ -94,7 +148,7 @@ public class KernelUidCpuFreqTimeReaderTest {
    }

    private String[] getUidTimesLines(int[] uids, long[][] times) {
        final String[] lines = new String[uids.length];
        final String[] lines = new String[uids.length + 1];
        final StringBuilder sb = new StringBuilder();
        for (int i = 0; i < uids.length; ++i) {
            sb.setLength(0);
@@ -104,6 +158,7 @@ public class KernelUidCpuFreqTimeReaderTest {
            }
            lines[i] = sb.toString();
        }
        lines[uids.length] = null;
        return lines;
    }
}
+217 −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.internal.os;

import static android.os.BatteryStats.STATS_SINCE_CHARGED;

import static com.android.internal.os.BatteryStatsImpl.LongSamplingCounterArray;
import static com.android.internal.os.BatteryStatsImpl.TimeBase;

import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;

import android.os.Parcel;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;

import java.util.Arrays;

/**
 * Test class for {@link BatteryStatsImpl.LongSamplingCounterArray}.
 *
 * To run the tests, use
 *
 * runtest -c com.android.internal.os.LongSamplingCounterArrayTest frameworks-core
 *
 * or the following steps:
 *
 * Build: m FrameworksCoreTests
 * Install: adb install -r \
 *     ${ANDROID_PRODUCT_OUT}/data/app/FrameworksCoreTests/FrameworksCoreTests.apk
 * Run: adb shell am instrument -e class com.android.internal.os.LongSamplingCounterArrayTest -w \
 *     com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner
 */
@SmallTest
@RunWith(AndroidJUnit4.class)
public class LongSamplingCounterArrayTest {

    private static final long[] COUNTS = {1111, 2222, 3333, 4444};
    private static final long[] LOADED_COUNTS = {5555, 6666, 7777, 8888};
    private static final long[] PLUGGED_COUNTS = {9999, 11111, 22222, 33333};
    private static final long[] UNPLUGGED_COUNTS = {44444, 55555, 66666, 77777};
    private static final long[] ZEROES = {0, 0, 0, 0};

    @Mock private TimeBase mTimeBase;
    private LongSamplingCounterArray mCounterArray;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mCounterArray = new LongSamplingCounterArray(mTimeBase);
        Mockito.reset(mTimeBase);
    }

    @Test
    public void testReadWriteParcel() {
        final Parcel parcel = Parcel.obtain();
        initializeCounterArrayWithDefaultValues();
        LongSamplingCounterArray.writeToParcel(parcel, mCounterArray);
        parcel.setDataPosition(0);

        // Now clear counterArray and verify values are read from parcel correctly.
        updateCounts(null, null, null, null);
        mCounterArray = LongSamplingCounterArray.readFromParcel(parcel, mTimeBase);
        assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
        assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts,
                "Unexpected unpluggedCounts");
        parcel.recycle();
    }

    @Test
    public void testReadWriteSummaryParcel() {
        final Parcel parcel = Parcel.obtain();
        initializeCounterArrayWithDefaultValues();
        LongSamplingCounterArray.writeSummaryToParcelLocked(parcel, mCounterArray);
        parcel.setDataPosition(0);

        // Now clear counterArray and verify values are read from parcel correctly.
        updateCounts(null, null, null, null);
        mCounterArray = LongSamplingCounterArray.readSummaryFromParcelLocked(parcel, mTimeBase);
        assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
        assertArrayEquals(COUNTS, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts");
        parcel.recycle();
    }

    @Test
    public void testOnTimeStarted() {
        initializeCounterArrayWithDefaultValues();
        mCounterArray.onTimeStarted(0, 0, 0);
        assertArrayEquals(PLUGGED_COUNTS, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(PLUGGED_COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
        assertArrayEquals(PLUGGED_COUNTS, mCounterArray.mUnpluggedCounts,
                "Unexpected unpluggedCounts");
    }

    @Test
    public void testOnTimeStopped() {
        initializeCounterArrayWithDefaultValues();
        mCounterArray.onTimeStopped(0, 0, 0);
        assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
        assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts,
                "Unexpected unpluggedCounts");
    }

    @Test
    public void testGetCountsLocked() {
        initializeCounterArrayWithDefaultValues();

        when(mTimeBase.isRunning()).thenReturn(false);
        long[] actualVal = mCounterArray.getCountsLocked(STATS_SINCE_CHARGED);
        long[] expectedVal = PLUGGED_COUNTS;
        assertArrayEquals(expectedVal, actualVal, "Unexpected values");

        when(mTimeBase.isRunning()).thenReturn(true);
        actualVal = mCounterArray.getCountsLocked(STATS_SINCE_CHARGED);
        expectedVal = COUNTS;
        assertArrayEquals(expectedVal, actualVal, "Unexpected values");
    }

    @Test
    public void testAddCountLocked() {
        final long[] deltas = {123, 234, 345, 456};
        mCounterArray.addCountLocked(deltas);
        assertArrayEquals(deltas, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(null, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(null, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
        assertArrayEquals(null, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts");

        initializeCounterArrayWithDefaultValues();
        final long[] newCounts = new long[deltas.length];
        for (int i = 0; i < deltas.length; ++i) {
            newCounts[i] = COUNTS[i] + deltas[i];
        }
        mCounterArray.addCountLocked(deltas);
        assertArrayEquals(newCounts, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(PLUGGED_COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
        assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts,
                "Unexpected unpluggedCounts");
    }

    @Test
    public void testReset() {
        initializeCounterArrayWithDefaultValues();
        // Test with detachIfReset=false
        mCounterArray.reset(false /* detachIfReset */);
        assertArrayEquals(ZEROES, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(ZEROES, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(ZEROES, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
        assertArrayEquals(ZEROES, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts");
        verifyZeroInteractions(mTimeBase);

        initializeCounterArrayWithDefaultValues();
        // Test with detachIfReset=true
        mCounterArray.reset(true /* detachIfReset */);
        assertArrayEquals(ZEROES, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(ZEROES, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(ZEROES, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
        assertArrayEquals(ZEROES, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts");
        verify(mTimeBase).remove(mCounterArray);
        verifyNoMoreInteractions(mTimeBase);
    }

    @Test
    public void testDetach() {
        mCounterArray.detach();
        verify(mTimeBase).remove(mCounterArray);
        verifyNoMoreInteractions(mTimeBase);
    }

    private void initializeCounterArrayWithDefaultValues() {
        updateCounts(COUNTS, LOADED_COUNTS, PLUGGED_COUNTS, UNPLUGGED_COUNTS);
    }

    private void assertArrayEquals(long[] expected, long[] actual, String msg) {
        assertTrue(msg + ", expected: " + Arrays.toString(expected)
                + ", actual: " + Arrays.toString(actual), Arrays.equals(expected, actual));
    }

    private void updateCounts(long[] counts, long[] loadedCounts,
            long[] pluggedCounts, long[] unpluggedCounts) {
        mCounterArray.mCounts = counts;
        mCounterArray.mLoadedCounts = loadedCounts;
        mCounterArray.mPluggedCounts = pluggedCounts;
        mCounterArray.mUnpluggedCounts = unpluggedCounts;
    }
}