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

Commit 602bf1a8 authored by Bernardo Rufino's avatar Bernardo Rufino
Browse files

Add tests for TransportStats and some refactor

Added units for http://ag/3709565. Some refactoring.

Test: m -j RunFrameworksServicesRoboTests
Bug: 72485465
Change-Id: Id75a4e0b96936580fd677041e091340b0fff8c1e
(cherry picked from commit cac3a740)
parent 9554dd94
Loading
Loading
Loading
Loading
+33 −33
Original line number Diff line number Diff line
@@ -32,9 +32,12 @@ public class TransportStats {

    void registerConnectionTime(ComponentName transportComponent, long timeMs) {
        synchronized (mStatsLock) {
            mTransportStats
                    .computeIfAbsent(transportComponent, name -> new Stats())
                    .register(timeMs);
            Stats stats = mTransportStats.get(transportComponent);
            if (stats == null) {
                stats = new Stats();
                mTransportStats.put(transportComponent, stats);
            }
            stats.register(timeMs);
        }
    }

@@ -71,52 +74,49 @@ public class TransportStats {
    private static void dumpStats(PrintWriter pw, String prefix, Stats stats) {
        pw.println(
                String.format(
                        Locale.US, "%sAverage connection time: %.2f ms", prefix, stats.mAverage));
        pw.println(String.format(Locale.US, "%sMax connection time: %d ms", prefix, stats.mMax));
        pw.println(String.format(Locale.US, "%sMin connection time: %d ms", prefix, stats.mMin));
        pw.println(String.format(Locale.US, "%sNumber of connections: %d ", prefix, stats.mN));
                        Locale.US, "%sAverage connection time: %.2f ms", prefix, stats.average));
        pw.println(String.format(Locale.US, "%sMax connection time: %d ms", prefix, stats.max));
        pw.println(String.format(Locale.US, "%sMin connection time: %d ms", prefix, stats.min));
        pw.println(String.format(Locale.US, "%sNumber of connections: %d ", prefix, stats.n));
    }

    public static final class Stats {
        public static Stats merge(Stats a, Stats b) {
            return new Stats(
                    a.mN + b.mN,
                    (a.mAverage * a.mN + b.mAverage * b.mN) / (a.mN + b.mN),
                    Math.max(a.mMax, b.mMax),
                    Math.min(a.mMin, b.mMin));
                    a.n + b.n,
                    (a.average * a.n + b.average * b.n) / (a.n + b.n),
                    Math.max(a.max, b.max),
                    Math.min(a.min, b.min));
        }

        public int mN;
        public double mAverage;
        public long mMax;
        public long mMin;
        public int n;
        public double average;
        public long max;
        public long min;

        public Stats() {
            mN = 0;
            mAverage = 0;
            mMax = 0;
            mMin = Long.MAX_VALUE;
            n = 0;
            average = 0;
            max = 0;
            min = Long.MAX_VALUE;
        }

        private Stats(Stats original) {
            mN = original.mN;
            mAverage = original.mAverage;
            mMax = original.mMax;
            mMin = original.mMin;
        private Stats(int n, double average, long max, long min) {
            this.n = n;
            this.average = average;
            this.max = max;
            this.min = min;
        }

        private Stats(int n, double average, long max, long min) {
            mN = n;
            mAverage = average;
            mMax = max;
            mMin = min;
        private Stats(Stats original) {
            this(original.n, original.average, original.max, original.min);
        }

        private void register(long sample) {
            mAverage = (mAverage * mN + sample) / (mN + 1);
            mN++;
            mMax = Math.max(mMax, sample);
            mMin = Math.min(mMin, sample);
            average = (average * n + sample) / (n + 1);
            n++;
            max = Math.max(max, sample);
            min = Math.min(min, sample);
        }
    }
}
+105 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.backup.transport;

import static com.android.server.backup.testing.TransportData.backupTransport;
import static com.android.server.backup.testing.TransportData.d2dTransport;

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

import android.content.ComponentName;
import android.platform.test.annotations.Presubmit;

import com.android.server.backup.transport.TransportStats.Stats;
import com.android.server.testing.FrameworkRobolectricTestRunner;
import com.android.server.testing.SystemLoaderPackages;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;

@RunWith(FrameworkRobolectricTestRunner.class)
@Config(manifest = Config.NONE, sdk = 26)
@SystemLoaderPackages({"com.android.server.backup"})
@Presubmit
public class TransportStatsTest {
    private static final double TOLERANCE = 0.0001;

    private TransportStats mTransportStats;
    private ComponentName mTransportComponent1;
    private ComponentName mTransportComponent2;

    @Before
    public void setUp() throws Exception {
        mTransportStats = new TransportStats();
        mTransportComponent1 = backupTransport().getTransportComponent();
        mTransportComponent2 = d2dTransport().getTransportComponent();
    }

    @Test
    public void testRegisterConnectionTime() {
        mTransportStats.registerConnectionTime(mTransportComponent1, 50L);

        Stats stats = mTransportStats.getStatsForTransport(mTransportComponent1);
        assertThat(stats.average).isWithin(TOLERANCE).of(50);
        assertThat(stats.max).isEqualTo(50L);
        assertThat(stats.min).isEqualTo(50L);
        assertThat(stats.n).isEqualTo(1);
    }

    @Test
    public void testRegisterConnectionTime_whenHasAlreadyOneSample() {
        mTransportStats.registerConnectionTime(mTransportComponent1, 50L);

        mTransportStats.registerConnectionTime(mTransportComponent1, 100L);

        Stats stats = mTransportStats.getStatsForTransport(mTransportComponent1);
        assertThat(stats.average).isWithin(TOLERANCE).of(75);
        assertThat(stats.max).isEqualTo(100L);
        assertThat(stats.min).isEqualTo(50L);
        assertThat(stats.n).isEqualTo(2);
    }

    @Test
    public void testGetStatsForTransport() {
        mTransportStats.registerConnectionTime(mTransportComponent1, 10L);
        mTransportStats.registerConnectionTime(mTransportComponent2, 20L);

        Stats stats = mTransportStats.getStatsForTransport(mTransportComponent1);

        assertThat(stats.average).isWithin(TOLERANCE).of(10);
        assertThat(stats.max).isEqualTo(10L);
        assertThat(stats.min).isEqualTo(10L);
        assertThat(stats.n).isEqualTo(1);
    }

    @Test
    public void testMerge() {
        mTransportStats.registerConnectionTime(mTransportComponent1, 10L);
        mTransportStats.registerConnectionTime(mTransportComponent2, 20L);
        Stats stats1 = mTransportStats.getStatsForTransport(mTransportComponent1);
        Stats stats2 = mTransportStats.getStatsForTransport(mTransportComponent2);

        Stats stats = Stats.merge(stats1, stats2);

        assertThat(stats.average).isWithin(TOLERANCE).of(15);
        assertThat(stats.max).isEqualTo(20L);
        assertThat(stats.min).isEqualTo(10L);
        assertThat(stats.n).isEqualTo(2);
    }
}