blob: cf90242550cb8acdd3d2bc2c25611a50abc38e25 [file] [log] [blame]
/*
* 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.car.telemetry.publisher.net;
import static android.net.NetworkStats.TAG_NONE;
import static com.google.common.truth.Truth.assertThat;
import android.annotation.NonNull;
import android.car.test.mocks.AbstractExtendedMockitoTestCase;
import android.net.NetworkStats;
import android.os.PersistableBundle;
import com.android.internal.util.FastXmlSerializer;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
import java.io.StringWriter;
/**
* Tests for {@link RefinedStats}. Some logic is acquired from {@link android.net.NetworkStatsTest}
* in {@code FrameworksNetTests} test package.
*/
@RunWith(MockitoJUnitRunner.class)
public class RefinedStatsTest extends AbstractExtendedMockitoTestCase {
private static final int UID_0 = 0;
private static final int UID_1 = 1;
private static final int UID_2 = 2;
private static final int TAG_1 = 1;
private RefinedStats mRefinedStats; // subject
@Before
public void setUp() throws Exception {
mRefinedStats = new RefinedStats(/* startMillis= */ 10_000, /* endMillis= */ 20_000);
}
@Override
protected void onSessionBuilder(@NonNull CustomMockitoSessionBuilder session) {}
@Test
public void testAddNetworkStats_toPersistableBundle() throws Exception {
FakeNetworkStats stats = new FakeNetworkStats();
stats.add(buildBucket(UID_0, TAG_1, /* rx= */ 4096, /* tx= */ 2048));
stats.add(buildBucket(UID_1, TAG_NONE, /* rx= */ 4095, /* tx= */ 2047));
stats.add(buildBucket(UID_0, TAG_1, /* rx= */ 10000, /* tx= */ 10000)); // merges with 1st
mRefinedStats.addNetworkStats(stats.getNetworkStats());
PersistableBundle result = mRefinedStats.toPersistableBundle();
PersistableBundle expected = new PersistableBundle();
expected.putLong("startMillis", 10_000);
expected.putLong("endMillis", 20_000);
expected.putInt("size", 2);
expected.putIntArray("uid", new int[] {UID_0, UID_1});
expected.putIntArray("tag", new int[] {TAG_1, TAG_NONE});
expected.putLongArray("rxBytes", new long[] {14096, 4095});
expected.putLongArray("txBytes", new long[] {12048, 2047});
assertThat(bundleToXml(result)).isEqualTo(bundleToXml(expected));
}
@Test
public void testIsEmpty() throws Exception {
FakeNetworkStats stats = new FakeNetworkStats();
stats.add(buildBucket(UID_0, TAG_NONE, /* rx= */ 256, /* tx= */ 256));
assertThat(mRefinedStats.isEmpty()).isTrue();
mRefinedStats.addNetworkStats(stats.getNetworkStats());
assertThat(mRefinedStats.isEmpty()).isFalse();
}
@Test
public void testSubtract() throws Exception {
FakeNetworkStats stats = new FakeNetworkStats();
stats.add(buildBucket(UID_1, TAG_NONE, /* rx= */ 4096, /* tx= */ 2048));
stats.add(buildBucket(UID_1, TAG_1, /* rx= */ 4096, /* tx= */ 2048));
// This one is not present in "other" below.
stats.add(buildBucket(UID_2, TAG_NONE, /* rx= */ 4096, /* tx= */ 2048));
mRefinedStats.addNetworkStats(stats.getNetworkStats());
FakeNetworkStats stats2 = new FakeNetworkStats();
stats2.add(buildBucket(UID_1, TAG_NONE, /* rx= */ 6, /* tx= */ 8));
stats2.add(buildBucket(UID_1, TAG_1, /* rx= */ 99999, /* tx= */ 99999));
// This one is not present in mRefinedStats.
stats2.add(buildBucket(UID_0, TAG_1, /* rx= */ 6, /* tx= */ 8));
stats2.add(buildBucket(UID_2, TAG_1, /* rx= */ 6, /* tx= */ 8));
RefinedStats other = new RefinedStats(/* startMillis= */ 9_000, /* endMillis= */ 15_000);
other.addNetworkStats(stats2.getNetworkStats());
RefinedStats diff = RefinedStats.subtract(mRefinedStats, other);
PersistableBundle expected = new PersistableBundle();
expected.putLong("startMillis", 10_000);
expected.putLong("endMillis", 20_000);
expected.putInt("size", 3); // the same size as "mRefinedStats"
expected.putIntArray("uid", new int[] {UID_1, UID_1, UID_2});
expected.putIntArray("tag", new int[] {TAG_NONE, TAG_1, TAG_NONE});
// Handles negative values too (hence 0).
expected.putLongArray("rxBytes", new long[] {4090, 0, 4096});
expected.putLongArray("txBytes", new long[] {2040, 0, 2048});
assertThat(bundleToXml(diff.toPersistableBundle())).isEqualTo(bundleToXml(expected));
}
private static NetworkStats.Entry buildBucket(int uid, int tag, long rx, long tx) {
return new NetworkStats.Entry(
/* iface= */ null,
uid,
NetworkStats.SET_DEFAULT,
tag,
rx,
rx,
tx,
tx,
/* operations= */ 0);
}
/** Converts the bundle to a XML String for easy asserting equality. */
private static String bundleToXml(PersistableBundle bundle) throws Exception {
StringWriter writer = new StringWriter();
FastXmlSerializer serializer = new FastXmlSerializer();
serializer.setOutput(writer);
bundle.saveToXml(serializer);
serializer.flush();
return writer.toString();
}
}