summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Remi NGUYEN VAN <reminv@google.com> 2021-07-02 16:20:07 +0900
committer Remi NGUYEN VAN <reminv@google.com> 2021-07-02 16:21:56 +0900
commitaaa5249e58520a11f4923af364013b80974831a6 (patch)
treed4a3cdc62fa00b3b8696ae017c48561e8f9db5a8
parentf9eb7b947a88b905a1cd4bb3e0b22582cae26055 (diff)
Move BitUtils, RingBuffer test to coretests
The utilities are part of com.android.internal.util, but were historically tested as part of the services.net tests. They were then mistakenly moved to packages/modules/Connectivity with the rest of the networking code, but actually belong in coretests. Bug: 187935317 Test: atest FrameworksCoreTests Change-Id: Ia4179ac3e25170e46b47133be0f5d4f1b24caf3d
-rw-r--r--core/tests/coretests/src/com/android/internal/util/BitUtilsTest.java201
-rw-r--r--core/tests/coretests/src/com/android/internal/util/RingBufferTest.java178
2 files changed, 379 insertions, 0 deletions
diff --git a/core/tests/coretests/src/com/android/internal/util/BitUtilsTest.java b/core/tests/coretests/src/com/android/internal/util/BitUtilsTest.java
new file mode 100644
index 000000000000..fdba811f3eaa
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/util/BitUtilsTest.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2021 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.util;
+
+import static com.android.internal.util.BitUtils.bytesToBEInt;
+import static com.android.internal.util.BitUtils.bytesToLEInt;
+import static com.android.internal.util.BitUtils.getUint16;
+import static com.android.internal.util.BitUtils.getUint32;
+import static com.android.internal.util.BitUtils.getUint8;
+import static com.android.internal.util.BitUtils.packBits;
+import static com.android.internal.util.BitUtils.uint16;
+import static com.android.internal.util.BitUtils.uint32;
+import static com.android.internal.util.BitUtils.uint8;
+import static com.android.internal.util.BitUtils.unpackBits;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.Random;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class BitUtilsTest {
+
+ @Test
+ public void testUnsignedByteWideningConversions() {
+ byte b0 = 0;
+ byte b1 = 1;
+ byte bm1 = -1;
+ assertEquals(0, uint8(b0));
+ assertEquals(1, uint8(b1));
+ assertEquals(127, uint8(Byte.MAX_VALUE));
+ assertEquals(128, uint8(Byte.MIN_VALUE));
+ assertEquals(255, uint8(bm1));
+ assertEquals(255, uint8((byte)255));
+ }
+
+ @Test
+ public void testUnsignedShortWideningConversions() {
+ short s0 = 0;
+ short s1 = 1;
+ short sm1 = -1;
+ assertEquals(0, uint16(s0));
+ assertEquals(1, uint16(s1));
+ assertEquals(32767, uint16(Short.MAX_VALUE));
+ assertEquals(32768, uint16(Short.MIN_VALUE));
+ assertEquals(65535, uint16(sm1));
+ assertEquals(65535, uint16((short)65535));
+ }
+
+ @Test
+ public void testUnsignedShortComposition() {
+ byte b0 = 0;
+ byte b1 = 1;
+ byte b2 = 2;
+ byte b10 = 10;
+ byte b16 = 16;
+ byte b128 = -128;
+ byte b224 = -32;
+ byte b255 = -1;
+ assertEquals(0x0000, uint16(b0, b0));
+ assertEquals(0xffff, uint16(b255, b255));
+ assertEquals(0x0a01, uint16(b10, b1));
+ assertEquals(0x8002, uint16(b128, b2));
+ assertEquals(0x01ff, uint16(b1, b255));
+ assertEquals(0x80ff, uint16(b128, b255));
+ assertEquals(0xe010, uint16(b224, b16));
+ }
+
+ @Test
+ public void testUnsignedIntWideningConversions() {
+ assertEquals(0, uint32(0));
+ assertEquals(1, uint32(1));
+ assertEquals(2147483647L, uint32(Integer.MAX_VALUE));
+ assertEquals(2147483648L, uint32(Integer.MIN_VALUE));
+ assertEquals(4294967295L, uint32(-1));
+ assertEquals(4294967295L, uint32((int)4294967295L));
+ }
+
+ @Test
+ public void testBytesToInt() {
+ assertEquals(0x00000000, bytesToBEInt(bytes(0, 0, 0, 0)));
+ assertEquals(0xffffffff, bytesToBEInt(bytes(255, 255, 255, 255)));
+ assertEquals(0x0a000001, bytesToBEInt(bytes(10, 0, 0, 1)));
+ assertEquals(0x0a000002, bytesToBEInt(bytes(10, 0, 0, 2)));
+ assertEquals(0x0a001fff, bytesToBEInt(bytes(10, 0, 31, 255)));
+ assertEquals(0xe0000001, bytesToBEInt(bytes(224, 0, 0, 1)));
+
+ assertEquals(0x00000000, bytesToLEInt(bytes(0, 0, 0, 0)));
+ assertEquals(0x01020304, bytesToLEInt(bytes(4, 3, 2, 1)));
+ assertEquals(0xffff0000, bytesToLEInt(bytes(0, 0, 255, 255)));
+ }
+
+ @Test
+ public void testUnsignedGetters() {
+ ByteBuffer b = ByteBuffer.allocate(4);
+ b.putInt(0xffff);
+
+ assertEquals(0x0, getUint8(b, 0));
+ assertEquals(0x0, getUint8(b, 1));
+ assertEquals(0xff, getUint8(b, 2));
+ assertEquals(0xff, getUint8(b, 3));
+
+ assertEquals(0x0, getUint16(b, 0));
+ assertEquals(0xffff, getUint16(b, 2));
+
+ b.rewind();
+ b.putInt(0xffffffff);
+ assertEquals(0xffffffffL, getUint32(b, 0));
+ }
+
+ @Test
+ public void testBitsPacking() {
+ BitPackingTestCase[] testCases = {
+ new BitPackingTestCase(0, ints()),
+ new BitPackingTestCase(1, ints(0)),
+ new BitPackingTestCase(2, ints(1)),
+ new BitPackingTestCase(3, ints(0, 1)),
+ new BitPackingTestCase(4, ints(2)),
+ new BitPackingTestCase(6, ints(1, 2)),
+ new BitPackingTestCase(9, ints(0, 3)),
+ new BitPackingTestCase(~Long.MAX_VALUE, ints(63)),
+ new BitPackingTestCase(~Long.MAX_VALUE + 1, ints(0, 63)),
+ new BitPackingTestCase(~Long.MAX_VALUE + 2, ints(1, 63)),
+ };
+ for (BitPackingTestCase tc : testCases) {
+ int[] got = unpackBits(tc.packedBits);
+ assertTrue(
+ "unpackBits("
+ + tc.packedBits
+ + "): expected "
+ + Arrays.toString(tc.bits)
+ + " but got "
+ + Arrays.toString(got),
+ Arrays.equals(tc.bits, got));
+ }
+ for (BitPackingTestCase tc : testCases) {
+ long got = packBits(tc.bits);
+ assertEquals(
+ "packBits("
+ + Arrays.toString(tc.bits)
+ + "): expected "
+ + tc.packedBits
+ + " but got "
+ + got,
+ tc.packedBits,
+ got);
+ }
+
+ long[] moreTestCases = {
+ 0, 1, -1, 23895, -908235, Long.MAX_VALUE, Long.MIN_VALUE, new Random().nextLong(),
+ };
+ for (long l : moreTestCases) {
+ assertEquals(l, packBits(unpackBits(l)));
+ }
+ }
+
+ static byte[] bytes(int b1, int b2, int b3, int b4) {
+ return new byte[] {b(b1), b(b2), b(b3), b(b4)};
+ }
+
+ static byte b(int i) {
+ return (byte) i;
+ }
+
+ static int[] ints(int... array) {
+ return array;
+ }
+
+ static class BitPackingTestCase {
+ final int[] bits;
+ final long packedBits;
+
+ BitPackingTestCase(long packedBits, int[] bits) {
+ this.bits = bits;
+ this.packedBits = packedBits;
+ }
+ }
+}
diff --git a/core/tests/coretests/src/com/android/internal/util/RingBufferTest.java b/core/tests/coretests/src/com/android/internal/util/RingBufferTest.java
new file mode 100644
index 000000000000..4497770ef40d
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/util/RingBufferTest.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2021 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.util;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class RingBufferTest {
+
+ @Test
+ public void testEmptyRingBuffer() {
+ RingBuffer<String> buffer = new RingBuffer<>(String.class, 100);
+
+ assertArrayEquals(new String[0], buffer.toArray());
+ }
+
+ @Test
+ public void testIncorrectConstructorArguments() {
+ try {
+ RingBuffer<String> buffer = new RingBuffer<>(String.class, -10);
+ fail("Should not be able to create a negative capacity RingBuffer");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ RingBuffer<String> buffer = new RingBuffer<>(String.class, 0);
+ fail("Should not be able to create a 0 capacity RingBuffer");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ @Test
+ public void testRingBufferWithNoWrapping() {
+ RingBuffer<String> buffer = new RingBuffer<>(String.class, 100);
+
+ buffer.append("a");
+ buffer.append("b");
+ buffer.append("c");
+ buffer.append("d");
+ buffer.append("e");
+
+ String[] expected = {"a", "b", "c", "d", "e"};
+ assertArrayEquals(expected, buffer.toArray());
+ }
+
+ @Test
+ public void testRingBufferWithCapacity1() {
+ RingBuffer<String> buffer = new RingBuffer<>(String.class, 1);
+
+ buffer.append("a");
+ assertArrayEquals(new String[]{"a"}, buffer.toArray());
+
+ buffer.append("b");
+ assertArrayEquals(new String[]{"b"}, buffer.toArray());
+
+ buffer.append("c");
+ assertArrayEquals(new String[]{"c"}, buffer.toArray());
+
+ buffer.append("d");
+ assertArrayEquals(new String[]{"d"}, buffer.toArray());
+
+ buffer.append("e");
+ assertArrayEquals(new String[]{"e"}, buffer.toArray());
+ }
+
+ @Test
+ public void testRingBufferWithWrapping() {
+ int capacity = 100;
+ RingBuffer<String> buffer = new RingBuffer<>(String.class, capacity);
+
+ buffer.append("a");
+ buffer.append("b");
+ buffer.append("c");
+ buffer.append("d");
+ buffer.append("e");
+
+ String[] expected1 = {"a", "b", "c", "d", "e"};
+ assertArrayEquals(expected1, buffer.toArray());
+
+ String[] expected2 = new String[capacity];
+ int firstIndex = 0;
+ int lastIndex = capacity - 1;
+
+ expected2[firstIndex] = "e";
+ for (int i = 1; i < capacity; i++) {
+ buffer.append("x");
+ expected2[i] = "x";
+ }
+ assertArrayEquals(expected2, buffer.toArray());
+
+ buffer.append("x");
+ expected2[firstIndex] = "x";
+ assertArrayEquals(expected2, buffer.toArray());
+
+ for (int i = 0; i < 10; i++) {
+ for (String s : expected2) {
+ buffer.append(s);
+ }
+ }
+ assertArrayEquals(expected2, buffer.toArray());
+
+ buffer.append("a");
+ expected2[lastIndex] = "a";
+ assertArrayEquals(expected2, buffer.toArray());
+ }
+
+ @Test
+ public void testGetNextSlot() {
+ int capacity = 100;
+ RingBuffer<DummyClass1> buffer = new RingBuffer<>(DummyClass1.class, capacity);
+
+ final DummyClass1[] actual = new DummyClass1[capacity];
+ final DummyClass1[] expected = new DummyClass1[capacity];
+ for (int i = 0; i < capacity; ++i) {
+ final DummyClass1 obj = buffer.getNextSlot();
+ obj.x = capacity * i;
+ actual[i] = obj;
+ expected[i] = new DummyClass1();
+ expected[i].x = capacity * i;
+ }
+ assertArrayEquals(expected, buffer.toArray());
+
+ for (int i = 0; i < capacity; ++i) {
+ if (actual[i] != buffer.getNextSlot()) {
+ fail("getNextSlot() should re-use objects if available");
+ }
+ }
+
+ RingBuffer<DummyClass2> buffer2 = new RingBuffer<>(DummyClass2.class, capacity);
+ assertNull("getNextSlot() should return null if the object can't be initiated "
+ + "(No nullary constructor)", buffer2.getNextSlot());
+
+ RingBuffer<DummyClass3> buffer3 = new RingBuffer<>(DummyClass3.class, capacity);
+ assertNull("getNextSlot() should return null if the object can't be initiated "
+ + "(Inaccessible class)", buffer3.getNextSlot());
+ }
+
+ public static final class DummyClass1 {
+ int x;
+
+ public boolean equals(Object o) {
+ if (o instanceof DummyClass1) {
+ final DummyClass1 other = (DummyClass1) o;
+ return other.x == this.x;
+ }
+ return false;
+ }
+ }
+
+ public static final class DummyClass2 {
+ public DummyClass2(int x) {}
+ }
+
+ private static final class DummyClass3 {}
+}