diff options
Diffstat (limited to 'common/tests/unit/src')
60 files changed, 0 insertions, 13656 deletions
diff --git a/common/tests/unit/src/com/android/net/module/util/ArpPacketTest.java b/common/tests/unit/src/com/android/net/module/util/ArpPacketTest.java deleted file mode 100644 index e25d5548..00000000 --- a/common/tests/unit/src/com/android/net/module/util/ArpPacketTest.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (C) 2019 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.net.module.util; - -import static com.android.net.module.util.NetworkStackConstants.ARP_REQUEST; -import static com.android.net.module.util.NetworkStackConstants.ETHER_ADDR_LEN; -import static com.android.net.module.util.NetworkStackConstants.ETHER_BROADCAST; -import static com.android.testutils.MiscAsserts.assertThrows; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; - -import android.net.InetAddresses; -import android.net.MacAddress; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.net.module.util.arp.ArpPacket; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.Inet4Address; -import java.nio.ByteBuffer; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public final class ArpPacketTest { - - private static final Inet4Address TEST_IPV4_ADDR = - (Inet4Address) InetAddresses.parseNumericAddress("192.168.1.2"); - private static final Inet4Address INADDR_ANY = - (Inet4Address) InetAddresses.parseNumericAddress("0.0.0.0"); - private static final byte[] TEST_SENDER_MAC_ADDR = new byte[] { - 0x00, 0x1a, 0x11, 0x22, 0x33, 0x33 }; - private static final byte[] TEST_TARGET_MAC_ADDR = new byte[] { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - private static final byte[] TEST_ARP_PROBE = new byte[] { - // dst mac address - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - // src mac address - (byte) 0x00, (byte) 0x1a, (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x33, - // ether type - (byte) 0x08, (byte) 0x06, - // hardware type - (byte) 0x00, (byte) 0x01, - // protocol type - (byte) 0x08, (byte) 0x00, - // hardware address size - (byte) 0x06, - // protocol address size - (byte) 0x04, - // opcode - (byte) 0x00, (byte) 0x01, - // sender mac address - (byte) 0x00, (byte) 0x1a, (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x33, - // sender IP address - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - // target mac address - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - // target IP address - (byte) 0xc0, (byte) 0xa8, (byte) 0x01, (byte) 0x02, - }; - - private static final byte[] TEST_ARP_ANNOUNCE = new byte[] { - // dst mac address - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - // src mac address - (byte) 0x00, (byte) 0x1a, (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x33, - // ether type - (byte) 0x08, (byte) 0x06, - // hardware type - (byte) 0x00, (byte) 0x01, - // protocol type - (byte) 0x08, (byte) 0x00, - // hardware address size - (byte) 0x06, - // protocol address size - (byte) 0x04, - // opcode - (byte) 0x00, (byte) 0x01, - // sender mac address - (byte) 0x00, (byte) 0x1a, (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x33, - // sender IP address - (byte) 0xc0, (byte) 0xa8, (byte) 0x01, (byte) 0x02, - // target mac address - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - // target IP address - (byte) 0xc0, (byte) 0xa8, (byte) 0x01, (byte) 0x02, - }; - - private static final byte[] TEST_ARP_PROBE_TRUNCATED = new byte[] { - // dst mac address - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - // src mac address - (byte) 0x00, (byte) 0x1a, (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x33, - // ether type - (byte) 0x08, (byte) 0x06, - // hardware type - (byte) 0x00, (byte) 0x01, - // protocol type - (byte) 0x08, (byte) 0x00, - // hardware address size - (byte) 0x06, - // protocol address size - (byte) 0x04, - // opcode - (byte) 0x00, - }; - - private static final byte[] TEST_ARP_PROBE_TRUNCATED_MAC = new byte[] { - // dst mac address - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - // src mac address - (byte) 0x00, (byte) 0x1a, (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x33, - // ether type - (byte) 0x08, (byte) 0x06, - // hardware type - (byte) 0x00, (byte) 0x01, - // protocol type - (byte) 0x08, (byte) 0x00, - // hardware address size - (byte) 0x06, - // protocol address size - (byte) 0x04, - // opcode - (byte) 0x00, (byte) 0x01, - // sender mac address - (byte) 0x00, (byte) 0x1a, (byte) 0x11, (byte) 0x22, (byte) 0x33, - }; - - @Test - public void testBuildArpProbePacket() throws Exception { - final ByteBuffer arpProbe = ArpPacket.buildArpPacket(ETHER_BROADCAST, - TEST_SENDER_MAC_ADDR, TEST_IPV4_ADDR.getAddress(), new byte[ETHER_ADDR_LEN], - INADDR_ANY.getAddress(), (short) ARP_REQUEST); - assertArrayEquals(arpProbe.array(), TEST_ARP_PROBE); - } - - @Test - public void testBuildArpAnnouncePacket() throws Exception { - final ByteBuffer arpAnnounce = ArpPacket.buildArpPacket(ETHER_BROADCAST, - TEST_SENDER_MAC_ADDR, TEST_IPV4_ADDR.getAddress(), new byte[ETHER_ADDR_LEN], - TEST_IPV4_ADDR.getAddress(), (short) ARP_REQUEST); - assertArrayEquals(arpAnnounce.array(), TEST_ARP_ANNOUNCE); - } - - @Test - public void testParseArpProbePacket() throws Exception { - final ArpPacket packet = ArpPacket.parseArpPacket(TEST_ARP_PROBE, TEST_ARP_PROBE.length); - assertEquals(packet.opCode, ARP_REQUEST); - assertEquals(packet.senderHwAddress, MacAddress.fromBytes(TEST_SENDER_MAC_ADDR)); - assertEquals(packet.targetHwAddress, MacAddress.fromBytes(TEST_TARGET_MAC_ADDR)); - assertEquals(packet.senderIp, INADDR_ANY); - assertEquals(packet.targetIp, TEST_IPV4_ADDR); - } - - @Test - public void testParseArpAnnouncePacket() throws Exception { - final ArpPacket packet = ArpPacket.parseArpPacket(TEST_ARP_ANNOUNCE, - TEST_ARP_ANNOUNCE.length); - assertEquals(packet.opCode, ARP_REQUEST); - assertEquals(packet.senderHwAddress, MacAddress.fromBytes(TEST_SENDER_MAC_ADDR)); - assertEquals(packet.targetHwAddress, MacAddress.fromBytes(TEST_TARGET_MAC_ADDR)); - assertEquals(packet.senderIp, TEST_IPV4_ADDR); - assertEquals(packet.targetIp, TEST_IPV4_ADDR); - } - - @Test - public void testParseArpPacket_invalidByteBufferParameters() throws Exception { - assertThrows(ArpPacket.ParseException.class, () -> ArpPacket.parseArpPacket( - TEST_ARP_PROBE, 0)); - } - - @Test - public void testParseArpPacket_truncatedPacket() throws Exception { - assertThrows(ArpPacket.ParseException.class, () -> ArpPacket.parseArpPacket( - TEST_ARP_PROBE_TRUNCATED, TEST_ARP_PROBE_TRUNCATED.length)); - } - - @Test - public void testParseArpPacket_truncatedMacAddress() throws Exception { - assertThrows(ArpPacket.ParseException.class, () -> ArpPacket.parseArpPacket( - TEST_ARP_PROBE_TRUNCATED_MAC, TEST_ARP_PROBE_TRUNCATED.length)); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/BitUtilsTests.kt b/common/tests/unit/src/com/android/net/module/util/BitUtilsTests.kt deleted file mode 100644 index 49940ea8..00000000 --- a/common/tests/unit/src/com/android/net/module/util/BitUtilsTests.kt +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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.net.module.util - -import com.android.net.module.util.BitUtils.appendStringRepresentationOfBitMaskToStringBuilder -import com.android.net.module.util.BitUtils.describeDifferences -import com.android.net.module.util.BitUtils.packBits -import com.android.net.module.util.BitUtils.unpackBits -import kotlin.test.assertEquals -import kotlin.test.assertNull -import kotlin.test.assertTrue -import org.junit.Test - -class BitUtilsTests { - @Test - fun testBitPackingTestCase() { - runBitPackingTestCase(0, intArrayOf()) - runBitPackingTestCase(1, intArrayOf(0)) - runBitPackingTestCase(3, intArrayOf(0, 1)) - runBitPackingTestCase(4, intArrayOf(2)) - runBitPackingTestCase(63, intArrayOf(0, 1, 2, 3, 4, 5)) - runBitPackingTestCase(Long.MAX_VALUE.inv(), intArrayOf(63)) - runBitPackingTestCase(Long.MAX_VALUE.inv() + 1, intArrayOf(0, 63)) - runBitPackingTestCase(Long.MAX_VALUE.inv() + 2, intArrayOf(1, 63)) - } - - fun runBitPackingTestCase(packedBits: Long, bits: IntArray) { - assertEquals(packedBits, packBits(bits)) - assertTrue(bits contentEquals unpackBits(packedBits)) - } - - @Test - fun testAppendStringRepresentationOfBitMaskToStringBuilder() { - runTestAppendStringRepresentationOfBitMaskToStringBuilder("", 0) - runTestAppendStringRepresentationOfBitMaskToStringBuilder("BIT0", 0b1) - runTestAppendStringRepresentationOfBitMaskToStringBuilder("BIT1&BIT2&BIT4", 0b10110) - runTestAppendStringRepresentationOfBitMaskToStringBuilder( - "BIT0&BIT60&BIT61&BIT62&BIT63", - (0b11110000_00000000_00000000_00000000 shl 32) + - 0b00000000_00000000_00000000_00000001) - } - - fun runTestAppendStringRepresentationOfBitMaskToStringBuilder(expected: String, bitMask: Long) { - StringBuilder().let { - appendStringRepresentationOfBitMaskToStringBuilder(it, bitMask, { i -> "BIT$i" }, "&") - assertEquals(expected, it.toString()) - } - } - - @Test - fun testDescribeDifferences() { - fun describe(a: Long, b: Long) = describeDifferences(a, b, Integer::toString) - assertNull(describe(0, 0)) - assertNull(describe(5, 5)) - assertNull(describe(Long.MAX_VALUE, Long.MAX_VALUE)) - - assertEquals("+0", describe(0, 1)) - assertEquals("-0", describe(1, 0)) - - assertEquals("+0+2", describe(0, 5)) - assertEquals("+2", describe(1, 5)) - assertEquals("-0+2", describe(1, 4)) - - fun makeField(vararg i: Int) = i.sumOf { 1L shl it } - assertEquals("-0-4-6-9+1+3+11", describe(makeField(0, 4, 6, 9), makeField(1, 3, 11))) - assertEquals("-1-5-9+6+8", describe(makeField(0, 1, 3, 4, 5, 9), makeField(0, 3, 4, 6, 8))) - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/BpfDumpTest.java b/common/tests/unit/src/com/android/net/module/util/BpfDumpTest.java deleted file mode 100644 index a66dacd9..00000000 --- a/common/tests/unit/src/com/android/net/module/util/BpfDumpTest.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * 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.net.module.util; - -import static android.system.OsConstants.EPERM; -import static android.system.OsConstants.R_OK; - -import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.doThrow; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThrows; -import static org.junit.Assert.assertTrue; - -import android.system.ErrnoException; -import android.system.Os; -import android.util.Pair; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.testutils.TestBpfMap; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.MockitoSession; - -import java.io.PrintWriter; -import java.io.StringWriter; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class BpfDumpTest { - private static final int TEST_KEY = 123; - private static final String TEST_KEY_BASE64 = "ewAAAA=="; - private static final int TEST_VAL = 456; - private static final String TEST_VAL_BASE64 = "yAEAAA=="; - private static final String BASE64_DELIMITER = ","; - private static final String TEST_KEY_VAL_BASE64 = - TEST_KEY_BASE64 + BASE64_DELIMITER + TEST_VAL_BASE64; - private static final String INVALID_BASE64_STRING = "Map is null"; - - @Test - public void testToBase64EncodedString() { - final Struct.S32 key = new Struct.S32(TEST_KEY); - final Struct.S32 value = new Struct.S32(TEST_VAL); - - // Verified in python: - // import base64 - // print(base64.b64encode(b'\x7b\x00\x00\x00')) # key: ewAAAA== (TEST_KEY_BASE64) - // print(base64.b64encode(b'\xc8\x01\x00\x00')) # value: yAEAAA== (TEST_VAL_BASE64) - assertEquals("7B000000", HexDump.toHexString(key.writeToBytes())); - assertEquals("C8010000", HexDump.toHexString(value.writeToBytes())); - assertEquals(TEST_KEY_VAL_BASE64, BpfDump.toBase64EncodedString(key, value)); - } - - @Test - public void testFromBase64EncodedString() { - Pair<Struct.S32, Struct.S32> decodedKeyValue = BpfDump.fromBase64EncodedString( - Struct.S32.class, Struct.S32.class, TEST_KEY_VAL_BASE64); - assertEquals(TEST_KEY, decodedKeyValue.first.val); - assertEquals(TEST_VAL, decodedKeyValue.second.val); - } - - private void assertThrowsIllegalArgumentException(final String testStr) { - assertThrows(IllegalArgumentException.class, - () -> BpfDump.fromBase64EncodedString(Struct.S32.class, Struct.S32.class, testStr)); - } - - @Test - public void testFromBase64EncodedStringInvalidString() { - assertThrowsIllegalArgumentException(INVALID_BASE64_STRING); - assertThrowsIllegalArgumentException(TEST_KEY_BASE64); - assertThrowsIllegalArgumentException( - TEST_KEY_BASE64 + BASE64_DELIMITER + INVALID_BASE64_STRING); - assertThrowsIllegalArgumentException( - INVALID_BASE64_STRING + BASE64_DELIMITER + TEST_VAL_BASE64); - assertThrowsIllegalArgumentException( - INVALID_BASE64_STRING + BASE64_DELIMITER + INVALID_BASE64_STRING); - assertThrowsIllegalArgumentException( - TEST_KEY_VAL_BASE64 + BASE64_DELIMITER + TEST_KEY_BASE64); - } - - private String getDumpMap(final IBpfMap<Struct.S32, Struct.S32> map) { - final StringWriter sw = new StringWriter(); - BpfDump.dumpMap(map, new PrintWriter(sw), "mapName", "header", - (key, val) -> "key=" + key.val + ", val=" + val.val); - return sw.toString(); - } - - @Test - public void testDumpMap() throws Exception { - final IBpfMap<Struct.S32, Struct.S32> map = - new TestBpfMap<>(Struct.S32.class, Struct.S32.class); - map.updateEntry(new Struct.S32(123), new Struct.S32(456)); - - final String dump = getDumpMap(map); - assertEquals(dump, "mapName:\n" - + " header\n" - + " key=123, val=456\n"); - } - - @Test - public void testDumpMapMultipleEntries() throws Exception { - final IBpfMap<Struct.S32, Struct.S32> map = - new TestBpfMap<>(Struct.S32.class, Struct.S32.class); - map.updateEntry(new Struct.S32(123), new Struct.S32(456)); - map.updateEntry(new Struct.S32(789), new Struct.S32(123)); - - final String dump = getDumpMap(map); - assertTrue(dump.contains("mapName:")); - assertTrue(dump.contains("header")); - assertTrue(dump.contains("key=123, val=456")); - assertTrue(dump.contains("key=789, val=123")); - } - - private String getDumpMapStatus(final IBpfMap<Struct.S32, Struct.S32> map) { - final StringWriter sw = new StringWriter(); - BpfDump.dumpMapStatus(map, new PrintWriter(sw), "mapName", "mapPath"); - return sw.toString(); - } - - @Test - public void testGetMapStatus() { - final IBpfMap<Struct.S32, Struct.S32> map = - new TestBpfMap<>(Struct.S32.class, Struct.S32.class); - assertEquals("mapName: OK\n", getDumpMapStatus(map)); - } - - @Test - public void testGetMapStatusNull() { - final MockitoSession session = mockitoSession() - .spyStatic(Os.class) - .startMocking(); - try { - // Os.access succeeds - doReturn(true).when(() -> Os.access("mapPath", R_OK)); - assertEquals("mapName: NULL(map is pinned to mapPath)\n", getDumpMapStatus(null)); - - // Os.access throws EPERM - doThrow(new ErrnoException("", EPERM)).when(() -> Os.access("mapPath", R_OK)); - assertEquals("mapName: NULL(map is not pinned to mapPath: Operation not permitted)\n", - getDumpMapStatus(null)); - } finally { - session.finishMocking(); - } - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/ByteUtilsTests.kt b/common/tests/unit/src/com/android/net/module/util/ByteUtilsTests.kt deleted file mode 100644 index e58adad3..00000000 --- a/common/tests/unit/src/com/android/net/module/util/ByteUtilsTests.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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.net.module.util - -import com.android.net.module.util.ByteUtils.indexOf -import com.android.net.module.util.ByteUtils.concat -import org.junit.Test -import kotlin.test.assertContentEquals -import kotlin.test.assertEquals -import kotlin.test.assertNotSame - -class ByteUtilsTests { - private val EMPTY = byteArrayOf() - private val ARRAY1 = byteArrayOf(1) - private val ARRAY234 = byteArrayOf(2, 3, 4) - - @Test - fun testIndexOf() { - assertEquals(-1, indexOf(EMPTY, 1)) - assertEquals(-1, indexOf(ARRAY1, 2)) - assertEquals(-1, indexOf(ARRAY234, 1)) - assertEquals(0, indexOf(byteArrayOf(-1), -1)) - assertEquals(0, indexOf(ARRAY234, 2)) - assertEquals(1, indexOf(ARRAY234, 3)) - assertEquals(2, indexOf(ARRAY234, 4)) - assertEquals(1, indexOf(byteArrayOf(2, 3, 2, 3), 3)) - } - - @Test - fun testConcat() { - assertContentEquals(EMPTY, concat()) - assertContentEquals(EMPTY, concat(EMPTY)) - assertContentEquals(EMPTY, concat(EMPTY, EMPTY, EMPTY)) - assertContentEquals(ARRAY1, concat(ARRAY1)) - assertNotSame(ARRAY1, concat(ARRAY1)) - assertContentEquals(ARRAY1, concat(EMPTY, ARRAY1, EMPTY)) - assertContentEquals(byteArrayOf(1, 1, 1), concat(ARRAY1, ARRAY1, ARRAY1)) - assertContentEquals(byteArrayOf(1, 2, 3, 4), concat(ARRAY1, ARRAY234)) - } -}
\ No newline at end of file diff --git a/common/tests/unit/src/com/android/net/module/util/CleanupTest.kt b/common/tests/unit/src/com/android/net/module/util/CleanupTest.kt deleted file mode 100644 index 851d09af..00000000 --- a/common/tests/unit/src/com/android/net/module/util/CleanupTest.kt +++ /dev/null @@ -1,223 +0,0 @@ -/* - * 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.net.module.util - -import android.util.Log -import com.android.testutils.tryTest -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.JUnit4 -import kotlin.test.assertEquals -import kotlin.test.assertFailsWith -import kotlin.test.assertTrue -import kotlin.test.fail - -private val TAG = CleanupTest::class.simpleName - -@RunWith(JUnit4::class) -class CleanupTest { - class TestException1 : Exception() - class TestException2 : Exception() - class TestException3 : Exception() - - @Test - fun testNotThrow() { - var x = 1 - val result = tryTest { - x = 2 - Log.e(TAG, "Do nothing") - 6 - } cleanup { - assertTrue(x == 2) - x = 3 - Log.e(TAG, "Do nothing") - } - assertTrue(x == 3) - assertTrue(result == 6) - } - - @Test - fun testThrowTry() { - var x = 1 - val thrown = assertFailsWith<TestException1> { - tryTest { - x = 2 - throw TestException1() - x = 4 - } cleanup { - assertTrue(x == 2) - x = 3 - Log.e(TAG, "Do nothing") - } - } - assertTrue(thrown.suppressedExceptions.isEmpty()) - assertTrue(x == 3) - } - - @Test - fun testThrowCleanup() { - var x = 1 - val thrown = assertFailsWith<TestException2> { - tryTest { - x = 2 - Log.e(TAG, "Do nothing") - } cleanup { - assertTrue(x == 2) - x = 3 - throw TestException2() - x = 4 - } - } - assertTrue(thrown.suppressedExceptions.isEmpty()) - assertTrue(x == 3) - } - - @Test - fun testThrowBoth() { - var x = 1 - val thrown = assertFailsWith<TestException1> { - tryTest { - x = 2 - throw TestException1() - x = 3 - } cleanup { - assertTrue(x == 2) - x = 4 - throw TestException2() - x = 5 - } - } - assertTrue(thrown.suppressedExceptions[0] is TestException2) - assertTrue(x == 4) - } - - @Test - fun testReturn() { - val resultIfSuccess = 11 - val resultIfException = 12 - fun doTestReturn(crash: Boolean) = tryTest { - if (crash) throw RuntimeException() else resultIfSuccess - }.catch<RuntimeException> { - resultIfException - } cleanup {} - - assertTrue(6 == tryTest { 6 } cleanup { Log.e(TAG, "tested") }) - assertEquals(resultIfSuccess, doTestReturn(crash = false)) - assertEquals(resultIfException, doTestReturn(crash = true)) - } - - @Test - fun testCatch() { - var x = 1 - tryTest { - x = 2 - throw TestException1() - x = 3 - }.catch<TestException1> { - x = 4 - }.catch<TestException2> { - x = 5 - } cleanup { - assertTrue(x == 4) - x = 6 - } - assertTrue(x == 6) - } - - @Test - fun testNotCatch() { - var x = 1 - assertFailsWith<TestException1> { - tryTest { - x = 2 - throw TestException1() - }.catch<TestException2> { - fail("Caught TestException2 instead of TestException1") - } cleanup { - assertTrue(x == 2) - x = 3 - } - } - assertTrue(x == 3) - } - - @Test - fun testThrowInCatch() { - var x = 1 - val thrown = assertFailsWith<TestException2> { - tryTest { - x = 2 - throw TestException1() - }.catch<TestException1> { - x = 3 - throw TestException2() - } cleanup { - assertTrue(x == 3) - x = 4 - } - } - assertTrue(x == 4) - assertTrue(thrown.suppressedExceptions.isEmpty()) - } - - @Test - fun testAssertionErrorInCatch() { - var x = 1 - val thrown = assertFailsWith<AssertionError> { - tryTest { - x = 2 - throw TestException1() - }.catch<TestException1> { - x = 3 - fail("Test failure in catch") - } cleanup { - assertTrue(x == 3) - x = 4 - } - } - assertTrue(x == 4) - assertTrue(thrown.suppressedExceptions.isEmpty()) - } - - @Test - fun testMultipleCleanups() { - var x = 1 - val thrown = assertFailsWith<TestException1> { - tryTest { - x = 2 - throw TestException1() - } cleanupStep { - assertTrue(x == 2) - x = 3 - throw TestException2() - x = 4 - } cleanupStep { - assertTrue(x == 3) - x = 5 - throw TestException3() - x = 6 - } cleanup { - assertTrue(x == 5) - x = 7 - } - } - assertEquals(2, thrown.suppressedExceptions.size) - assertTrue(thrown.suppressedExceptions[0] is TestException2) - assertTrue(thrown.suppressedExceptions[1] is TestException3) - assert(x == 7) - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/CleanupTestJava.java b/common/tests/unit/src/com/android/net/module/util/CleanupTestJava.java deleted file mode 100644 index 8a13397b..00000000 --- a/common/tests/unit/src/com/android/net/module/util/CleanupTestJava.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * 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.net.module.util; - -import static com.android.testutils.Cleanup.testAndCleanup; -import static com.android.testutils.MiscAsserts.assertThrows; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import android.util.Log; - -import org.junit.Test; - -import java.util.concurrent.atomic.AtomicInteger; - -public class CleanupTestJava { - private static final String TAG = CleanupTestJava.class.getSimpleName(); - private static final class TestException1 extends Exception {} - private static final class TestException2 extends Exception {} - private static final class TestException3 extends Exception {} - - @Test - public void testNotThrow() { - final AtomicInteger x = new AtomicInteger(1); - final int a = testAndCleanup(() -> { - x.compareAndSet(1, 2); - Log.e(TAG, "Do nothing"); - return 6; - }, () -> { - x.compareAndSet(2, 3); - Log.e(TAG, "Do nothing"); - }); - assertEquals(3, x.get()); - assertEquals(6, a); - } - - @Test - public void testThrowTry() { - final AtomicInteger x = new AtomicInteger(1); - assertThrows(TestException1.class, () -> - testAndCleanup(() -> { - x.compareAndSet(1, 2); - throw new TestException1(); - // Java refuses to call x.set(3) here because this line is unreachable - }, () -> { - x.compareAndSet(2, 3); - Log.e(TAG, "Do nothing"); - }) - ); - assertEquals(3, x.get()); - } - - @Test - public void testThrowCleanup() { - final AtomicInteger x = new AtomicInteger(1); - assertThrows(TestException2.class, () -> - testAndCleanup(() -> { - x.compareAndSet(1, 2); - Log.e(TAG, "Do nothing"); - }, () -> { - x.compareAndSet(2, 3); - throw new TestException2(); - // Java refuses to call x.set(4) here because this line is unreachable - }) - ); - assertEquals(3, x.get()); - } - - @Test - public void testThrowBoth() { - final AtomicInteger x = new AtomicInteger(1); - assertThrows(TestException1.class, () -> - testAndCleanup(() -> { - x.compareAndSet(1, 2); - throw new TestException1(); - }, () -> { - x.compareAndSet(2, 3); - throw new TestException2(); - }) - ); - assertEquals(3, x.get()); - } - - @Test - public void testMultipleCleanups() { - final AtomicInteger x = new AtomicInteger(1); - final TestException1 exception = assertThrows(TestException1.class, () -> - testAndCleanup(() -> { - x.compareAndSet(1, 2); - throw new TestException1(); - }, () -> { - x.compareAndSet(2, 3); - throw new TestException2(); - }, () -> { - x.compareAndSet(3, 4); - throw new TestException3(); - }, () -> { - x.compareAndSet(4, 5); - }) - ); - assertEquals(2, exception.getSuppressed().length); - assertTrue(exception.getSuppressed()[0] instanceof TestException2); - assertTrue(exception.getSuppressed()[1] instanceof TestException3); - assertEquals(5, x.get()); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt b/common/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt deleted file mode 100644 index e23f9991..00000000 --- a/common/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt +++ /dev/null @@ -1,182 +0,0 @@ -/* - * 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.net.module.util - -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import com.android.testutils.assertThrows -import org.junit.Test -import org.junit.runner.RunWith -import kotlin.test.assertEquals -import kotlin.test.assertFailsWith -import kotlin.test.assertFalse -import kotlin.test.assertNull -import kotlin.test.assertSame -import kotlin.test.assertTrue - -@RunWith(AndroidJUnit4::class) -@SmallTest -class CollectionUtilsTest { - @Test - fun testAny() { - assertTrue(CollectionUtils.any(listOf("A", "B", "C", "D", "E")) { it == "E" }) - assertFalse(CollectionUtils.any(listOf("A", "B", "C", "D", "E")) { it == "F" }) - assertTrue(CollectionUtils.any(listOf("AA", "BBB")) { it.length >= 3 }) - assertFalse(CollectionUtils.any(listOf("A", "BB", "CCC")) { it.length >= 4 }) - assertFalse(CollectionUtils.any(listOf("A", "BB", "CCC")) { it.length < 0 }) - assertFalse(CollectionUtils.any(listOf<String>()) { true }) - assertFalse(CollectionUtils.any(listOf<String>()) { false }) - assertTrue(CollectionUtils.any(listOf("A")) { true }) - assertFalse(CollectionUtils.any(listOf("A")) { false }) - } - - @Test - fun testIndexOf() { - assertEquals(4, CollectionUtils.indexOf(listOf("A", "B", "C", "D", "E")) { it == "E" }) - assertEquals(0, CollectionUtils.indexOf(listOf("A", "B", "C", "D", "E")) { it == "A" }) - assertEquals(1, CollectionUtils.indexOf(listOf("AA", "BBB", "CCCC")) { it.length >= 3 }) - assertEquals(1, CollectionUtils.indexOf(listOf("AA", null, "CCCC")) { it == null }) - assertEquals(1, CollectionUtils.indexOf(listOf(null, "CCCC")) { it != null }) - } - - @Test - fun testIndexOfSubArray() { - val haystack = byteArrayOf(1, 2, 3, 4, 5) - assertEquals(2, CollectionUtils.indexOfSubArray(haystack, byteArrayOf(3, 4))) - assertEquals(3, CollectionUtils.indexOfSubArray(haystack, byteArrayOf(4, 5))) - assertEquals(4, CollectionUtils.indexOfSubArray(haystack, byteArrayOf(5))) - assertEquals(-1, CollectionUtils.indexOfSubArray(haystack, byteArrayOf(3, 2))) - assertEquals(0, CollectionUtils.indexOfSubArray(haystack, byteArrayOf())) - assertEquals(-1, CollectionUtils.indexOfSubArray(byteArrayOf(), byteArrayOf(3, 2))) - assertEquals(0, CollectionUtils.indexOfSubArray(byteArrayOf(), byteArrayOf())) - } - - @Test - fun testAll() { - assertFalse(CollectionUtils.all(listOf("A", "B", "C", "D", "E")) { it != "E" }) - assertTrue(CollectionUtils.all(listOf("A", "B", "C", "D", "E")) { it != "F" }) - assertFalse(CollectionUtils.all(listOf("A", "BB", "CCC")) { it.length > 2 }) - assertTrue(CollectionUtils.all(listOf("A", "BB", "CCC")) { it.length >= 1 }) - assertTrue(CollectionUtils.all(listOf("A", "BB", "CCC")) { it.length < 4 }) - assertTrue(CollectionUtils.all(listOf<String>()) { true }) - assertTrue(CollectionUtils.all(listOf<String>()) { false }) - assertTrue(CollectionUtils.all(listOf(1)) { true }) - assertFalse(CollectionUtils.all(listOf(1)) { false }) - } - - @Test - fun testContains() { - assertTrue(CollectionUtils.contains(shortArrayOf(10, 20, 30), 10)) - assertTrue(CollectionUtils.contains(shortArrayOf(10, 20, 30), 30)) - assertFalse(CollectionUtils.contains(shortArrayOf(10, 20, 30), 40)) - assertFalse(CollectionUtils.contains(null, 10.toShort())) - assertTrue(CollectionUtils.contains(intArrayOf(10, 20, 30), 10)) - assertTrue(CollectionUtils.contains(intArrayOf(10, 20, 30), 30)) - assertFalse(CollectionUtils.contains(intArrayOf(10, 20, 30), 40)) - assertFalse(CollectionUtils.contains(null, 10.toInt())) - assertTrue(CollectionUtils.contains(arrayOf("A", "B", "C"), "A")) - assertTrue(CollectionUtils.contains(arrayOf("A", "B", "C"), "C")) - assertFalse(CollectionUtils.contains(arrayOf("A", "B", "C"), "D")) - assertFalse(CollectionUtils.contains(null, "A")) - - val list = listOf("A", "B", "Ab", "C", "D", "E", "A", "E") - assertTrue(CollectionUtils.contains(list) { it.length == 2 }) - assertFalse(CollectionUtils.contains(list) { it.length < 1 }) - assertTrue(CollectionUtils.contains(list) { it > "A" }) - assertFalse(CollectionUtils.contains(list) { it > "F" }) - } - - @Test - fun testTotal() { - assertEquals(10, CollectionUtils.total(longArrayOf(3, 6, 1))) - assertEquals(10, CollectionUtils.total(longArrayOf(6, 1, 3))) - assertEquals(10, CollectionUtils.total(longArrayOf(1, 3, 6))) - assertEquals(3, CollectionUtils.total(longArrayOf(1, 1, 1))) - assertEquals(0, CollectionUtils.total(null)) - } - - @Test - fun testFindFirstFindLast() { - val listAE = listOf("A", "B", "C", "D", "E") - assertSame(CollectionUtils.findFirst(listAE) { it == "A" }, listAE[0]) - assertSame(CollectionUtils.findFirst(listAE) { it == "B" }, listAE[1]) - assertSame(CollectionUtils.findFirst(listAE) { it == "E" }, listAE[4]) - assertNull(CollectionUtils.findFirst(listAE) { it == "F" }) - assertSame(CollectionUtils.findLast(listAE) { it == "A" }, listAE[0]) - assertSame(CollectionUtils.findLast(listAE) { it == "B" }, listAE[1]) - assertSame(CollectionUtils.findLast(listAE) { it == "E" }, listAE[4]) - assertNull(CollectionUtils.findLast(listAE) { it == "F" }) - - val listMulti = listOf("A", "B", "A", "C", "D", "E", "A", "E") - assertSame(CollectionUtils.findFirst(listMulti) { it == "A" }, listMulti[0]) - assertSame(CollectionUtils.findFirst(listMulti) { it == "B" }, listMulti[1]) - assertSame(CollectionUtils.findFirst(listMulti) { it == "E" }, listMulti[5]) - assertNull(CollectionUtils.findFirst(listMulti) { it == "F" }) - assertSame(CollectionUtils.findLast(listMulti) { it == "A" }, listMulti[6]) - assertSame(CollectionUtils.findLast(listMulti) { it == "B" }, listMulti[1]) - assertSame(CollectionUtils.findLast(listMulti) { it == "E" }, listMulti[7]) - assertNull(CollectionUtils.findLast(listMulti) { it == "F" }) - } - - @Test - fun testMap() { - val listAE = listOf("A", "B", "C", "D", "E", null) - assertEquals(listAE.map { "-$it-" }, CollectionUtils.map(listAE) { "-$it-" }) - } - - @Test - fun testZip() { - val listAE = listOf("A", "B", "C", "D", "E") - val list15 = listOf(1, 2, 3, 4, 5) - // Normal #zip returns kotlin.Pair, not android.util.Pair - assertEquals(list15.zip(listAE).map { android.util.Pair(it.first, it.second) }, - CollectionUtils.zip(list15, listAE)) - val listNull = listOf("A", null, "B", "C", "D") - assertEquals(list15.zip(listNull).map { android.util.Pair(it.first, it.second) }, - CollectionUtils.zip(list15, listNull)) - assertEquals(emptyList<android.util.Pair<Int, Int>>(), - CollectionUtils.zip(emptyList<Int>(), emptyList<Int>())) - assertFailsWith<IllegalArgumentException> { - // Different size - CollectionUtils.zip(listOf(1, 2), list15) - } - } - - @Test - fun testAssoc() { - val listADA = listOf("A", "B", "C", "D", "A") - val list15 = listOf(1, 2, 3, 4, 5) - assertEquals(list15.zip(listADA).toMap(), CollectionUtils.assoc(list15, listADA)) - - // Null key is fine - val assoc = CollectionUtils.assoc(listOf(1, 2, null), listOf("A", "B", "C")) - assertEquals("C", assoc[null]) - - assertFailsWith<IllegalArgumentException> { - // Same key multiple times - CollectionUtils.assoc(listOf("A", "B", "A"), listOf(1, 2, 3)) - } - assertFailsWith<IllegalArgumentException> { - // Same key multiple times, but it's null - CollectionUtils.assoc(listOf(null, "B", null), listOf(1, 2, 3)) - } - assertFailsWith<IllegalArgumentException> { - // Different size - CollectionUtils.assoc(listOf(1, 2), list15) - } - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/ConnectivityUtilsTest.java b/common/tests/unit/src/com/android/net/module/util/ConnectivityUtilsTest.java deleted file mode 100644 index 8af01965..00000000 --- a/common/tests/unit/src/com/android/net/module/util/ConnectivityUtilsTest.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2020 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.net.module.util; - -import static android.net.InetAddresses.parseNumericAddress; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import static com.android.net.module.util.ConnectivityUtils.isIPv6ULA; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import org.junit.Test; -import org.junit.runner.RunWith; - -/** Tests for ConnectivityUtils */ -@RunWith(AndroidJUnit4.class) -@SmallTest -public class ConnectivityUtilsTest { - @Test - public void testIsIPv6ULA() { - assertTrue(isIPv6ULA(parseNumericAddress("fc00::"))); - assertTrue(isIPv6ULA(parseNumericAddress("fc00::1"))); - assertTrue(isIPv6ULA(parseNumericAddress("fc00:1234::5678"))); - assertTrue(isIPv6ULA(parseNumericAddress("fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"))); - - assertFalse(isIPv6ULA(parseNumericAddress("fe00::"))); - assertFalse(isIPv6ULA(parseNumericAddress("2480:1248::123:456"))); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/DeviceConfigUtilsTest.java b/common/tests/unit/src/com/android/net/module/util/DeviceConfigUtilsTest.java deleted file mode 100644 index f259e687..00000000 --- a/common/tests/unit/src/com/android/net/module/util/DeviceConfigUtilsTest.java +++ /dev/null @@ -1,446 +0,0 @@ -/* - * Copyright (C) 2019 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.net.module.util; - -import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; -import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY; -import static android.provider.DeviceConfig.NAMESPACE_TETHERING; - -import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; -import static com.android.net.module.util.FeatureVersions.CONNECTIVITY_MODULE_ID; -import static com.android.net.module.util.FeatureVersions.NETWORK_STACK_MODULE_ID; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertThrows; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.anyString; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import android.content.Context; -import android.content.pm.ActivityInfo; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.pm.ResolveInfo; -import android.content.res.Resources; -import android.provider.DeviceConfig; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.mockito.MockitoSession; - -import java.util.Arrays; - - -/** - * Tests for DeviceConfigUtils. - * - */ -@RunWith(AndroidJUnit4.class) -@SmallTest -public class DeviceConfigUtilsTest { - private static final String TEST_NAME_SPACE = "connectivity"; - private static final String TEST_EXPERIMENT_FLAG = "experiment_flag"; - private static final int TEST_FLAG_VALUE = 28; - private static final String TEST_FLAG_VALUE_STRING = "28"; - private static final int TEST_DEFAULT_FLAG_VALUE = 0; - private static final int TEST_MAX_FLAG_VALUE = 1000; - private static final int TEST_MIN_FLAG_VALUE = 100; - private static final long TEST_PACKAGE_VERSION = 290000000; - private static final String TEST_PACKAGE_NAME = "test.package.name"; - // The APEX name is the name of the APEX module, as in android.content.pm.ModuleInfo, and is - // used for its mount point in /apex. APEX packages are actually APKs with a different - // file extension, so they have an AndroidManifest: the APEX package name is the package name in - // that manifest, and is reflected in android.content.pm.ApplicationInfo. Contrary to the APEX - // (module) name, different package names are typically used to identify the organization that - // built and signed the APEX modules. - private static final String TEST_APEX_NAME = "com.android.tethering"; - private static final String TEST_APEX_PACKAGE_NAME = "com.prefix.android.tethering"; - private static final String TEST_GO_APEX_PACKAGE_NAME = "com.prefix.android.go.tethering"; - private static final String TEST_CONNRES_PACKAGE_NAME = - "com.prefix.android.connectivity.resources"; - private static final String TEST_NETWORKSTACK_NAME = "com.prefix.android.networkstack"; - private static final String TEST_GO_NETWORKSTACK_NAME = "com.prefix.android.go.networkstack"; - private final PackageInfo mPackageInfo = new PackageInfo(); - private final PackageInfo mApexPackageInfo = new PackageInfo(); - private MockitoSession mSession; - - @Mock private Context mContext; - @Mock private PackageManager mPm; - @Mock private Resources mResources; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - mSession = mockitoSession().spyStatic(DeviceConfig.class).startMocking(); - - mPackageInfo.setLongVersionCode(TEST_PACKAGE_VERSION); - mApexPackageInfo.setLongVersionCode(TEST_PACKAGE_VERSION); - - doReturn(mPm).when(mContext).getPackageManager(); - doReturn(TEST_PACKAGE_NAME).when(mContext).getPackageName(); - doThrow(NameNotFoundException.class).when(mPm).getPackageInfo(anyString(), anyInt()); - doReturn(mPackageInfo).when(mPm).getPackageInfo(eq(TEST_PACKAGE_NAME), anyInt()); - doReturn(mApexPackageInfo).when(mPm).getPackageInfo(eq(TEST_APEX_PACKAGE_NAME), anyInt()); - - doReturn(mResources).when(mContext).getResources(); - - final ResolveInfo ri = new ResolveInfo(); - ri.activityInfo = new ActivityInfo(); - ri.activityInfo.applicationInfo = new ApplicationInfo(); - ri.activityInfo.applicationInfo.packageName = TEST_CONNRES_PACKAGE_NAME; - ri.activityInfo.applicationInfo.sourceDir = - "/apex/com.android.tethering/priv-app/ServiceConnectivityResources@version"; - doReturn(Arrays.asList(ri)).when(mPm).queryIntentActivities(argThat( - intent -> intent.getAction().equals(DeviceConfigUtils.RESOURCES_APK_INTENT)), - eq(MATCH_SYSTEM_ONLY)); - } - - @After - public void tearDown() { - mSession.finishMocking(); - DeviceConfigUtils.resetPackageVersionCacheForTest(); - } - - @Test - public void testGetDeviceConfigPropertyInt_Null() { - doReturn(null).when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE), - eq(TEST_EXPERIMENT_FLAG))); - assertEquals(TEST_DEFAULT_FLAG_VALUE, DeviceConfigUtils.getDeviceConfigPropertyInt( - TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG, - TEST_DEFAULT_FLAG_VALUE /* default value */)); - } - - @Test - public void testGetDeviceConfigPropertyInt_NotNull() { - doReturn(TEST_FLAG_VALUE_STRING).when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE), - eq(TEST_EXPERIMENT_FLAG))); - assertEquals(TEST_FLAG_VALUE, DeviceConfigUtils.getDeviceConfigPropertyInt( - TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG, - TEST_DEFAULT_FLAG_VALUE /* default value */)); - } - - @Test - public void testGetDeviceConfigPropertyInt_NormalValue() { - doReturn(TEST_FLAG_VALUE_STRING).when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE), - eq(TEST_EXPERIMENT_FLAG))); - assertEquals(TEST_FLAG_VALUE, DeviceConfigUtils.getDeviceConfigPropertyInt( - TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG, 0 /* minimum value */, - TEST_MAX_FLAG_VALUE /* maximum value */, - TEST_DEFAULT_FLAG_VALUE /* default value */)); - } - - @Test - public void testGetDeviceConfigPropertyInt_NullValue() { - doReturn(null).when(() -> DeviceConfig.getProperty( - eq(TEST_NAME_SPACE), eq(TEST_EXPERIMENT_FLAG))); - assertEquals(TEST_DEFAULT_FLAG_VALUE, DeviceConfigUtils.getDeviceConfigPropertyInt( - TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG, 0 /* minimum value */, - TEST_MAX_FLAG_VALUE /* maximum value */, - TEST_DEFAULT_FLAG_VALUE /* default value */)); - } - - @Test - public void testGetDeviceConfigPropertyInt_OverMaximumValue() { - doReturn(Integer.toString(TEST_MAX_FLAG_VALUE + 10)).when(() -> DeviceConfig.getProperty( - eq(TEST_NAME_SPACE), eq(TEST_EXPERIMENT_FLAG))); - assertEquals(TEST_DEFAULT_FLAG_VALUE, DeviceConfigUtils.getDeviceConfigPropertyInt( - TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG, TEST_MIN_FLAG_VALUE /* minimum value */, - TEST_MAX_FLAG_VALUE /* maximum value */, - TEST_DEFAULT_FLAG_VALUE /* default value */)); - } - - @Test - public void testGetDeviceConfigPropertyInt_EqualsMaximumValue() { - doReturn(Integer.toString(TEST_MAX_FLAG_VALUE)).when(() -> DeviceConfig.getProperty( - eq(TEST_NAME_SPACE), eq(TEST_EXPERIMENT_FLAG))); - assertEquals(TEST_MAX_FLAG_VALUE, DeviceConfigUtils.getDeviceConfigPropertyInt( - TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG, TEST_MIN_FLAG_VALUE /* minimum value */, - TEST_MAX_FLAG_VALUE /* maximum value */, - TEST_DEFAULT_FLAG_VALUE /* default value */)); - } - - @Test - public void testGetDeviceConfigPropertyInt_BelowMinimumValue() { - doReturn(Integer.toString(TEST_MIN_FLAG_VALUE - 10)).when(() -> DeviceConfig.getProperty( - eq(TEST_NAME_SPACE), eq(TEST_EXPERIMENT_FLAG))); - assertEquals(TEST_DEFAULT_FLAG_VALUE, DeviceConfigUtils.getDeviceConfigPropertyInt( - TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG, TEST_MIN_FLAG_VALUE /* minimum value */, - TEST_MAX_FLAG_VALUE /* maximum value */, - TEST_DEFAULT_FLAG_VALUE /* default value */)); - } - - @Test - public void testGetDeviceConfigPropertyInt_EqualsMinimumValue() { - doReturn(Integer.toString(TEST_MIN_FLAG_VALUE)).when(() -> DeviceConfig.getProperty( - eq(TEST_NAME_SPACE), eq(TEST_EXPERIMENT_FLAG))); - assertEquals(TEST_MIN_FLAG_VALUE, DeviceConfigUtils.getDeviceConfigPropertyInt( - TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG, TEST_MIN_FLAG_VALUE /* minimum value */, - TEST_MAX_FLAG_VALUE /* maximum value */, - TEST_DEFAULT_FLAG_VALUE /* default value */)); - } - - @Test - public void testGetDeviceConfigPropertyBoolean_Null() { - doReturn(null).when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE), - eq(TEST_EXPERIMENT_FLAG))); - assertFalse(DeviceConfigUtils.getDeviceConfigPropertyBoolean( - TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG, - false /* default value */)); - } - - @Test - public void testGetDeviceConfigPropertyBoolean_NotNull() { - doReturn("true").when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE), - eq(TEST_EXPERIMENT_FLAG))); - assertTrue(DeviceConfigUtils.getDeviceConfigPropertyBoolean( - TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG, - false /* default value */)); - } - - @Test - public void testFeatureIsEnabled() { - doReturn(TEST_FLAG_VALUE_STRING).when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE), - eq(TEST_EXPERIMENT_FLAG))); - assertTrue(DeviceConfigUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE, - TEST_EXPERIMENT_FLAG)); - assertTrue(DeviceConfigUtils.isTetheringFeatureEnabled(mContext, TEST_NAME_SPACE, - TEST_EXPERIMENT_FLAG, TEST_APEX_NAME, false /* defaultEnabled */)); - } - - @Test - public void testFeatureDefaultEnabled() { - doReturn(null).when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE), - eq(TEST_EXPERIMENT_FLAG))); - assertFalse(DeviceConfigUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE, - TEST_EXPERIMENT_FLAG)); - assertFalse(DeviceConfigUtils.isTetheringFeatureEnabled(mContext, TEST_NAME_SPACE, - TEST_EXPERIMENT_FLAG, TEST_APEX_NAME, false /* defaultEnabled */)); - assertTrue(DeviceConfigUtils.isTetheringFeatureEnabled(mContext, TEST_NAME_SPACE, - TEST_EXPERIMENT_FLAG, TEST_APEX_NAME, true /* defaultEnabled */)); - } - - @Test - public void testFeatureIsEnabledWithException() throws Exception { - doThrow(NameNotFoundException.class).when(mPm).getPackageInfo(anyString(), anyInt()); - - // Feature should be enabled by flag value "1". - doReturn("1").when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE), - eq(TEST_EXPERIMENT_FLAG))); - assertTrue(DeviceConfigUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE, - TEST_EXPERIMENT_FLAG)); - assertTrue(DeviceConfigUtils.isTetheringFeatureEnabled(mContext, TEST_NAME_SPACE, - TEST_EXPERIMENT_FLAG, TEST_APEX_NAME, false /* defaultEnabled */)); - - // Feature should be disabled by flag value "999999999". - doReturn("999999999").when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE), - eq(TEST_EXPERIMENT_FLAG))); - assertFalse(DeviceConfigUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE, - TEST_EXPERIMENT_FLAG)); - assertFalse(DeviceConfigUtils.isTetheringFeatureEnabled(mContext, TEST_NAME_SPACE, - TEST_EXPERIMENT_FLAG, TEST_APEX_NAME, false /* defaultEnabled */)); - - // Follow defaultEnabled if the flag is not set - doReturn(null).when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE), - eq(TEST_EXPERIMENT_FLAG))); - assertFalse(DeviceConfigUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE, - TEST_EXPERIMENT_FLAG, false /* defaultEnabled */)); - assertTrue(DeviceConfigUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE, - TEST_EXPERIMENT_FLAG, true /* defaultEnabled */)); - assertFalse(DeviceConfigUtils.isTetheringFeatureEnabled(mContext, TEST_NAME_SPACE, - TEST_EXPERIMENT_FLAG, TEST_APEX_NAME, false /* defaultEnabled */)); - assertTrue(DeviceConfigUtils.isTetheringFeatureEnabled(mContext, TEST_NAME_SPACE, - TEST_EXPERIMENT_FLAG, TEST_APEX_NAME, true /* defaultEnabled */)); - } - - @Test - public void testFeatureIsEnabledOnGo() throws Exception { - doThrow(NameNotFoundException.class).when(mPm).getPackageInfo( - eq(TEST_APEX_PACKAGE_NAME), anyInt()); - doReturn(mApexPackageInfo).when(mPm).getPackageInfo( - eq(TEST_GO_APEX_PACKAGE_NAME), anyInt()); - doReturn("0").when(() -> DeviceConfig.getProperty( - eq(TEST_NAME_SPACE), eq(TEST_EXPERIMENT_FLAG))); - - assertFalse(DeviceConfigUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE, - TEST_EXPERIMENT_FLAG)); - assertFalse(DeviceConfigUtils.isTetheringFeatureEnabled(mContext, TEST_NAME_SPACE, - TEST_EXPERIMENT_FLAG, TEST_APEX_NAME, false /* defaultEnabled */)); - assertTrue(DeviceConfigUtils.isTetheringFeatureEnabled(mContext, TEST_NAME_SPACE, - TEST_EXPERIMENT_FLAG, TEST_APEX_NAME, true /* defaultEnabled */)); - - doReturn(TEST_FLAG_VALUE_STRING).when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE), - eq(TEST_EXPERIMENT_FLAG))); - assertTrue(DeviceConfigUtils.isTetheringFeatureEnabled(mContext, TEST_NAME_SPACE, - TEST_EXPERIMENT_FLAG, TEST_APEX_NAME, false /* defaultEnabled */)); - } - - @Test - public void testFeatureIsEnabledCaching_APK() throws Exception { - doReturn(TEST_FLAG_VALUE_STRING).when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE), - eq(TEST_EXPERIMENT_FLAG))); - assertTrue(DeviceConfigUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE, - TEST_EXPERIMENT_FLAG)); - assertTrue(DeviceConfigUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE, - TEST_EXPERIMENT_FLAG)); - - // Package info is only queried once - verify(mContext, times(1)).getPackageManager(); - verify(mContext, times(1)).getPackageName(); - verify(mPm, times(1)).getPackageInfo(anyString(), anyInt()); - } - - @Test - public void testFeatureIsEnabledCaching_APEX() throws Exception { - doReturn(TEST_FLAG_VALUE_STRING).when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE), - eq(TEST_EXPERIMENT_FLAG))); - assertTrue(DeviceConfigUtils.isTetheringFeatureEnabled(mContext, TEST_NAME_SPACE, - TEST_EXPERIMENT_FLAG, TEST_APEX_NAME, false /* defaultEnabled */)); - assertTrue(DeviceConfigUtils.isTetheringFeatureEnabled(mContext, TEST_NAME_SPACE, - TEST_EXPERIMENT_FLAG, TEST_APEX_NAME, false /* defaultEnabled */)); - - // Package info is only queried once - verify(mPm, times(1)).getPackageInfo(anyString(), anyInt()); - verify(mContext, never()).getPackageName(); - } - - @Test - public void testGetResBooleanConfig() { - final int someResId = 1234; - doReturn(true).when(mResources).getBoolean(someResId); - assertTrue(DeviceConfigUtils.getResBooleanConfig(mContext, someResId, false)); - doReturn(false).when(mResources).getBoolean(someResId); - assertFalse(DeviceConfigUtils.getResBooleanConfig(mContext, someResId, false)); - doThrow(new Resources.NotFoundException()).when(mResources).getBoolean(someResId); - assertFalse(DeviceConfigUtils.getResBooleanConfig(mContext, someResId, false)); - } - - @Test - public void testGetResIntegerConfig() { - final int someResId = 1234; - doReturn(2097).when(mResources).getInteger(someResId); - assertEquals(2097, DeviceConfigUtils.getResIntegerConfig(mContext, someResId, 2098)); - doThrow(new Resources.NotFoundException()).when(mResources).getInteger(someResId); - assertEquals(2098, DeviceConfigUtils.getResIntegerConfig(mContext, someResId, 2098)); - } - - @Test - public void testGetNetworkStackModuleVersionCaching() throws Exception { - final PackageInfo networkStackPackageInfo = new PackageInfo(); - networkStackPackageInfo.setLongVersionCode(TEST_PACKAGE_VERSION); - doReturn(networkStackPackageInfo).when(mPm).getPackageInfo( - eq(TEST_NETWORKSTACK_NAME), anyInt()); - assertEquals(TEST_PACKAGE_VERSION, - DeviceConfigUtils.getNetworkStackModuleVersion(mContext)); - - assertEquals(TEST_PACKAGE_VERSION, - DeviceConfigUtils.getNetworkStackModuleVersion(mContext)); - // Package info is only queried once - verify(mPm, times(1)).getPackageInfo(anyString(), anyInt()); - verify(mContext, never()).getPackageName(); - } - - @Test - public void testGetNetworkStackModuleVersionOnNonMainline() { - assertEquals(DeviceConfigUtils.DEFAULT_PACKAGE_VERSION, - DeviceConfigUtils.getNetworkStackModuleVersion(mContext)); - } - - @Test - public void testGetNetworkStackModuleVersion() throws Exception { - final PackageInfo networkStackPackageInfo = new PackageInfo(); - final PackageInfo goNetworkStackPackageInfo = new PackageInfo(); - networkStackPackageInfo.setLongVersionCode(TEST_PACKAGE_VERSION); - goNetworkStackPackageInfo.setLongVersionCode(TEST_PACKAGE_VERSION + 1); - doReturn(goNetworkStackPackageInfo).when(mPm).getPackageInfo( - eq(TEST_NETWORKSTACK_NAME), anyInt()); - // Verify the returned value is go module version. - assertEquals(TEST_PACKAGE_VERSION + 1, - DeviceConfigUtils.getNetworkStackModuleVersion(mContext)); - } - - @Test - public void testIsFeatureSupported_networkStackFeature() throws Exception { - // Supported for DEFAULT_PACKAGE_VERSION - assertTrue(DeviceConfigUtils.isFeatureSupported( - mContext, TEST_PACKAGE_VERSION + NETWORK_STACK_MODULE_ID)); - - final PackageInfo networkStackPackageInfo = new PackageInfo(); - networkStackPackageInfo.setLongVersionCode(TEST_PACKAGE_VERSION); - doReturn(networkStackPackageInfo).when(mPm).getPackageInfo( - eq(TEST_NETWORKSTACK_NAME), anyInt()); - - assertTrue(DeviceConfigUtils.isFeatureSupported( - mContext, TEST_PACKAGE_VERSION + NETWORK_STACK_MODULE_ID)); - assertFalse(DeviceConfigUtils.isFeatureSupported( - mContext, TEST_PACKAGE_VERSION + NETWORK_STACK_MODULE_ID + 1)); - } - - @Test - public void testIsFeatureSupported_tetheringFeature() throws Exception { - assertTrue(DeviceConfigUtils.isFeatureSupported( - mContext, TEST_PACKAGE_VERSION + CONNECTIVITY_MODULE_ID)); - // Return false because feature requires a future version. - assertFalse(DeviceConfigUtils.isFeatureSupported( - mContext, 889900000L + CONNECTIVITY_MODULE_ID)); - } - - @Test - public void testIsFeatureSupported_illegalModule() throws Exception { - assertThrows(IllegalArgumentException.class, - () -> DeviceConfigUtils.isFeatureSupported(mContext, TEST_PACKAGE_VERSION)); - } - - @Test - public void testIsTetheringFeatureNotChickenedOut() throws Exception { - doReturn("0").when(() -> DeviceConfig.getProperty( - eq(NAMESPACE_TETHERING), eq(TEST_EXPERIMENT_FLAG))); - assertTrue(DeviceConfigUtils.isTetheringFeatureNotChickenedOut(TEST_EXPERIMENT_FLAG)); - - doReturn(TEST_FLAG_VALUE_STRING).when( - () -> DeviceConfig.getProperty(eq(NAMESPACE_TETHERING), eq(TEST_EXPERIMENT_FLAG))); - assertFalse(DeviceConfigUtils.isTetheringFeatureNotChickenedOut(TEST_EXPERIMENT_FLAG)); - } - - @Test - public void testIsNetworkStackFeatureNotChickenedOut() throws Exception { - doReturn("0").when(() -> DeviceConfig.getProperty( - eq(NAMESPACE_CONNECTIVITY), eq(TEST_EXPERIMENT_FLAG))); - assertTrue(DeviceConfigUtils.isNetworkStackFeatureNotChickenedOut(TEST_EXPERIMENT_FLAG)); - - doReturn(TEST_FLAG_VALUE_STRING).when( - () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY), - eq(TEST_EXPERIMENT_FLAG))); - assertFalse(DeviceConfigUtils.isNetworkStackFeatureNotChickenedOut(TEST_EXPERIMENT_FLAG)); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/DnsPacketTest.java b/common/tests/unit/src/com/android/net/module/util/DnsPacketTest.java deleted file mode 100644 index 28e183a9..00000000 --- a/common/tests/unit/src/com/android/net/module/util/DnsPacketTest.java +++ /dev/null @@ -1,426 +0,0 @@ -/* - * Copyright (C) 2019 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.net.module.util; - -import static android.net.DnsResolver.CLASS_IN; -import static android.net.DnsResolver.TYPE_A; -import static android.net.DnsResolver.TYPE_AAAA; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThrows; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import android.annotation.NonNull; -import android.annotation.Nullable; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import libcore.net.InetAddressUtils; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.io.IOException; -import java.nio.BufferUnderflowException; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class DnsPacketTest { - private static final int TEST_DNS_PACKET_ID = 0x7722; - private static final int TEST_DNS_PACKET_FLAGS = 0x8180; - - private void assertHeaderParses(DnsPacket.DnsHeader header, int id, int flag, - int qCount, int aCount, int nsCount, int arCount) { - assertEquals(header.getId(), id); - assertEquals(header.getFlags(), flag); - assertEquals(header.getRecordCount(DnsPacket.QDSECTION), qCount); - assertEquals(header.getRecordCount(DnsPacket.ANSECTION), aCount); - assertEquals(header.getRecordCount(DnsPacket.NSSECTION), nsCount); - assertEquals(header.getRecordCount(DnsPacket.ARSECTION), arCount); - } - - private void assertRecordParses(DnsPacket.DnsRecord record, String dname, - int dtype, int dclass, int ttl, byte[] rr) { - assertEquals(record.dName, dname); - assertEquals(record.nsType, dtype); - assertEquals(record.nsClass, dclass); - assertEquals(record.ttl, ttl); - assertTrue(Arrays.equals(record.getRR(), rr)); - } - - static class TestDnsPacket extends DnsPacket { - TestDnsPacket(byte[] data) throws DnsPacket.ParseException { - super(data); - } - - TestDnsPacket(@NonNull DnsHeader header, @Nullable ArrayList<DnsRecord> qd, - @Nullable ArrayList<DnsRecord> an) { - super(header, qd, an); - } - - public DnsHeader getHeader() { - return mHeader; - } - public List<DnsRecord> getRecordList(int secType) { - return mRecords[secType]; - } - } - - @Test - public void testNullDisallowed() { - try { - new TestDnsPacket(null); - fail("Exception not thrown for null byte array"); - } catch (DnsPacket.ParseException e) { - } - } - - @Test - public void testV4Answer() throws Exception { - final byte[] v4blob = new byte[] { - /* Header */ - 0x55, 0x66, /* Transaction ID */ - (byte) 0x81, (byte) 0x80, /* Flags */ - 0x00, 0x01, /* Questions */ - 0x00, 0x01, /* Answer RRs */ - 0x00, 0x00, /* Authority RRs */ - 0x00, 0x00, /* Additional RRs */ - /* Queries */ - 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6c, 0x65, - 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */ - 0x00, 0x01, /* Type */ - 0x00, 0x01, /* Class */ - /* Answers */ - (byte) 0xc0, 0x0c, /* Name */ - 0x00, 0x01, /* Type */ - 0x00, 0x01, /* Class */ - 0x00, 0x00, 0x01, 0x2b, /* TTL */ - 0x00, 0x04, /* Data length */ - (byte) 0xac, (byte) 0xd9, (byte) 0xa1, (byte) 0x84 /* Address */ - }; - TestDnsPacket packet = new TestDnsPacket(v4blob); - - // Header part - assertHeaderParses(packet.getHeader(), 0x5566, 0x8180, 1, 1, 0, 0); - - // Record part - List<DnsPacket.DnsRecord> qdRecordList = - packet.getRecordList(DnsPacket.QDSECTION); - assertEquals(qdRecordList.size(), 1); - assertRecordParses(qdRecordList.get(0), "www.google.com", 1, 1, 0, null); - - List<DnsPacket.DnsRecord> anRecordList = - packet.getRecordList(DnsPacket.ANSECTION); - assertEquals(anRecordList.size(), 1); - assertRecordParses(anRecordList.get(0), "www.google.com", 1, 1, 0x12b, - new byte[]{ (byte) 0xac, (byte) 0xd9, (byte) 0xa1, (byte) 0x84 }); - } - - @Test - public void testV6Answer() throws Exception { - final byte[] v6blob = new byte[] { - /* Header */ - 0x77, 0x22, /* Transaction ID */ - (byte) 0x81, (byte) 0x80, /* Flags */ - 0x00, 0x01, /* Questions */ - 0x00, 0x01, /* Answer RRs */ - 0x00, 0x00, /* Authority RRs */ - 0x00, 0x00, /* Additional RRs */ - /* Queries */ - 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6c, 0x65, - 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */ - 0x00, 0x1c, /* Type */ - 0x00, 0x01, /* Class */ - /* Answers */ - (byte) 0xc0, 0x0c, /* Name */ - 0x00, 0x1c, /* Type */ - 0x00, 0x01, /* Class */ - 0x00, 0x00, 0x00, 0x37, /* TTL */ - 0x00, 0x10, /* Data length */ - 0x24, 0x04, 0x68, 0x00, 0x40, 0x05, 0x08, 0x0d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x04 /* Address */ - }; - TestDnsPacket packet = new TestDnsPacket(v6blob); - - // Header part - assertHeaderParses(packet.getHeader(), 0x7722, 0x8180, 1, 1, 0, 0); - - // Record part - List<DnsPacket.DnsRecord> qdRecordList = - packet.getRecordList(DnsPacket.QDSECTION); - assertEquals(qdRecordList.size(), 1); - assertRecordParses(qdRecordList.get(0), "www.google.com", 28, 1, 0, null); - - List<DnsPacket.DnsRecord> anRecordList = - packet.getRecordList(DnsPacket.ANSECTION); - assertEquals(anRecordList.size(), 1); - assertRecordParses(anRecordList.get(0), "www.google.com", 28, 1, 0x37, - new byte[]{ 0x24, 0x04, 0x68, 0x00, 0x40, 0x05, 0x08, 0x0d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x04 }); - } - - /** Verifies that the synthesized {@link DnsPacket.DnsHeader} can be parsed correctly. */ - @Test - public void testDnsHeaderSynthesize() { - final DnsPacket.DnsHeader testHeader = new DnsPacket.DnsHeader(TEST_DNS_PACKET_ID, - TEST_DNS_PACKET_FLAGS, 3 /* qcount */, 5 /* ancount */); - final DnsPacket.DnsHeader actualHeader = new DnsPacket.DnsHeader( - ByteBuffer.wrap(testHeader.getBytes())); - assertEquals(testHeader, actualHeader); - } - - /** Verifies that the synthesized {@link DnsPacket.DnsRecord} can be parsed correctly. */ - @Test - public void testDnsRecordSynthesize() throws IOException { - assertDnsRecordRoundTrip( - DnsPacket.DnsRecord.makeAOrAAAARecord(DnsPacket.ANSECTION, - "test.com", CLASS_IN, 5 /* ttl */, - InetAddressUtils.parseNumericAddress("abcd::fedc"))); - assertDnsRecordRoundTrip(DnsPacket.DnsRecord.makeQuestion("test.com", TYPE_AAAA, CLASS_IN)); - assertDnsRecordRoundTrip(DnsPacket.DnsRecord.makeCNameRecord(DnsPacket.ANSECTION, - "test.com", CLASS_IN, 0 /* ttl */, "example.com")); - } - - /** - * Verifies ttl/rData error handling when parsing - * {@link DnsPacket.DnsRecord} from bytes. - */ - @Test - public void testDnsRecordTTLRDataErrorHandling() throws IOException { - // Verify the constructor ignore ttl/rData of questions even if they are supplied. - final byte[] qdWithTTLRData = new byte[]{ - 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6c, 0x65, - 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */ - 0x00, 0x00, /* Type */ - 0x00, 0x01, /* Class */ - 0x00, 0x00, 0x01, 0x2b, /* TTL */ - 0x00, 0x04, /* Data length */ - (byte) 0xac, (byte) 0xd9, (byte) 0xa1, (byte) 0x84 /* Address */}; - final DnsPacket.DnsRecord questionsFromBytes = - DnsPacket.DnsRecord.parse(DnsPacket.QDSECTION, ByteBuffer.wrap(qdWithTTLRData)); - assertEquals(0, questionsFromBytes.ttl); - assertNull(questionsFromBytes.getRR()); - - // Verify ANSECTION must have rData when constructing. - final byte[] anWithoutTTLRData = new byte[]{ - 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6c, 0x65, - 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */ - 0x00, 0x01, /* Type */ - 0x00, 0x01, /* Class */}; - assertThrows(BufferUnderflowException.class, () -> - DnsPacket.DnsRecord.parse(DnsPacket.ANSECTION, ByteBuffer.wrap(anWithoutTTLRData))); - } - - private void assertDnsRecordRoundTrip(DnsPacket.DnsRecord before) - throws IOException { - final DnsPacket.DnsRecord after = DnsPacket.DnsRecord.parse(before.rType, - ByteBuffer.wrap(before.getBytes())); - assertEquals(after, before); - } - - /** Verifies that the synthesized {@link DnsPacket} can be parsed correctly. */ - @Test - public void testDnsPacketSynthesize() throws IOException { - // Ipv4 dns response packet generated by scapy: - // dns_r = scapy.DNS( - // id=0xbeef, - // qr=1, - // qd=scapy.DNSQR(qname="hello.example.com"), - // an=scapy.DNSRR(rrname="hello.example.com", type="CNAME", rdata='test.com') / - // scapy.DNSRR(rrname="hello.example.com", rdata='1.2.3.4')) - // scapy.hexdump(dns_r) - // dns_r.show2() - // Note that since the synthesizing does not support name compression yet, the domain - // name of the sample need to be uncompressed when generating. - final byte[] v4BlobUncompressed = new byte[]{ - /* Header */ - (byte) 0xbe, (byte) 0xef, /* Transaction ID */ - (byte) 0x81, 0x00, /* Flags */ - 0x00, 0x01, /* Questions */ - 0x00, 0x02, /* Answer RRs */ - 0x00, 0x00, /* Authority RRs */ - 0x00, 0x00, /* Additional RRs */ - /* Queries */ - 0x05, 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x07, 0x65, 0x78, 0x61, - 0x6D, 0x70, 0x6C, 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, /* Name: hello.example.com */ - 0x00, 0x01, /* Type */ - 0x00, 0x01, /* Class */ - /* Answers */ - 0x05, 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x07, 0x65, 0x78, 0x61, - 0x6D, 0x70, 0x6C, 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, /* Name: hello.example.com */ - 0x00, 0x05, /* Type */ - 0x00, 0x01, /* Class */ - 0x00, 0x00, 0x00, 0x00, /* TTL */ - 0x00, 0x0A, /* Data length */ - 0x04, 0x74, 0x65, 0x73, 0x74, 0x03, 0x63, 0x6F, 0x6D, 0x00, /* Alias: test.com */ - 0x05, 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x07, 0x65, 0x78, 0x61, - 0x6D, 0x70, 0x6C, 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, /* Name: hello.example.com */ - 0x00, 0x01, /* Type */ - 0x00, 0x01, /* Class */ - 0x00, 0x00, 0x00, 0x00, /* TTL */ - 0x00, 0x04, /* Data length */ - 0x01, 0x02, 0x03, 0x04, /* Address: 1.2.3.4 */ - }; - - // Forge one via constructors. - final DnsPacket.DnsHeader testHeader = new DnsPacket.DnsHeader(0xbeef, - 0x8100, 1 /* qcount */, 2 /* ancount */); - final ArrayList<DnsPacket.DnsRecord> qlist = new ArrayList<>(); - final ArrayList<DnsPacket.DnsRecord> alist = new ArrayList<>(); - qlist.add(DnsPacket.DnsRecord.makeQuestion( - "hello.example.com", TYPE_A, CLASS_IN)); - alist.add(DnsPacket.DnsRecord.makeCNameRecord( - DnsPacket.ANSECTION, "hello.example.com", CLASS_IN, 0 /* ttl */, "test.com")); - alist.add(DnsPacket.DnsRecord.makeAOrAAAARecord( - DnsPacket.ANSECTION, "hello.example.com", CLASS_IN, 0 /* ttl */, - InetAddressUtils.parseNumericAddress("1.2.3.4"))); - final TestDnsPacket testPacket = new TestDnsPacket(testHeader, qlist, alist); - - // Assert content equals in both ways. - assertTrue(Arrays.equals(v4BlobUncompressed, testPacket.getBytes())); - assertEquals(new TestDnsPacket(v4BlobUncompressed), testPacket); - } - - @Test - public void testDnsPacketSynthesize_recordCountMismatch() throws IOException { - final DnsPacket.DnsHeader testHeader = new DnsPacket.DnsHeader(0xbeef, - 0x8100, 1 /* qcount */, 1 /* ancount */); - final ArrayList<DnsPacket.DnsRecord> qlist = new ArrayList<>(); - final ArrayList<DnsPacket.DnsRecord> alist = new ArrayList<>(); - qlist.add(DnsPacket.DnsRecord.makeQuestion( - "hello.example.com", TYPE_A, CLASS_IN)); - - // Assert throws if the supplied answer records fewer than the declared count. - assertThrows(IllegalArgumentException.class, () -> - new TestDnsPacket(testHeader, qlist, alist)); - - // Assert throws if the supplied answer records more than the declared count. - alist.add(DnsPacket.DnsRecord.makeCNameRecord( - DnsPacket.ANSECTION, "hello.example.com", CLASS_IN, 0 /* ttl */, "test.com")); - alist.add(DnsPacket.DnsRecord.makeAOrAAAARecord( - DnsPacket.ANSECTION, "hello.example.com", CLASS_IN, 0 /* ttl */, - InetAddressUtils.parseNumericAddress("1.2.3.4"))); - assertThrows(IllegalArgumentException.class, () -> - new TestDnsPacket(testHeader, qlist, alist)); - - // Assert counts matched if the byte buffer still has data when parsing ended. - final byte[] blobTooMuchData = new byte[]{ - /* Header */ - (byte) 0xbe, (byte) 0xef, /* Transaction ID */ - (byte) 0x81, 0x00, /* Flags */ - 0x00, 0x00, /* Questions */ - 0x00, 0x00, /* Answer RRs */ - 0x00, 0x00, /* Authority RRs */ - 0x00, 0x00, /* Additional RRs */ - /* Queries */ - 0x05, 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x07, 0x65, 0x78, 0x61, - 0x6D, 0x70, 0x6C, 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, /* Name */ - 0x00, 0x01, /* Type */ - 0x00, 0x01, /* Class */ - }; - final TestDnsPacket packetFromTooMuchData = new TestDnsPacket(blobTooMuchData); - for (int i = 0; i < DnsPacket.NUM_SECTIONS; i++) { - assertEquals(0, packetFromTooMuchData.getRecordList(i).size()); - assertEquals(0, packetFromTooMuchData.getHeader().getRecordCount(i)); - } - - // Assert throws if the byte buffer ended when expecting more records. - final byte[] blobNotEnoughData = new byte[]{ - /* Header */ - (byte) 0xbe, (byte) 0xef, /* Transaction ID */ - (byte) 0x81, 0x00, /* Flags */ - 0x00, 0x01, /* Questions */ - 0x00, 0x02, /* Answer RRs */ - 0x00, 0x00, /* Authority RRs */ - 0x00, 0x00, /* Additional RRs */ - /* Queries */ - 0x05, 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x07, 0x65, 0x78, 0x61, - 0x6D, 0x70, 0x6C, 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, /* Name */ - 0x00, 0x01, /* Type */ - 0x00, 0x01, /* Class */ - /* Answers */ - 0x05, 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x07, 0x65, 0x78, 0x61, - 0x6D, 0x70, 0x6C, 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, /* Name */ - 0x00, 0x01, /* Type */ - 0x00, 0x01, /* Class */ - 0x00, 0x00, 0x00, 0x00, /* TTL */ - 0x00, 0x04, /* Data length */ - 0x01, 0x02, 0x03, 0x04, /* Address */ - }; - assertThrows(DnsPacket.ParseException.class, () -> new TestDnsPacket(blobNotEnoughData)); - } - - @Test - public void testEqualsAndHashCode() throws IOException { - // Verify DnsHeader equals and hashCode. - final DnsPacket.DnsHeader testHeader = new DnsPacket.DnsHeader(TEST_DNS_PACKET_ID, - TEST_DNS_PACKET_FLAGS, 1 /* qcount */, 1 /* ancount */); - final DnsPacket.DnsHeader emptyHeader = new DnsPacket.DnsHeader(TEST_DNS_PACKET_ID + 1, - TEST_DNS_PACKET_FLAGS + 0x08, 0 /* qcount */, 0 /* ancount */); - final DnsPacket.DnsHeader headerFromBytes = - new DnsPacket.DnsHeader(ByteBuffer.wrap(testHeader.getBytes())); - assertEquals(testHeader, headerFromBytes); - assertEquals(testHeader.hashCode(), headerFromBytes.hashCode()); - assertNotEquals(testHeader, emptyHeader); - assertNotEquals(testHeader.hashCode(), emptyHeader.hashCode()); - assertNotEquals(headerFromBytes, emptyHeader); - assertNotEquals(headerFromBytes.hashCode(), emptyHeader.hashCode()); - - // Verify DnsRecord equals and hashCode. - final DnsPacket.DnsRecord testQuestion = DnsPacket.DnsRecord.makeQuestion( - "test.com", TYPE_AAAA, CLASS_IN); - final DnsPacket.DnsRecord testAnswer = DnsPacket.DnsRecord.makeCNameRecord( - DnsPacket.ANSECTION, "test.com", CLASS_IN, 9, "www.test.com"); - final DnsPacket.DnsRecord questionFromBytes = DnsPacket.DnsRecord.parse(DnsPacket.QDSECTION, - ByteBuffer.wrap(testQuestion.getBytes())); - assertEquals(testQuestion, questionFromBytes); - assertEquals(testQuestion.hashCode(), questionFromBytes.hashCode()); - assertNotEquals(testQuestion, testAnswer); - assertNotEquals(testQuestion.hashCode(), testAnswer.hashCode()); - assertNotEquals(questionFromBytes, testAnswer); - assertNotEquals(questionFromBytes.hashCode(), testAnswer.hashCode()); - - // Verify DnsPacket equals and hashCode. - final ArrayList<DnsPacket.DnsRecord> qlist = new ArrayList<>(); - final ArrayList<DnsPacket.DnsRecord> alist = new ArrayList<>(); - qlist.add(testQuestion); - alist.add(testAnswer); - final TestDnsPacket testPacket = new TestDnsPacket(testHeader, qlist, alist); - final TestDnsPacket emptyPacket = new TestDnsPacket( - emptyHeader, new ArrayList<>(), new ArrayList<>()); - final TestDnsPacket packetFromBytes = new TestDnsPacket(testPacket.getBytes()); - assertEquals(testPacket, packetFromBytes); - assertEquals(testPacket.hashCode(), packetFromBytes.hashCode()); - assertNotEquals(testPacket, emptyPacket); - assertNotEquals(testPacket.hashCode(), emptyPacket.hashCode()); - assertNotEquals(packetFromBytes, emptyPacket); - assertNotEquals(packetFromBytes.hashCode(), emptyPacket.hashCode()); - - // Verify DnsPacket with empty list. - final TestDnsPacket emptyPacketFromBytes = new TestDnsPacket(emptyPacket.getBytes()); - assertEquals(emptyPacket, emptyPacketFromBytes); - assertEquals(emptyPacket.hashCode(), emptyPacketFromBytes.hashCode()); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/DnsPacketUtilsTest.java b/common/tests/unit/src/com/android/net/module/util/DnsPacketUtilsTest.java deleted file mode 100644 index 9e1ab824..00000000 --- a/common/tests/unit/src/com/android/net/module/util/DnsPacketUtilsTest.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (C) 2019 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.net.module.util; - -import static com.android.net.module.util.DnsPacketUtils.DnsRecordParser; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThrows; - -import android.net.ParseException; -import android.os.Build; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.testutils.DevSdkIgnoreRule; - -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.nio.ByteBuffer; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class DnsPacketUtilsTest { - @Rule - public final DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule(); - - /** - * Verifies that the compressed NAME field in the answer section of the DNS message is parsed - * successfully when name compression is permitted. Additionally, verifies that a - * {@link DnsPacket.ParseException} is thrown in a hypothetical scenario where name compression - * is not expected. - */ - @Test - public void testParsingAnswerSectionNameCompressed() throws Exception { - final byte[] v4blobNameCompressedAnswer = new byte[] { - /* Header */ - 0x55, 0x66, /* Transaction ID */ - (byte) 0x81, (byte) 0x80, /* Flags */ - 0x00, 0x01, /* Questions */ - 0x00, 0x01, /* Answer RRs */ - 0x00, 0x00, /* Authority RRs */ - 0x00, 0x00, /* Additional RRs */ - /* Queries */ - 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6c, 0x65, - 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */ - 0x00, 0x01, /* Type */ - 0x00, 0x01, /* Class */ - /* Answers */ - (byte) 0xc0, 0x0c, /* Name */ - 0x00, 0x01, /* Type */ - 0x00, 0x01, /* Class */ - 0x00, 0x00, 0x01, 0x2b, /* TTL */ - 0x00, 0x04, /* Data length */ - (byte) 0xac, (byte) 0xd9, (byte) 0xa1, (byte) 0x84 /* Address */ - }; - final int answerOffsetBytePosition = 32; - final ByteBuffer nameCompressedBuf = ByteBuffer.wrap(v4blobNameCompressedAnswer); - - nameCompressedBuf.position(answerOffsetBytePosition); - assertThrows(DnsPacket.ParseException.class, () -> DnsRecordParser.parseName( - nameCompressedBuf, /* depth= */ 0, /* isNameCompressionSupported= */false)); - - nameCompressedBuf.position(answerOffsetBytePosition); - String domainName = DnsRecordParser.parseName( - nameCompressedBuf, /* depth= */ 0, /* isNameCompressionSupported= */true); - assertEquals(domainName, "www.google.com"); - } - - /** - * Verifies that an uncompressed NAME field in the answer section of the DNS message is parsed - * successfully irrespective of whether name compression is permitted. - */ - @Test - public void testParsingAnswerSectionNoNameCompression() throws Exception { - final byte[] v4blobNoNameCompression = new byte[] { - /* Header */ - 0x55, 0x66, /* Transaction ID */ - (byte) 0x81, (byte) 0x80, /* Flags */ - 0x00, 0x01, /* Questions */ - 0x00, 0x01, /* Answer RRs */ - 0x00, 0x00, /* Authority RRs */ - 0x00, 0x00, /* Additional RRs */ - /* Queries */ - 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6c, 0x65, - 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */ - 0x00, 0x01, /* Type */ - 0x00, 0x01, /* Class */ - /* Answers */ - 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6c, 0x65, - 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */ - 0x00, 0x01, /* Type */ - 0x00, 0x01, /* Class */ - 0x00, 0x00, 0x01, 0x2b, /* TTL */ - 0x00, 0x04, /* Data length */ - (byte) 0xac, (byte) 0xd9, (byte) 0xa1, (byte) 0x84 /* Address */ - }; - final int answerOffsetBytePosition = 32; - final ByteBuffer notNameCompressedBuf = ByteBuffer.wrap(v4blobNoNameCompression); - - notNameCompressedBuf.position(answerOffsetBytePosition); - String domainName = DnsRecordParser.parseName( - notNameCompressedBuf, /* depth= */ 0, /* isNameCompressionSupported= */ true); - assertEquals(domainName, "www.google.com"); - - notNameCompressedBuf.position(answerOffsetBytePosition); - domainName = DnsRecordParser.parseName( - notNameCompressedBuf, /* depth= */ 0, /* isNameCompressionSupported= */ false); - assertEquals(domainName, "www.google.com"); - } - - // Skip test on R- devices since ParseException only available on S+ devices. - @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R) - @Test - public void testDomainNameToLabels() throws Exception { - assertArrayEquals( - new byte[]{3, 'w', 'w', 'w', 6, 'g', 'o', 'o', 'g', 'l', 'e', 3, 'c', 'o', 'm', 0}, - DnsRecordParser.domainNameToLabels("www.google.com")); - assertThrows(ParseException.class, () -> - DnsRecordParser.domainNameToLabels("aaa.")); - assertThrows(ParseException.class, () -> - DnsRecordParser.domainNameToLabels("aaa")); - assertThrows(ParseException.class, () -> - DnsRecordParser.domainNameToLabels(".")); - assertThrows(ParseException.class, () -> - DnsRecordParser.domainNameToLabels("")); - } - - @Test - public void testIsHostName() { - Assert.assertTrue(DnsRecordParser.isHostName("www.google.com")); - Assert.assertFalse(DnsRecordParser.isHostName("com")); - Assert.assertFalse(DnsRecordParser.isHostName("1.2.3.4")); - Assert.assertFalse(DnsRecordParser.isHostName("1234::5678")); - Assert.assertFalse(DnsRecordParser.isHostName(null)); - Assert.assertFalse(DnsRecordParser.isHostName("")); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/DomainUtilsTest.java b/common/tests/unit/src/com/android/net/module/util/DomainUtilsTest.java deleted file mode 100644 index 5eaf2add..00000000 --- a/common/tests/unit/src/com/android/net/module/util/DomainUtilsTest.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (C) 2023 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.net.module.util; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import libcore.util.HexEncoding; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.ArrayList; -import java.util.List; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class DomainUtilsTest { - @Test - public void testEncodeInvalidDomain() { - byte[] buffer = DomainUtils.encode(".google.com"); - assertNull(buffer); - - buffer = DomainUtils.encode("google.com."); - assertNull(buffer); - - buffer = DomainUtils.encode("-google.com"); - assertNull(buffer); - - buffer = DomainUtils.encode("google.com-"); - assertNull(buffer); - - buffer = DomainUtils.encode("google..com"); - assertNull(buffer); - - buffer = DomainUtils.encode("google!.com"); - assertNull(buffer); - - buffer = DomainUtils.encode("google.o"); - assertNull(buffer); - - buffer = DomainUtils.encode("google,com"); - assertNull(buffer); - } - - @Test - public void testEncodeValidDomainNamesWithoutCompression() { - // Single domain: "google.com" - String suffix = "06676F6F676C6503636F6D00"; - byte[] buffer = DomainUtils.encode("google.com"); - //assertNotNull(buffer); - assertEquals(suffix, HexEncoding.encodeToString(buffer)); - - // Single domain: "google-guest.com" - suffix = "0C676F6F676C652D677565737403636F6D00"; - buffer = DomainUtils.encode("google-guest.com"); - assertNotNull(buffer); - assertEquals(suffix, HexEncoding.encodeToString(buffer)); - - // domain search list: "example.corp.google.com", "corp.google.com", "google.com" - suffix = "076578616D706C6504636F727006676F6F676C6503636F6D00" // example.corp.google.com - + "04636F727006676F6F676C6503636F6D00" // corp.google.com - + "06676F6F676C6503636F6D00"; // google.com - buffer = DomainUtils.encode(new String[] { - "example.corp.google.com", "corp.google.com", "google.com"}, - false /* compression */); - assertNotNull(buffer); - assertEquals(suffix, HexEncoding.encodeToString(buffer)); - - - // domain search list: "example.corp.google.com", "corp..google.com"(invalid domain), - // "google.com" - suffix = "076578616D706C6504636F727006676F6F676C6503636F6D00" // example.corp.google.com - + "06676F6F676C6503636F6D00"; // google.com - buffer = DomainUtils.encode(new String[] { - "example.corp.google.com", "corp..google.com", "google.com"}, - false /* compression */); - assertNotNull(buffer); - assertEquals(suffix, HexEncoding.encodeToString(buffer)); - - // Invalid domain search list: "corp..google.com", "..google.com" - buffer = DomainUtils.encode(new String[] {"corp..google.com", "..google.com"}, - false /* compression */); - assertEquals(0, buffer.length); - } - - @Test - public void testEncodeValidDomainNamesWithCompression() { - // domain search list: "example.corp.google.com", "corp.google.com", "google.com" - String suffix = - "076578616D706C6504636F727006676F6F676C6503636F6D00" // example.corp.google.com - + "C008" // corp.google.com - + "C00D"; // google.com - byte[] buffer = DomainUtils.encode(new String[] { - "example.corp.google.com", "corp.google.com", "google.com"}, true); - assertNotNull(buffer); - assertEquals(suffix, HexEncoding.encodeToString(buffer)); - - // domain search list: "example.corp.google.com", "a.example.corp.google.com", "google.com" - suffix = "076578616D706C6504636F727006676F6F676C6503636F6D00" // example.corp.google.com - + "0161C000" // a.example.corp.google.com - + "C00D"; // google.com - buffer = DomainUtils.encode(new String[] { - "example.corp.google.com", "a.example.corp.google.com", "google.com"}, true); - assertNotNull(buffer); - assertEquals(suffix, HexEncoding.encodeToString(buffer)); - - // domain search list: "example.corp.google.com", "google.com", "gle.com" - suffix = "076578616D706C6504636F727006676F6F676C6503636F6D00" // example.corp.google.com - + "C00D" // google.com - + "03676C65C014"; // gle.com - buffer = DomainUtils.encode(new String[] { - "example.corp.google.com", "google.com", "gle.com"}, true); - assertNotNull(buffer); - assertEquals(suffix, HexEncoding.encodeToString(buffer)); - - // domain search list: "example.corp.google.com", "google.com", "google" - suffix = "076578616D706C6504636F727006676F6F676C6503636F6D00" // example.corp.google.com - + "C00D"; // google.com - buffer = DomainUtils.encode(new String[] { - "example.corp.google.com", "google.com", "google"}, true); - assertNotNull(buffer); - assertEquals(suffix, HexEncoding.encodeToString(buffer)); - - // domain search list: "example.corp.google.com", "..google.com"(invalid domain), "google" - suffix = "076578616D706C6504636F727006676F6F676C6503636F6D00"; // example.corp.google.com - buffer = DomainUtils.encode(new String[] { - "example.corp.google.com", "..google.com", "google"}, true); - assertNotNull(buffer); - assertEquals(suffix, HexEncoding.encodeToString(buffer)); - - // domain search list: "example.corp.google.com", "suffix.example.edu.cn", "edu.cn" - suffix = "076578616D706C6504636F727006676F6F676C6503636F6D00" // example.corp.google.com - + "06737566666978076578616D706C650365647502636E00" // suffix.example.edu.cn - + "C028"; // edu.cn - buffer = DomainUtils.encode(new String[] { - "example.corp.google.com", "suffix.example.edu.cn", "edu.cn"}, true); - assertNotNull(buffer); - assertEquals(suffix, HexEncoding.encodeToString(buffer)); - - // domain search list: "google.com", "example.com", "sub.example.com" - suffix = "06676F6F676C6503636F6D00" // google.com - + "076578616D706C65C007" // example.com - + "03737562C00C"; // sub.example.com - buffer = DomainUtils.encode(new String[] { - "google.com", "example.com", "sub.example.com"}, true); - assertNotNull(buffer); - assertEquals(suffix, HexEncoding.encodeToString(buffer)); - } - - @Test - public void testDecodeDomainNames() { - ArrayList<String> suffixStringList; - String suffixes = "06676F6F676C6503636F6D00" // google.com - + "076578616D706C6503636F6D00" // example.com - + "06676F6F676C6500"; // google - List<String> expected = Arrays.asList("google.com", "example.com"); - ByteBuffer buffer = ByteBuffer.wrap(HexEncoding.decode(suffixes)); - suffixStringList = DomainUtils.decode(buffer, false /* compression */); - assertEquals(expected, suffixStringList); - - // include suffix with invalid length: 64 - suffixes = "06676F6F676C6503636F6D00" // google.com - + "406578616D706C6503636F6D00" // example.com(length=64) - + "06676F6F676C6500"; // google - expected = Arrays.asList("google.com"); - buffer = ByteBuffer.wrap(HexEncoding.decode(suffixes)); - suffixStringList = DomainUtils.decode(buffer, false /* compression */); - assertEquals(expected, suffixStringList); - - // include suffix with invalid length: 0 - suffixes = "06676F6F676C6503636F6D00" // google.com - + "076578616D706C6503636F6D00" // example.com - + "00676F6F676C6500"; // google(length=0) - expected = Arrays.asList("google.com", "example.com"); - buffer = ByteBuffer.wrap(HexEncoding.decode(suffixes)); - suffixStringList = DomainUtils.decode(buffer, false /* compression */); - assertEquals(expected, suffixStringList); - - suffixes = - "076578616D706C6504636F727006676F6F676C6503636F6D00" // example.corp.google.com - + "C008" // corp.google.com - + "C00D"; // google.com - expected = Arrays.asList("example.corp.google.com", "corp.google.com", "google.com"); - buffer = ByteBuffer.wrap(HexEncoding.decode(suffixes)); - suffixStringList = DomainUtils.decode(buffer, true /* compression */); - assertEquals(expected, suffixStringList); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/HexDumpTest.java b/common/tests/unit/src/com/android/net/module/util/HexDumpTest.java deleted file mode 100644 index 5a15585d..00000000 --- a/common/tests/unit/src/com/android/net/module/util/HexDumpTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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.net.module.util; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class HexDumpTest { - @Test - public void testBytesToHexString() { - assertEquals("abcdef", HexDump.toHexString( - new byte[]{(byte) 0xab, (byte) 0xcd, (byte) 0xef}, false)); - assertEquals("ABCDEF", HexDump.toHexString( - new byte[]{(byte) 0xab, (byte) 0xcd, (byte) 0xef}, true)); - } - - @Test - public void testNullArray() { - assertEquals("(null)", HexDump.dumpHexString(null)); - } - - @Test - public void testHexStringToByteArray() { - assertArrayEquals(new byte[]{(byte) 0xab, (byte) 0xcd, (byte) 0xef}, - HexDump.hexStringToByteArray("abcdef")); - assertArrayEquals(new byte[]{(byte) 0xAB, (byte) 0xCD, (byte) 0xEF}, - HexDump.hexStringToByteArray("ABCDEF")); - } - - @Test - public void testIntegerToByteArray() { - assertArrayEquals(new byte[]{(byte) 0xff, (byte) 0x00, (byte) 0x00, (byte) 0x04}, - HexDump.toByteArray((int) 0xff000004)); - } - - @Test - public void testByteToByteArray() { - assertArrayEquals(new byte[]{(byte) 0x7f}, HexDump.toByteArray((byte) 0x7f)); - } - - @Test - public void testIntegerToHexString() { - assertEquals("FF000004", HexDump.toHexString((int) 0xff000004)); - } - - @Test - public void testByteToHexString() { - assertEquals("7F", HexDump.toHexString((byte) 0x7f)); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/Inet4AddressUtilsTest.java b/common/tests/unit/src/com/android/net/module/util/Inet4AddressUtilsTest.java deleted file mode 100644 index 702bdaf8..00000000 --- a/common/tests/unit/src/com/android/net/module/util/Inet4AddressUtilsTest.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (C) 2020 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.net.module.util; - -import static com.android.net.module.util.Inet4AddressUtils.getBroadcastAddress; -import static com.android.net.module.util.Inet4AddressUtils.getImplicitNetmask; -import static com.android.net.module.util.Inet4AddressUtils.getPrefixMaskAsInet4Address; -import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTH; -import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTL; -import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH; -import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTL; -import static com.android.net.module.util.Inet4AddressUtils.netmaskToPrefixLength; -import static com.android.net.module.util.Inet4AddressUtils.prefixLengthToV4NetmaskIntHTH; -import static com.android.net.module.util.Inet4AddressUtils.prefixLengthToV4NetmaskIntHTL; -import static com.android.net.module.util.Inet4AddressUtils.trimAddressZeros; - -import static junit.framework.Assert.assertEquals; - -import static org.junit.Assert.assertNull; -import static org.junit.Assert.fail; - -import android.net.InetAddresses; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.Inet4Address; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class Inet4AddressUtilsTest { - - @Test - public void testInet4AddressToIntHTL() { - assertEquals(0, inet4AddressToIntHTL(ipv4Address("0.0.0.0"))); - assertEquals(0x000080ff, inet4AddressToIntHTL(ipv4Address("255.128.0.0"))); - assertEquals(0x0080ff0a, inet4AddressToIntHTL(ipv4Address("10.255.128.0"))); - assertEquals(0x00feff0a, inet4AddressToIntHTL(ipv4Address("10.255.254.0"))); - assertEquals(0xfeffa8c0, inet4AddressToIntHTL(ipv4Address("192.168.255.254"))); - assertEquals(0xffffa8c0, inet4AddressToIntHTL(ipv4Address("192.168.255.255"))); - } - - @Test - public void testIntToInet4AddressHTL() { - assertEquals(ipv4Address("0.0.0.0"), intToInet4AddressHTL(0)); - assertEquals(ipv4Address("255.128.0.0"), intToInet4AddressHTL(0x000080ff)); - assertEquals(ipv4Address("10.255.128.0"), intToInet4AddressHTL(0x0080ff0a)); - assertEquals(ipv4Address("10.255.254.0"), intToInet4AddressHTL(0x00feff0a)); - assertEquals(ipv4Address("192.168.255.254"), intToInet4AddressHTL(0xfeffa8c0)); - assertEquals(ipv4Address("192.168.255.255"), intToInet4AddressHTL(0xffffa8c0)); - } - - @Test - public void testInet4AddressToIntHTH() { - assertEquals(0, inet4AddressToIntHTH(ipv4Address("0.0.0.0"))); - assertEquals(0xff800000, inet4AddressToIntHTH(ipv4Address("255.128.0.0"))); - assertEquals(0x0aff8000, inet4AddressToIntHTH(ipv4Address("10.255.128.0"))); - assertEquals(0x0afffe00, inet4AddressToIntHTH(ipv4Address("10.255.254.0"))); - assertEquals(0xc0a8fffe, inet4AddressToIntHTH(ipv4Address("192.168.255.254"))); - assertEquals(0xc0a8ffff, inet4AddressToIntHTH(ipv4Address("192.168.255.255"))); - } - - @Test - public void testIntToInet4AddressHTH() { - assertEquals(ipv4Address("0.0.0.0"), intToInet4AddressHTH(0)); - assertEquals(ipv4Address("255.128.0.0"), intToInet4AddressHTH(0xff800000)); - assertEquals(ipv4Address("10.255.128.0"), intToInet4AddressHTH(0x0aff8000)); - assertEquals(ipv4Address("10.255.254.0"), intToInet4AddressHTH(0x0afffe00)); - assertEquals(ipv4Address("192.168.255.254"), intToInet4AddressHTH(0xc0a8fffe)); - assertEquals(ipv4Address("192.168.255.255"), intToInet4AddressHTH(0xc0a8ffff)); - } - - - @Test - public void testPrefixLengthToV4NetmaskIntHTL() { - assertEquals(0, prefixLengthToV4NetmaskIntHTL(0)); - assertEquals(0x000080ff /* 255.128.0.0 */, prefixLengthToV4NetmaskIntHTL(9)); - assertEquals(0x0080ffff /* 255.255.128.0 */, prefixLengthToV4NetmaskIntHTL(17)); - assertEquals(0x00feffff /* 255.255.254.0 */, prefixLengthToV4NetmaskIntHTL(23)); - assertEquals(0xfeffffff /* 255.255.255.254 */, prefixLengthToV4NetmaskIntHTL(31)); - assertEquals(0xffffffff /* 255.255.255.255 */, prefixLengthToV4NetmaskIntHTL(32)); - } - - @Test - public void testPrefixLengthToV4NetmaskIntHTH() { - assertEquals(0, prefixLengthToV4NetmaskIntHTH(0)); - assertEquals(0xff800000 /* 255.128.0.0 */, prefixLengthToV4NetmaskIntHTH(9)); - assertEquals(0xffff8000 /* 255.255.128.0 */, prefixLengthToV4NetmaskIntHTH(17)); - assertEquals(0xfffffe00 /* 255.255.254.0 */, prefixLengthToV4NetmaskIntHTH(23)); - assertEquals(0xfffffffe /* 255.255.255.254 */, prefixLengthToV4NetmaskIntHTH(31)); - assertEquals(0xffffffff /* 255.255.255.255 */, prefixLengthToV4NetmaskIntHTH(32)); - } - - @Test(expected = IllegalArgumentException.class) - public void testPrefixLengthToV4NetmaskIntHTH_NegativeLength() { - prefixLengthToV4NetmaskIntHTH(-1); - } - - @Test(expected = IllegalArgumentException.class) - public void testPrefixLengthToV4NetmaskIntHTH_LengthTooLarge() { - prefixLengthToV4NetmaskIntHTH(33); - } - - private void checkAddressMasking(String expectedAddr, String addr, int prefixLength) { - final int prefix = prefixLengthToV4NetmaskIntHTH(prefixLength); - final int addrInt = inet4AddressToIntHTH(ipv4Address(addr)); - assertEquals(ipv4Address(expectedAddr), intToInet4AddressHTH(prefix & addrInt)); - } - - @Test - public void testPrefixLengthToV4NetmaskIntHTH_MaskAddr() { - checkAddressMasking("192.168.0.0", "192.168.128.1", 16); - checkAddressMasking("255.240.0.0", "255.255.255.255", 12); - checkAddressMasking("255.255.255.255", "255.255.255.255", 32); - checkAddressMasking("0.0.0.0", "255.255.255.255", 0); - } - - @Test - public void testGetImplicitNetmask() { - assertEquals(8, getImplicitNetmask(ipv4Address("4.2.2.2"))); - assertEquals(8, getImplicitNetmask(ipv4Address("10.5.6.7"))); - assertEquals(16, getImplicitNetmask(ipv4Address("173.194.72.105"))); - assertEquals(16, getImplicitNetmask(ipv4Address("172.23.68.145"))); - assertEquals(24, getImplicitNetmask(ipv4Address("192.0.2.1"))); - assertEquals(24, getImplicitNetmask(ipv4Address("192.168.5.1"))); - assertEquals(32, getImplicitNetmask(ipv4Address("224.0.0.1"))); - assertEquals(32, getImplicitNetmask(ipv4Address("255.6.7.8"))); - } - - private void assertInvalidNetworkMask(Inet4Address addr) { - try { - netmaskToPrefixLength(addr); - fail("Invalid netmask " + addr.getHostAddress() + " did not cause exception"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testNetmaskToPrefixLength() { - assertEquals(0, netmaskToPrefixLength(ipv4Address("0.0.0.0"))); - assertEquals(9, netmaskToPrefixLength(ipv4Address("255.128.0.0"))); - assertEquals(17, netmaskToPrefixLength(ipv4Address("255.255.128.0"))); - assertEquals(23, netmaskToPrefixLength(ipv4Address("255.255.254.0"))); - assertEquals(31, netmaskToPrefixLength(ipv4Address("255.255.255.254"))); - assertEquals(32, netmaskToPrefixLength(ipv4Address("255.255.255.255"))); - - assertInvalidNetworkMask(ipv4Address("0.0.0.1")); - assertInvalidNetworkMask(ipv4Address("255.255.255.253")); - assertInvalidNetworkMask(ipv4Address("255.255.0.255")); - } - - @Test - public void testGetPrefixMaskAsAddress() { - assertEquals("255.255.240.0", getPrefixMaskAsInet4Address(20).getHostAddress()); - assertEquals("255.0.0.0", getPrefixMaskAsInet4Address(8).getHostAddress()); - assertEquals("0.0.0.0", getPrefixMaskAsInet4Address(0).getHostAddress()); - assertEquals("255.255.255.255", getPrefixMaskAsInet4Address(32).getHostAddress()); - } - - @Test - public void testGetBroadcastAddress() { - assertEquals("192.168.15.255", - getBroadcastAddress(ipv4Address("192.168.0.123"), 20).getHostAddress()); - assertEquals("192.255.255.255", - getBroadcastAddress(ipv4Address("192.168.0.123"), 8).getHostAddress()); - assertEquals("192.168.0.123", - getBroadcastAddress(ipv4Address("192.168.0.123"), 32).getHostAddress()); - assertEquals("255.255.255.255", - getBroadcastAddress(ipv4Address("192.168.0.123"), 0).getHostAddress()); - } - - @Test(expected = IllegalArgumentException.class) - public void testGetBroadcastAddress_PrefixTooLarge() { - getBroadcastAddress(ipv4Address("192.168.0.123"), 33); - } - - @Test(expected = IllegalArgumentException.class) - public void testGetBroadcastAddress_NegativePrefix() { - getBroadcastAddress(ipv4Address("192.168.0.123"), -1); - } - - @Test(expected = IllegalArgumentException.class) - public void testGetPrefixMaskAsAddress_PrefixTooLarge() { - getPrefixMaskAsInet4Address(33); - } - - @Test(expected = IllegalArgumentException.class) - public void testGetPrefixMaskAsAddress_NegativePrefix() { - getPrefixMaskAsInet4Address(-1); - } - - @Test - public void testTrimAddressZeros() { - assertNull(trimAddressZeros(null)); - assertEquals("$invalid&", trimAddressZeros("$invalid&")); - assertEquals("example.com", trimAddressZeros("example.com")); - assertEquals("a.b.c.d", trimAddressZeros("a.b.c.d")); - - assertEquals("192.0.2.2", trimAddressZeros("192.000.02.2")); - assertEquals("192.0.2.2", trimAddressZeros("192.0.2.2")); - } - - private Inet4Address ipv4Address(String addr) { - return (Inet4Address) InetAddresses.parseNumericAddress(addr); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/InetAddressUtilsTest.java b/common/tests/unit/src/com/android/net/module/util/InetAddressUtilsTest.java deleted file mode 100644 index bb2b9332..00000000 --- a/common/tests/unit/src/com/android/net/module/util/InetAddressUtilsTest.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2020 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.net.module.util; - -import static junit.framework.Assert.assertEquals; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import android.net.InetAddresses; -import android.os.Parcel; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.Inet6Address; -import java.net.InetAddress; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class InetAddressUtilsTest { - - private InetAddress parcelUnparcelAddress(InetAddress addr) { - Parcel p = Parcel.obtain(); - InetAddressUtils.parcelInetAddress(p, addr, 0 /* flags */); - p.setDataPosition(0); - byte[] marshalled = p.marshall(); - p.recycle(); - p = Parcel.obtain(); - p.unmarshall(marshalled, 0, marshalled.length); - p.setDataPosition(0); - InetAddress out = InetAddressUtils.unparcelInetAddress(p); - p.recycle(); - return out; - } - - @Test - public void testParcelUnparcelIpv4Address() throws Exception { - InetAddress ipv4 = InetAddress.getByName("192.0.2.1"); - assertEquals(ipv4, parcelUnparcelAddress(ipv4)); - } - - @Test - public void testParcelUnparcelIpv6Address() throws Exception { - InetAddress ipv6 = InetAddress.getByName("2001:db8::1"); - assertEquals(ipv6, parcelUnparcelAddress(ipv6)); - } - - @Test - public void testParcelUnparcelScopedIpv6Address() throws Exception { - InetAddress ipv6 = InetAddress.getByName("fe80::1%42"); - assertEquals(42, ((Inet6Address) ipv6).getScopeId()); - Inet6Address out = (Inet6Address) parcelUnparcelAddress(ipv6); - assertEquals(ipv6, out); - assertEquals(42, out.getScopeId()); - } - - @Test - public void testWithScopeId() { - final int scopeId = 999; - - final String globalAddrStr = "2401:fa00:49c:484:dc41:e6ff:fefd:f180"; - final Inet6Address globalAddr = (Inet6Address) InetAddresses - .parseNumericAddress(globalAddrStr); - final Inet6Address updatedGlobalAddr = InetAddressUtils.withScopeId(globalAddr, scopeId); - assertFalse(updatedGlobalAddr.isLinkLocalAddress()); - assertEquals(globalAddrStr, updatedGlobalAddr.getHostAddress()); - assertEquals(0, updatedGlobalAddr.getScopeId()); - - final String localAddrStr = "fe80::4735:9628:d038:2087"; - final Inet6Address localAddr = (Inet6Address) InetAddresses - .parseNumericAddress(localAddrStr); - final Inet6Address updatedLocalAddr = InetAddressUtils.withScopeId(localAddr, scopeId); - assertTrue(updatedLocalAddr.isLinkLocalAddress()); - assertEquals(localAddrStr + "%" + scopeId, updatedLocalAddr.getHostAddress()); - assertEquals(scopeId, updatedLocalAddr.getScopeId()); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/InterfaceParamsTest.java b/common/tests/unit/src/com/android/net/module/util/InterfaceParamsTest.java deleted file mode 100644 index a1d8c106..00000000 --- a/common/tests/unit/src/com/android/net/module/util/InterfaceParamsTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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.net.module.util; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class InterfaceParamsTest { - @Test - public void testNullInterfaceReturnsNull() { - assertNull(InterfaceParams.getByName(null)); - } - - @Test - public void testNonExistentInterfaceReturnsNull() { - assertNull(InterfaceParams.getByName("doesnotexist0")); - } - - @Test - public void testLoopback() { - final InterfaceParams ifParams = InterfaceParams.getByName("lo"); - assertNotNull(ifParams); - assertEquals("lo", ifParams.name); - assertTrue(ifParams.index > 0); - assertNotNull(ifParams.macAddr); - assertFalse(ifParams.hasMacAddress); - assertTrue(ifParams.defaultMtu >= NetworkStackConstants.ETHER_MTU); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/IpRangeTest.java b/common/tests/unit/src/com/android/net/module/util/IpRangeTest.java deleted file mode 100644 index 20bbd4a1..00000000 --- a/common/tests/unit/src/com/android/net/module/util/IpRangeTest.java +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Copyright (C) 2020 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.net.module.util; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import android.annotation.SuppressLint; -import android.net.InetAddresses; -import android.net.IpPrefix; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.util.ArrayList; -import java.util.List; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class IpRangeTest { - - private static InetAddress address(String addr) { - return InetAddresses.parseNumericAddress(addr); - } - - private static final Inet4Address IPV4_ADDR = (Inet4Address) address("192.0.2.4"); - private static final Inet4Address IPV4_RANGE_END = (Inet4Address) address("192.0.3.1"); - private static final Inet6Address IPV6_ADDR = (Inet6Address) address("2001:db8::"); - private static final Inet6Address IPV6_RANGE_END = (Inet6Address) address("2001:db9:010f::"); - - private static final byte[] IPV4_BYTES = IPV4_ADDR.getAddress(); - private static final byte[] IPV6_BYTES = IPV6_ADDR.getAddress(); - - @Test - public void testConstructorBadArguments() { - try { - new IpRange(null, IPV6_ADDR); - fail("Expected NullPointerException: null start address"); - } catch (NullPointerException expected) { - } - - try { - new IpRange(IPV6_ADDR, null); - fail("Expected NullPointerException: null end address"); - } catch (NullPointerException expected) { - } - - try { - new IpRange(null, null); - fail("Expected NullPointerException: null addresses"); - } catch (NullPointerException expected) { - } - - try { - new IpRange(null); - fail("Expected NullPointerException: null start address"); - } catch (NullPointerException expected) { - } - - try { - new IpRange(address("10.10.10.10"), address("1.2.3.4")); - fail("Expected IllegalArgumentException: start address after end address"); - } catch (IllegalArgumentException expected) { - } - - try { - new IpRange(address("ffff::"), address("abcd::")); - fail("Expected IllegalArgumentException: start address after end address"); - } catch (IllegalArgumentException expected) { - } - } - - @SuppressLint("NewApi") - @Test - public void testConstructor() { - IpRange r = new IpRange(new IpPrefix(IPV4_ADDR, 32)); - assertEquals(IPV4_ADDR, r.getStartAddr()); - assertEquals(IPV4_ADDR, r.getEndAddr()); - - r = new IpRange(new IpPrefix(IPV4_ADDR, 16)); - assertEquals(address("192.0.0.0"), r.getStartAddr()); - assertEquals(address("192.0.255.255"), r.getEndAddr()); - - r = new IpRange(IPV4_ADDR, IPV4_RANGE_END); - assertEquals(IPV4_ADDR, r.getStartAddr()); - assertEquals(IPV4_RANGE_END, r.getEndAddr()); - - r = new IpRange(new IpPrefix(IPV6_ADDR, 128)); - assertEquals(IPV6_ADDR, r.getStartAddr()); - assertEquals(IPV6_ADDR, r.getEndAddr()); - - r = new IpRange(new IpPrefix(IPV6_ADDR, 16)); - assertEquals(address("2001::"), r.getStartAddr()); - assertEquals(address("2001:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), r.getEndAddr()); - - r = new IpRange(IPV6_ADDR, IPV6_RANGE_END); - assertEquals(IPV6_ADDR, r.getStartAddr()); - assertEquals(IPV6_RANGE_END, r.getEndAddr()); - } - - @SuppressLint("NewApi") - @Test - public void testContainsRangeEqualRanges() { - final IpRange r1 = new IpRange(new IpPrefix(IPV6_ADDR, 35)); - final IpRange r2 = new IpRange(new IpPrefix(IPV6_ADDR, 35)); - - assertTrue(r1.containsRange(r2)); - assertTrue(r2.containsRange(r1)); - assertEquals(r1, r2); - } - - @SuppressLint("NewApi") - @Test - public void testContainsRangeSubset() { - final IpRange r1 = new IpRange(new IpPrefix(IPV6_ADDR, 64)); - final IpRange r2 = new IpRange(new IpPrefix(address("2001:db8::0101"), 128)); - - assertTrue(r1.containsRange(r2)); - assertFalse(r2.containsRange(r1)); - assertNotEquals(r1, r2); - } - - @SuppressLint("NewApi") - @Test - public void testContainsRangeTruncatesLowerOrderBits() { - final IpRange r1 = new IpRange(new IpPrefix(IPV6_ADDR, 100)); - final IpRange r2 = new IpRange(new IpPrefix(address("2001:db8::0101"), 100)); - - assertTrue(r1.containsRange(r2)); - assertTrue(r2.containsRange(r1)); - assertEquals(r1, r2); - } - - @SuppressLint("NewApi") - @Test - public void testContainsRangeSubsetSameStartAddr() { - final IpRange r1 = new IpRange(new IpPrefix(IPV6_ADDR, 35)); - final IpRange r2 = new IpRange(new IpPrefix(IPV6_ADDR, 39)); - - assertTrue(r1.containsRange(r2)); - assertFalse(r2.containsRange(r1)); - assertNotEquals(r1, r2); - } - - @SuppressLint("NewApi") - @Test - public void testContainsRangeOverlapping() { - final IpRange r1 = new IpRange(new IpPrefix(address("2001:db9::"), 32)); - final IpRange r2 = new IpRange(address("2001:db8::"), address("2001:db9::1")); - - assertFalse(r1.containsRange(r2)); - assertFalse(r2.containsRange(r1)); - assertNotEquals(r1, r2); - } - - @SuppressLint("NewApi") - @Test - public void testOverlapsRangeEqualRanges() { - final IpRange r1 = new IpRange(new IpPrefix(IPV6_ADDR, 35)); - final IpRange r2 = new IpRange(new IpPrefix(IPV6_ADDR, 35)); - - assertTrue(r1.overlapsRange(r2)); - assertTrue(r2.overlapsRange(r1)); - assertEquals(r1, r2); - } - - @SuppressLint("NewApi") - @Test - public void testOverlapsRangeSubset() { - final IpRange r1 = new IpRange(new IpPrefix(IPV6_ADDR, 35)); - final IpRange r2 = new IpRange(new IpPrefix(IPV6_ADDR, 39)); - - assertTrue(r1.overlapsRange(r2)); - assertTrue(r2.overlapsRange(r1)); - assertNotEquals(r1, r2); - } - - @SuppressLint("NewApi") - @Test - public void testOverlapsRangeDisjoint() { - final IpRange r1 = new IpRange(new IpPrefix(IPV6_ADDR, 32)); - final IpRange r2 = new IpRange(new IpPrefix(address("2001:db9::"), 32)); - - assertFalse(r1.overlapsRange(r2)); - assertFalse(r2.overlapsRange(r1)); - assertNotEquals(r1, r2); - } - - @SuppressLint("NewApi") - @Test - public void testOverlapsRangePartialOverlapLow() { - final IpRange r1 = new IpRange(new IpPrefix(address("2001:db9::"), 32)); - final IpRange r2 = new IpRange(address("2001:db8::"), address("2001:db9::1")); - - assertTrue(r1.overlapsRange(r2)); - assertTrue(r2.overlapsRange(r1)); - assertNotEquals(r1, r2); - } - - @SuppressLint("NewApi") - @Test - public void testOverlapsRangePartialOverlapHigh() { - final IpRange r1 = new IpRange(new IpPrefix(address("2001:db7::"), 32)); - final IpRange r2 = new IpRange(address("2001:db7::ffff"), address("2001:db8::")); - - assertTrue(r1.overlapsRange(r2)); - assertTrue(r2.overlapsRange(r1)); - assertNotEquals(r1, r2); - } - - @Test - public void testIpRangeToPrefixesIpv4FullRange() throws Exception { - final IpRange range = new IpRange(address("0.0.0.0"), address("255.255.255.255")); - final List<IpPrefix> prefixes = new ArrayList<>(); - prefixes.add(new IpPrefix("0.0.0.0/0")); - - assertEquals(prefixes, range.asIpPrefixes()); - } - - @Test - public void testIpRangeToPrefixesIpv4() throws Exception { - final IpRange range = new IpRange(IPV4_ADDR, IPV4_RANGE_END); - final List<IpPrefix> prefixes = new ArrayList<>(); - prefixes.add(new IpPrefix("192.0.2.128/25")); - prefixes.add(new IpPrefix("192.0.2.64/26")); - prefixes.add(new IpPrefix("192.0.2.32/27")); - prefixes.add(new IpPrefix("192.0.2.16/28")); - prefixes.add(new IpPrefix("192.0.2.8/29")); - prefixes.add(new IpPrefix("192.0.2.4/30")); - prefixes.add(new IpPrefix("192.0.3.0/31")); - - assertEquals(prefixes, range.asIpPrefixes()); - } - - @Test - public void testIpRangeToPrefixesIpv6FullRange() throws Exception { - final IpRange range = - new IpRange(address("::"), address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")); - final List<IpPrefix> prefixes = new ArrayList<>(); - prefixes.add(new IpPrefix("::/0")); - - assertEquals(prefixes, range.asIpPrefixes()); - } - - @Test - public void testIpRangeToPrefixesIpv6() throws Exception { - final IpRange range = new IpRange(IPV6_ADDR, IPV6_RANGE_END); - final List<IpPrefix> prefixes = new ArrayList<>(); - prefixes.add(new IpPrefix("2001:db8::/32")); - prefixes.add(new IpPrefix("2001:db9::/40")); - prefixes.add(new IpPrefix("2001:db9:100::/45")); - prefixes.add(new IpPrefix("2001:db9:108::/46")); - prefixes.add(new IpPrefix("2001:db9:10c::/47")); - prefixes.add(new IpPrefix("2001:db9:10e::/48")); - prefixes.add(new IpPrefix("2001:db9:10f::/128")); - - assertEquals(prefixes, range.asIpPrefixes()); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/IpUtilsTest.java b/common/tests/unit/src/com/android/net/module/util/IpUtilsTest.java deleted file mode 100644 index d57023ca..00000000 --- a/common/tests/unit/src/com/android/net/module/util/IpUtilsTest.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright (C) 2020 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.net.module.util; - -import static com.android.net.module.util.NetworkStackConstants.ICMP_CHECKSUM_OFFSET; -import static com.android.net.module.util.NetworkStackConstants.IPV4_CHECKSUM_OFFSET; - -import static org.junit.Assert.assertEquals; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.nio.ByteBuffer; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class IpUtilsTest { - - private static final int IPV4_HEADER_LENGTH = 20; - private static final int IPV6_HEADER_LENGTH = 40; - private static final int TCP_HEADER_LENGTH = 20; - private static final int UDP_HEADER_LENGTH = 8; - private static final int TCP_CHECKSUM_OFFSET = 16; - private static final int UDP_CHECKSUM_OFFSET = 6; - - private int getUnsignedByte(ByteBuffer buf, int offset) { - return buf.get(offset) & 0xff; - } - - private int getChecksum(ByteBuffer buf, int offset) { - return getUnsignedByte(buf, offset) * 256 + getUnsignedByte(buf, offset + 1); - } - - private void assertChecksumEquals(int expected, short actual) { - assertEquals(Integer.toHexString(expected), Integer.toHexString(actual & 0xffff)); - } - - // Generate test packets using Python code like this:: - // - // from scapy import all as scapy - // - // def JavaPacketDefinition(bytes): - // out = " ByteBuffer packet = ByteBuffer.wrap(new byte[] {\n " - // for i in xrange(len(bytes)): - // out += "(byte) 0x%02x" % ord(bytes[i]) - // if i < len(bytes) - 1: - // if i % 4 == 3: - // out += ",\n " - // else: - // out += ", " - // out += "\n });" - // return out - // - // packet = (scapy.IPv6(src="2001:db8::1", dst="2001:db8::2") / - // scapy.UDP(sport=12345, dport=7) / - // "hello") - // print JavaPacketDefinition(str(packet)) - - @Test - public void testEmptyAndZeroBufferChecksum() throws Exception { - ByteBuffer packet = ByteBuffer.wrap(new byte[] { (byte) 0x00, (byte) 0x00, }); - // the following should *not* return 0xFFFF - assertEquals(0, IpUtils.checksum(packet, 0, 0, 0)); - assertEquals(0, IpUtils.checksum(packet, 0, 0, 1)); - assertEquals(0, IpUtils.checksum(packet, 0, 0, 2)); - assertEquals(0, IpUtils.checksum(packet, 0, 1, 2)); - assertEquals(0, IpUtils.checksum(packet, 0xFFFF, 0, 0)); - assertEquals(0, IpUtils.checksum(packet, 0xFFFF, 0, 1)); - assertEquals(0, IpUtils.checksum(packet, 0xFFFF, 0, 2)); - assertEquals(0, IpUtils.checksum(packet, 0xFFFF, 1, 2)); - } - - @Test - public void testIpv6TcpChecksum() throws Exception { - // packet = (scapy.IPv6(src="2001:db8::1", dst="2001:db8::2", tc=0x80) / - // scapy.TCP(sport=12345, dport=7, - // seq=1692871236, ack=128376451, flags=16, - // window=32768) / - // "hello, world") - ByteBuffer packet = ByteBuffer.wrap(new byte[] { - (byte) 0x68, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x20, (byte) 0x06, (byte) 0x40, - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, - (byte) 0x30, (byte) 0x39, (byte) 0x00, (byte) 0x07, - (byte) 0x64, (byte) 0xe7, (byte) 0x2a, (byte) 0x44, - (byte) 0x07, (byte) 0xa6, (byte) 0xde, (byte) 0x83, - (byte) 0x50, (byte) 0x10, (byte) 0x80, (byte) 0x00, - (byte) 0xee, (byte) 0x71, (byte) 0x00, (byte) 0x00, - (byte) 0x68, (byte) 0x65, (byte) 0x6c, (byte) 0x6c, - (byte) 0x6f, (byte) 0x2c, (byte) 0x20, (byte) 0x77, - (byte) 0x6f, (byte) 0x72, (byte) 0x6c, (byte) 0x64 - }); - - // Check that a valid packet has checksum 0. - int transportLen = packet.limit() - IPV6_HEADER_LENGTH; - assertEquals(0, IpUtils.tcpChecksum(packet, 0, IPV6_HEADER_LENGTH, transportLen)); - - // Check that we can calculate the checksum from scratch. - int sumOffset = IPV6_HEADER_LENGTH + TCP_CHECKSUM_OFFSET; - int sum = getUnsignedByte(packet, sumOffset) * 256 + getUnsignedByte(packet, sumOffset + 1); - assertEquals(0xee71, sum); - - packet.put(sumOffset, (byte) 0); - packet.put(sumOffset + 1, (byte) 0); - assertChecksumEquals(sum, IpUtils.tcpChecksum(packet, 0, IPV6_HEADER_LENGTH, transportLen)); - - // Check that writing the checksum back into the packet results in a valid packet. - packet.putShort( - sumOffset, - IpUtils.tcpChecksum(packet, 0, IPV6_HEADER_LENGTH, transportLen)); - assertEquals(0, IpUtils.tcpChecksum(packet, 0, IPV6_HEADER_LENGTH, transportLen)); - } - - @Test - public void testIpv4UdpChecksum() { - // packet = (scapy.IP(src="192.0.2.1", dst="192.0.2.2", tos=0x40) / - // scapy.UDP(sport=32012, dport=4500) / - // "\xff") - ByteBuffer packet = ByteBuffer.wrap(new byte[] { - (byte) 0x45, (byte) 0x40, (byte) 0x00, (byte) 0x1d, - (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, - (byte) 0x40, (byte) 0x11, (byte) 0xf6, (byte) 0x8b, - (byte) 0xc0, (byte) 0x00, (byte) 0x02, (byte) 0x01, - (byte) 0xc0, (byte) 0x00, (byte) 0x02, (byte) 0x02, - (byte) 0x7d, (byte) 0x0c, (byte) 0x11, (byte) 0x94, - (byte) 0x00, (byte) 0x09, (byte) 0xee, (byte) 0x36, - (byte) 0xff - }); - - // Check that a valid packet has IP checksum 0 and UDP checksum 0xffff (0 is not a valid - // UDP checksum, so the udpChecksum rewrites 0 to 0xffff). - assertEquals(0, IpUtils.ipChecksum(packet, 0)); - assertEquals((short) 0xffff, IpUtils.udpChecksum(packet, 0, IPV4_HEADER_LENGTH)); - - // Check that we can calculate the checksums from scratch. - final int ipSumOffset = IPV4_CHECKSUM_OFFSET; - final int ipSum = getChecksum(packet, ipSumOffset); - assertEquals(0xf68b, ipSum); - - packet.put(ipSumOffset, (byte) 0); - packet.put(ipSumOffset + 1, (byte) 0); - assertChecksumEquals(ipSum, IpUtils.ipChecksum(packet, 0)); - - final int udpSumOffset = IPV4_HEADER_LENGTH + UDP_CHECKSUM_OFFSET; - final int udpSum = getChecksum(packet, udpSumOffset); - assertEquals(0xee36, udpSum); - - packet.put(udpSumOffset, (byte) 0); - packet.put(udpSumOffset + 1, (byte) 0); - assertChecksumEquals(udpSum, IpUtils.udpChecksum(packet, 0, IPV4_HEADER_LENGTH)); - - // Check that writing the checksums back into the packet results in a valid packet. - packet.putShort(ipSumOffset, IpUtils.ipChecksum(packet, 0)); - packet.putShort(udpSumOffset, IpUtils.udpChecksum(packet, 0, IPV4_HEADER_LENGTH)); - assertEquals(0, IpUtils.ipChecksum(packet, 0)); - assertEquals((short) 0xffff, IpUtils.udpChecksum(packet, 0, IPV4_HEADER_LENGTH)); - } - - @Test - public void testIpv4IcmpChecksum() throws Exception { - // packet = (scapy.IP(src="192.0.2.1", dst="192.0.2.2", tos=0x40) / - // scapy.ICMP(type=0x8, id=0x1234, seq=0x5678) / - // "hello, world") - ByteBuffer packet = ByteBuffer.wrap(new byte[] { - /* IPv4 */ - (byte) 0x45, (byte) 0x40, (byte) 0x00, (byte) 0x28, - (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, - (byte) 0x40, (byte) 0x01, (byte) 0xf6, (byte) 0x90, - (byte) 0xc0, (byte) 0x00, (byte) 0x02, (byte) 0x01, - (byte) 0xc0, (byte) 0x00, (byte) 0x02, (byte) 0x02, - /* ICMP */ - (byte) 0x08, /* type: echo-request */ - (byte) 0x00, /* code: 0 */ - (byte) 0x4f, (byte) 0x07, /* chksum: 0x4f07 */ - (byte) 0x12, (byte) 0x34, /* id: 0x1234 */ - (byte) 0x56, (byte) 0x78, /* seq: 0x5678 */ - (byte) 0x68, (byte) 0x65, (byte) 0x6c, (byte) 0x6c, /* data: hello, world */ - (byte) 0x6f, (byte) 0x2c, (byte) 0x20, (byte) 0x77, - (byte) 0x6f, (byte) 0x72, (byte) 0x6c, (byte) 0x64 - }); - - // Check that a valid packet has checksum 0. - int transportLen = packet.limit() - IPV4_HEADER_LENGTH; - assertEquals(0, IpUtils.icmpChecksum(packet, IPV4_HEADER_LENGTH, transportLen)); - - // Check that we can calculate the checksum from scratch. - int sumOffset = IPV4_HEADER_LENGTH + ICMP_CHECKSUM_OFFSET; - int sum = getUnsignedByte(packet, sumOffset) * 256 + getUnsignedByte(packet, sumOffset + 1); - assertEquals(0x4f07, sum); - - packet.put(sumOffset, (byte) 0); - packet.put(sumOffset + 1, (byte) 0); - assertChecksumEquals(sum, IpUtils.icmpChecksum(packet, IPV4_HEADER_LENGTH, transportLen)); - - // Check that writing the checksum back into the packet results in a valid packet. - packet.putShort( - sumOffset, - IpUtils.icmpChecksum(packet, IPV4_HEADER_LENGTH, transportLen)); - assertEquals(0, IpUtils.icmpChecksum(packet, IPV4_HEADER_LENGTH, transportLen)); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/Ipv6UtilsTest.java b/common/tests/unit/src/com/android/net/module/util/Ipv6UtilsTest.java deleted file mode 100644 index 4866a489..00000000 --- a/common/tests/unit/src/com/android/net/module/util/Ipv6UtilsTest.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2020 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.net.module.util; - -import static org.junit.Assert.assertEquals; - -import android.net.InetAddresses; -import android.net.IpPrefix; -import android.net.MacAddress; -import android.system.OsConstants; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.net.module.util.structs.EthernetHeader; -import com.android.net.module.util.structs.Icmpv6Header; -import com.android.net.module.util.structs.Ipv6Header; -import com.android.net.module.util.structs.PrefixInformationOption; -import com.android.net.module.util.structs.RaHeader; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.Inet6Address; -import java.nio.ByteBuffer; -import java.util.Arrays; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class Ipv6UtilsTest { - - private static final MacAddress MAC1 = MacAddress.fromString("11:22:33:44:55:66"); - private static final MacAddress MAC2 = MacAddress.fromString("aa:bb:cc:dd:ee:ff"); - private static final Inet6Address LINK_LOCAL = addr("fe80::1"); - private static final Inet6Address ROUTER_LINK_LOCAL = addr("fe80::cafe:d00d"); - private static final Inet6Address ALL_ROUTERS = - NetworkStackConstants.IPV6_ADDR_ALL_ROUTERS_MULTICAST; - private static final Inet6Address ALL_NODES = - NetworkStackConstants.IPV6_ADDR_ALL_NODES_MULTICAST; - - @Test - public void testBuildRsPacket() { - ByteBuffer b = Ipv6Utils.buildRsPacket(MAC1, MAC2, LINK_LOCAL, ALL_ROUTERS /* no opts */); - - EthernetHeader eth = Struct.parse(EthernetHeader.class, b); - assertEquals(MAC1, eth.srcMac); - assertEquals(MAC2, eth.dstMac); - - Ipv6Header ipv6 = Struct.parse(Ipv6Header.class, b); - assertEquals(255, ipv6.hopLimit); - assertEquals(OsConstants.IPPROTO_ICMPV6, ipv6.nextHeader); - assertEquals(LINK_LOCAL, ipv6.srcIp); - assertEquals(ALL_ROUTERS, ipv6.dstIp); - - Icmpv6Header icmpv6 = Struct.parse(Icmpv6Header.class, b); - assertEquals(NetworkStackConstants.ICMPV6_ROUTER_SOLICITATION, icmpv6.type); - assertEquals(0, icmpv6.code); - } - - @Test - public void testBuildRaPacket() { - final byte pioFlags = - NetworkStackConstants.PIO_FLAG_AUTONOMOUS | NetworkStackConstants.PIO_FLAG_ON_LINK; - ByteBuffer pio1 = PrefixInformationOption.build(new IpPrefix("2001:db8:1::/64"), - pioFlags, 3600 /* validLifetime */, 1800 /* preferredLifetime */); - ByteBuffer pio2 = PrefixInformationOption.build(new IpPrefix("fdcd:a17f:6502:1::/64"), - pioFlags, 86400 /* validLifetime */, 86400 /* preferredLifetime */); - - ByteBuffer b = Ipv6Utils.buildRaPacket(MAC2, MAC1, ROUTER_LINK_LOCAL, ALL_NODES, - (byte) 0 /* flags */, 7200 /* lifetime */, - 30_000 /* reachableTime */, 750 /* retransTimer */, - pio1, pio2); - - EthernetHeader eth = Struct.parse(EthernetHeader.class, b); - assertEquals(MAC2, eth.srcMac); - assertEquals(MAC1, eth.dstMac); - - Ipv6Header ipv6 = Struct.parse(Ipv6Header.class, b); - assertEquals(255, ipv6.hopLimit); - assertEquals(OsConstants.IPPROTO_ICMPV6, ipv6.nextHeader); - assertEquals(ROUTER_LINK_LOCAL, ipv6.srcIp); - assertEquals(ALL_NODES, ipv6.dstIp); - - Icmpv6Header icmpv6 = Struct.parse(Icmpv6Header.class, b); - assertEquals(NetworkStackConstants.ICMPV6_ROUTER_ADVERTISEMENT, icmpv6.type); - assertEquals(0, icmpv6.code); - - RaHeader ra = Struct.parse(RaHeader.class, b); - assertEquals(0, ra.hopLimit); // Hop limit: unspecified. - assertEquals(0, ra.flags); - assertEquals(7200, ra.lifetime); - assertEquals(30_000, ra.reachableTime); - assertEquals(750, ra.retransTimer); - - PrefixInformationOption pio = Struct.parse(PrefixInformationOption.class, b); - assertPioEquals(pio, "2001:db8:1::/64", pioFlags, 3600, 1800); - pio = Struct.parse(PrefixInformationOption.class, b); - assertPioEquals(pio, "fdcd:a17f:6502:1::/64", pioFlags, 86400, 86400); - } - - @Test - public void testBuildEchoRequestPacket() { - final ByteBuffer b = Ipv6Utils.buildEchoRequestPacket(MAC2, MAC1, LINK_LOCAL, ALL_NODES); - - EthernetHeader eth = Struct.parse(EthernetHeader.class, b); - assertEquals(MAC2, eth.srcMac); - assertEquals(MAC1, eth.dstMac); - - Ipv6Header ipv6 = Struct.parse(Ipv6Header.class, b); - assertEquals(255, ipv6.hopLimit); - assertEquals(OsConstants.IPPROTO_ICMPV6, ipv6.nextHeader); - assertEquals(LINK_LOCAL, ipv6.srcIp); - assertEquals(ALL_NODES, ipv6.dstIp); - - Icmpv6Header icmpv6 = Struct.parse(Icmpv6Header.class, b); - assertEquals(NetworkStackConstants.ICMPV6_ECHO_REQUEST_TYPE, icmpv6.type); - assertEquals(0, icmpv6.code); - } - - @Test - public void testBuildEchoReplyPacket() { - final ByteBuffer b = Ipv6Utils.buildEchoReplyPacket(LINK_LOCAL, ALL_NODES); - - Ipv6Header ipv6 = Struct.parse(Ipv6Header.class, b); - assertEquals(255, ipv6.hopLimit); - assertEquals(OsConstants.IPPROTO_ICMPV6, ipv6.nextHeader); - assertEquals(LINK_LOCAL, ipv6.srcIp); - assertEquals(ALL_NODES, ipv6.dstIp); - - Icmpv6Header icmpv6 = Struct.parse(Icmpv6Header.class, b); - assertEquals(NetworkStackConstants.ICMPV6_ECHO_REPLY_TYPE, icmpv6.type); - assertEquals(0, icmpv6.code); - } - - private void assertPioEquals(PrefixInformationOption pio, String prefix, byte flags, - long valid, long preferred) { - assertEquals(NetworkStackConstants.ICMPV6_ND_OPTION_PIO, pio.type); - assertEquals(4, pio.length); - assertEquals(flags, pio.flags); - assertEquals(valid, pio.validLifetime); - assertEquals(preferred, pio.preferredLifetime); - IpPrefix expected = new IpPrefix(prefix); - IpPrefix actual = new IpPrefix(pio.prefix, pio.prefixLen); - assertEquals(expected, actual); - } - - private static Inet6Address addr(String addr) { - return (Inet6Address) InetAddresses.parseNumericAddress(addr); - } - - private byte[] slice(byte[] array, int length) { - return Arrays.copyOf(array, length); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/JniUtilTest.kt b/common/tests/unit/src/com/android/net/module/util/JniUtilTest.kt deleted file mode 100644 index 75740877..00000000 --- a/common/tests/unit/src/com/android/net/module/util/JniUtilTest.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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.net.module.util - -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import kotlin.test.assertEquals -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(AndroidJUnit4::class) -@SmallTest -public final class JniUtilTest { - private val TEST_JAVA_UTIL_NAME = "java_util_jni" - private val TEST_ORG_JUNIT_NAME = "org_junit_jni" - - @Test - fun testGetJniLibraryName() { - assertEquals(TEST_JAVA_UTIL_NAME, - JniUtil.getJniLibraryName(java.util.Set::class.java.getPackage())) - assertEquals(TEST_ORG_JUNIT_NAME, - JniUtil.getJniLibraryName(org.junit.Before::class.java.getPackage())) - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/LinkPropertiesUtilsTest.java b/common/tests/unit/src/com/android/net/module/util/LinkPropertiesUtilsTest.java deleted file mode 100644 index 80ab6185..00000000 --- a/common/tests/unit/src/com/android/net/module/util/LinkPropertiesUtilsTest.java +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright (C) 2019 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.net.module.util; - -import static com.android.testutils.MiscAsserts.assertSameElements; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import android.annotation.SuppressLint; -import android.net.InetAddresses; -import android.net.IpPrefix; -import android.net.LinkAddress; -import android.net.LinkProperties; -import android.net.ProxyInfo; -import android.net.RouteInfo; -import android.util.ArraySet; - -import androidx.test.runner.AndroidJUnit4; - -import com.android.net.module.util.LinkPropertiesUtils.CompareOrUpdateResult; -import com.android.net.module.util.LinkPropertiesUtils.CompareResult; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.InetAddress; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.function.Function; - -@RunWith(AndroidJUnit4.class) -public final class LinkPropertiesUtilsTest { - @SuppressLint("NewApi") - private static final IpPrefix PREFIX = new IpPrefix(toInetAddress("75.208.6.0"), 24); - private static final InetAddress V4_ADDR = toInetAddress("75.208.6.1"); - private static final InetAddress V6_ADDR = toInetAddress( - "2001:0db8:85a3:0000:0000:8a2e:0370:7334"); - private static final InetAddress DNS1 = toInetAddress("75.208.7.1"); - private static final InetAddress DNS2 = toInetAddress("69.78.7.1"); - - private static final InetAddress GATEWAY1 = toInetAddress("75.208.8.1"); - private static final InetAddress GATEWAY2 = toInetAddress("69.78.8.1"); - - private static final String IF_NAME = "wlan0"; - private static final LinkAddress V4_LINKADDR = new LinkAddress(V4_ADDR, 32); - private static final LinkAddress V6_LINKADDR = new LinkAddress(V6_ADDR, 128); - private static final RouteInfo RT_INFO1 = new RouteInfo(PREFIX, GATEWAY1, IF_NAME); - private static final RouteInfo RT_INFO2 = new RouteInfo(PREFIX, GATEWAY2, IF_NAME); - private static final String TEST_DOMAIN = "link.properties.com"; - - private static InetAddress toInetAddress(String addrString) { - return InetAddresses.parseNumericAddress(addrString); - } - - private LinkProperties createTestObject() { - final LinkProperties lp = new LinkProperties(); - lp.setInterfaceName(IF_NAME); - lp.addLinkAddress(V4_LINKADDR); - lp.addLinkAddress(V6_LINKADDR); - lp.addDnsServer(DNS1); - lp.addDnsServer(DNS2); - lp.setDomains(TEST_DOMAIN); - lp.addRoute(RT_INFO1); - lp.addRoute(RT_INFO2); - lp.setHttpProxy(ProxyInfo.buildDirectProxy("test", 8888)); - return lp; - } - - @Test - public void testLinkPropertiesIdenticalEqual() { - final LinkProperties source = createTestObject(); - final LinkProperties target = new LinkProperties(source); - - assertTrue(LinkPropertiesUtils.isIdenticalInterfaceName(source, target)); - assertTrue(LinkPropertiesUtils.isIdenticalInterfaceName(target, source)); - - assertTrue(LinkPropertiesUtils.isIdenticalAddresses(source, target)); - assertTrue(LinkPropertiesUtils.isIdenticalAddresses(target, source)); - - assertTrue(LinkPropertiesUtils.isIdenticalAllLinkAddresses(source, target)); - assertTrue(LinkPropertiesUtils.isIdenticalAllLinkAddresses(target, source)); - - assertTrue(LinkPropertiesUtils.isIdenticalDnses(source, target)); - assertTrue(LinkPropertiesUtils.isIdenticalDnses(target, source)); - - assertTrue(LinkPropertiesUtils.isIdenticalRoutes(source, target)); - assertTrue(LinkPropertiesUtils.isIdenticalRoutes(target, source)); - - assertTrue(LinkPropertiesUtils.isIdenticalHttpProxy(source, target)); - assertTrue(LinkPropertiesUtils.isIdenticalHttpProxy(target, source)); - - // Test different interface name. - target.setInterfaceName("lo"); - assertFalse(LinkPropertiesUtils.isIdenticalInterfaceName(source, target)); - assertFalse(LinkPropertiesUtils.isIdenticalInterfaceName(target, source)); - // Restore interface name - target.setInterfaceName(IF_NAME); - - // Compare addresses.size() not equals. - final LinkAddress testLinkAddr = new LinkAddress(toInetAddress("75.208.6.2"), 32); - target.addLinkAddress(testLinkAddr); - assertFalse(LinkPropertiesUtils.isIdenticalAddresses(source, target)); - assertFalse(LinkPropertiesUtils.isIdenticalAddresses(target, source)); - - assertFalse(LinkPropertiesUtils.isIdenticalAllLinkAddresses(source, target)); - assertFalse(LinkPropertiesUtils.isIdenticalAllLinkAddresses(target, source)); - - // Currently, target contains V4_LINKADDR, V6_LINKADDR and testLinkAddr. - // Compare addresses.size() equals but contains different address. - target.removeLinkAddress(V4_LINKADDR); - assertEquals(source.getAddresses().size(), target.getAddresses().size()); - assertFalse(LinkPropertiesUtils.isIdenticalAddresses(source, target)); - assertFalse(LinkPropertiesUtils.isIdenticalAddresses(target, source)); - assertFalse(LinkPropertiesUtils.isIdenticalAllLinkAddresses(source, target)); - assertFalse(LinkPropertiesUtils.isIdenticalAllLinkAddresses(target, source)); - // Restore link address - target.addLinkAddress(V4_LINKADDR); - target.removeLinkAddress(testLinkAddr); - - // Compare size not equals. - target.addDnsServer(toInetAddress("75.208.10.1")); - assertFalse(LinkPropertiesUtils.isIdenticalDnses(source, target)); - assertFalse(LinkPropertiesUtils.isIdenticalDnses(target, source)); - - // Compare the same servers but target has different domains. - target.removeDnsServer(toInetAddress("75.208.10.1")); - target.setDomains("test.com"); - assertFalse(LinkPropertiesUtils.isIdenticalDnses(source, target)); - assertFalse(LinkPropertiesUtils.isIdenticalDnses(target, source)); - - // Test null domain. - target.setDomains(null); - assertFalse(LinkPropertiesUtils.isIdenticalDnses(source, target)); - assertFalse(LinkPropertiesUtils.isIdenticalDnses(target, source)); - // Restore domain - target.setDomains(TEST_DOMAIN); - - // Compare size not equals. - final RouteInfo testRoute = new RouteInfo(toInetAddress("75.208.7.1")); - target.addRoute(testRoute); - assertFalse(LinkPropertiesUtils.isIdenticalRoutes(source, target)); - assertFalse(LinkPropertiesUtils.isIdenticalRoutes(target, source)); - - // Currently, target contains RT_INFO1, RT_INFO2 and testRoute. - // Compare size equals but different routes. - target.removeRoute(RT_INFO1); - assertEquals(source.getRoutes().size(), target.getRoutes().size()); - assertFalse(LinkPropertiesUtils.isIdenticalRoutes(source, target)); - assertFalse(LinkPropertiesUtils.isIdenticalRoutes(target, source)); - // Restore route - target.addRoute(RT_INFO1); - target.removeRoute(testRoute); - - // Test different proxy. - target.setHttpProxy(ProxyInfo.buildDirectProxy("hello", 8888)); - assertFalse(LinkPropertiesUtils.isIdenticalHttpProxy(source, target)); - assertFalse(LinkPropertiesUtils.isIdenticalHttpProxy(target, source)); - - // Test null proxy. - target.setHttpProxy(null); - assertFalse(LinkPropertiesUtils.isIdenticalHttpProxy(source, target)); - assertFalse(LinkPropertiesUtils.isIdenticalHttpProxy(target, source)); - - final LinkProperties stacked = new LinkProperties(); - stacked.setInterfaceName("v4-" + target.getInterfaceName()); - stacked.addLinkAddress(testLinkAddr); - target.addStackedLink(stacked); - assertFalse(LinkPropertiesUtils.isIdenticalAllLinkAddresses(source, target)); - assertFalse(LinkPropertiesUtils.isIdenticalAllLinkAddresses(target, source)); - } - - private <T> void compareResult(List<T> oldItems, List<T> newItems, List<T> expectRemoved, - List<T> expectAdded) { - CompareResult<T> result = new CompareResult<>(oldItems, newItems); - assertEquals(new ArraySet<>(expectAdded), new ArraySet<>(result.added)); - assertEquals(new ArraySet<>(expectRemoved), (new ArraySet<>(result.removed))); - } - - @Test - public void testCompareResult() { - // Either adding or removing items - compareResult(Arrays.asList(1, 2, 3, 4), Arrays.asList(1), - Arrays.asList(2, 3, 4), new ArrayList<>()); - compareResult(Arrays.asList(1, 2), Arrays.asList(3, 2, 1, 4), - new ArrayList<>(), Arrays.asList(3, 4)); - - - // adding and removing items at the same time - compareResult(Arrays.asList(1, 2, 3, 4), Arrays.asList(2, 3, 4, 5), - Arrays.asList(1), Arrays.asList(5)); - compareResult(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6), - Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6)); - - // null cases - compareResult(Arrays.asList(1, 2, 3), null, Arrays.asList(1, 2, 3), new ArrayList<>()); - compareResult(null, Arrays.asList(3, 2, 1), new ArrayList<>(), Arrays.asList(1, 2, 3)); - compareResult(null, null, new ArrayList<>(), new ArrayList<>()); - - // Some more tests with strings - final ArrayList<String> list1 = new ArrayList<>(); - list1.add("string1"); - - final ArrayList<String> list2 = new ArrayList<>(list1); - final CompareResult<String> cr1 = new CompareResult<>(list1, list2); - assertTrue(cr1.added.isEmpty()); - assertTrue(cr1.removed.isEmpty()); - - list2.add("string2"); - final CompareResult<String> cr2 = new CompareResult<>(list1, list2); - assertEquals(Arrays.asList("string2"), cr2.added); - assertTrue(cr2.removed.isEmpty()); - - list2.remove("string1"); - final CompareResult<String> cr3 = new CompareResult<>(list1, list2); - assertEquals(Arrays.asList("string2"), cr3.added); - assertEquals(Arrays.asList("string1"), cr3.removed); - - list1.add("string2"); - final CompareResult<String> cr4 = new CompareResult<>(list1, list2); - assertTrue(cr4.added.isEmpty()); - assertEquals(Arrays.asList("string1"), cr3.removed); - } - - @Test - public void testCompareAddresses() { - final LinkProperties source = createTestObject(); - final LinkProperties target = new LinkProperties(source); - final InetAddress addr1 = toInetAddress("75.208.6.2"); - final LinkAddress linkAddr1 = new LinkAddress(addr1, 32); - - CompareResult<LinkAddress> results = LinkPropertiesUtils.compareAddresses(source, target); - assertEquals(0, results.removed.size()); - assertEquals(0, results.added.size()); - - source.addLinkAddress(linkAddr1); - results = LinkPropertiesUtils.compareAddresses(source, target); - assertEquals(1, results.removed.size()); - assertEquals(linkAddr1, results.removed.get(0)); - assertEquals(0, results.added.size()); - - final InetAddress addr2 = toInetAddress("75.208.6.3"); - final LinkAddress linkAddr2 = new LinkAddress(addr2, 32); - - target.addLinkAddress(linkAddr2); - results = LinkPropertiesUtils.compareAddresses(source, target); - assertEquals(linkAddr1, results.removed.get(0)); - assertEquals(linkAddr2, results.added.get(0)); - } - - private void assertCompareOrUpdateResult(CompareOrUpdateResult result, - List<String> expectedAdded, List<String> expectedRemoved, - List<String> expectedUpdated) { - assertSameElements(expectedAdded, result.added); - assertSameElements(expectedRemoved, result.removed); - assertSameElements(expectedUpdated, result.updated); - } - - private List<String> strArray(String... strs) { - return Arrays.asList(strs); - } - - @Test - public void testCompareOrUpdateResult() { - // As the item type, use a simple string. An item is defined to be an update of another item - // if the string starts with the same alphabetical characters. - // Extracting the key from the object is just a regexp. - Function<String, String> extractPrefix = (s) -> s.replaceFirst("^([a-z]+).*", "$1"); - assertEquals("goodbye", extractPrefix.apply("goodbye1234")); - - List<String> oldItems = strArray("hello123", "goodbye5678", "howareyou669"); - List<String> newItems = strArray("hello123", "goodbye000", "verywell"); - - final List<String> emptyList = new ArrayList<>(); - - // Items -> empty: everything removed. - CompareOrUpdateResult<String, String> result = - new CompareOrUpdateResult<String, String>(oldItems, emptyList, extractPrefix); - assertCompareOrUpdateResult(result, - emptyList, strArray("hello123", "howareyou669", "goodbye5678"), emptyList); - - // Empty -> items: everything added. - result = new CompareOrUpdateResult<String, String>(emptyList, newItems, extractPrefix); - assertCompareOrUpdateResult(result, - strArray("hello123", "goodbye000", "verywell"), emptyList, emptyList); - - // Empty -> empty: no change. - result = new CompareOrUpdateResult<String, String>(newItems, newItems, extractPrefix); - assertCompareOrUpdateResult(result, emptyList, emptyList, emptyList); - - // Added, removed, updated at the same time. - result = new CompareOrUpdateResult<>(oldItems, newItems, extractPrefix); - assertCompareOrUpdateResult(result, - strArray("verywell"), strArray("howareyou669"), strArray("goodbye000")); - - // Null -> items: everything added. - result = new CompareOrUpdateResult<String, String>(null, newItems, extractPrefix); - assertCompareOrUpdateResult(result, - strArray("hello123", "goodbye000", "verywell"), emptyList, emptyList); - - // Items -> null: everything removed. - result = new CompareOrUpdateResult<String, String>(oldItems, null, extractPrefix); - assertCompareOrUpdateResult(result, - emptyList, strArray("hello123", "howareyou669", "goodbye5678"), emptyList); - - // Null -> null: all lists empty. - result = new CompareOrUpdateResult<String, String>(null, null, extractPrefix); - assertCompareOrUpdateResult(result, emptyList, emptyList, emptyList); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/LocationPermissionCheckerTest.java b/common/tests/unit/src/com/android/net/module/util/LocationPermissionCheckerTest.java deleted file mode 100644 index 84018a52..00000000 --- a/common/tests/unit/src/com/android/net/module/util/LocationPermissionCheckerTest.java +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Copyright (C) 2020 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.net.module.util; - -import static android.Manifest.permission.NETWORK_SETTINGS; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.Manifest; -import android.app.AppOpsManager; -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.location.LocationManager; -import android.os.Binder; -import android.os.Build; -import android.os.Process; -import android.os.UserHandle; -import android.os.UserManager; - -import androidx.annotation.RequiresApi; - -import com.android.testutils.DevSdkIgnoreRule; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.util.HashMap; - -/** Unit tests for {@link LocationPermissionChecker}. */ -@RequiresApi(Build.VERSION_CODES.R) -public class LocationPermissionCheckerTest { - @Rule - public final DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule( - Build.VERSION_CODES.Q /* ignoreClassUpTo */); - - // Mock objects for testing - @Mock private Context mMockContext; - @Mock private PackageManager mMockPkgMgr; - @Mock private ApplicationInfo mMockApplInfo; - @Mock private AppOpsManager mMockAppOps; - @Mock private UserManager mMockUserManager; - @Mock private LocationManager mLocationManager; - - private static final String TEST_PKG_NAME = "com.google.somePackage"; - private static final String TEST_FEATURE_ID = "com.google.someFeature"; - private static final int MANAGED_PROFILE_UID = 1100000; - private static final int OTHER_USER_UID = 1200000; - - private final String mInteractAcrossUsersFullPermission = - "android.permission.INTERACT_ACROSS_USERS_FULL"; - private final String mManifestStringCoarse = - Manifest.permission.ACCESS_COARSE_LOCATION; - private final String mManifestStringFine = - Manifest.permission.ACCESS_FINE_LOCATION; - - // Test variables - private int mWifiScanAllowApps; - private int mUid; - private int mCoarseLocationPermission; - private int mAllowCoarseLocationApps; - private int mFineLocationPermission; - private int mAllowFineLocationApps; - private int mNetworkSettingsPermission; - private int mCurrentUid; - private boolean mIsLocationEnabled; - private boolean mThrowSecurityException; - private Answer<Integer> mReturnPermission; - private HashMap<String, Integer> mPermissionsList = new HashMap<String, Integer>(); - private LocationPermissionChecker mChecker; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - initTestVars(); - } - - private void setupMocks() throws Exception { - when(mMockPkgMgr.getApplicationInfoAsUser(eq(TEST_PKG_NAME), eq(0), any())) - .thenReturn(mMockApplInfo); - when(mMockContext.getPackageManager()).thenReturn(mMockPkgMgr); - when(mMockAppOps.noteOp(AppOpsManager.OPSTR_WIFI_SCAN, mUid, TEST_PKG_NAME, - TEST_FEATURE_ID, null)).thenReturn(mWifiScanAllowApps); - when(mMockAppOps.noteOp(eq(AppOpsManager.OPSTR_COARSE_LOCATION), eq(mUid), - eq(TEST_PKG_NAME), eq(TEST_FEATURE_ID), nullable(String.class))) - .thenReturn(mAllowCoarseLocationApps); - when(mMockAppOps.noteOp(eq(AppOpsManager.OPSTR_FINE_LOCATION), eq(mUid), - eq(TEST_PKG_NAME), eq(TEST_FEATURE_ID), nullable(String.class))) - .thenReturn(mAllowFineLocationApps); - if (mThrowSecurityException) { - doThrow(new SecurityException("Package " + TEST_PKG_NAME + " doesn't belong" - + " to application bound to user " + mUid)) - .when(mMockAppOps).checkPackage(mUid, TEST_PKG_NAME); - } - mockSystemService(Context.APP_OPS_SERVICE, AppOpsManager.class, mMockAppOps); - mockSystemService(Context.USER_SERVICE, UserManager.class, mMockUserManager); - mockSystemService(Context.LOCATION_SERVICE, LocationManager.class, mLocationManager); - } - - private <T> void mockSystemService(String name, Class<T> clazz, T service) { - when(mMockContext.getSystemService(name)).thenReturn(service); - when(mMockContext.getSystemServiceName(clazz)).thenReturn(name); - // Do not use mockito extended final method mocking - when(mMockContext.getSystemService(clazz)).thenCallRealMethod(); - } - - private void setupTestCase() throws Exception { - setupMocks(); - setupMockInterface(); - mChecker = new LocationPermissionChecker(mMockContext) { - @Override - protected int getCurrentUser() { - // Get the user ID of the process running the test rather than the foreground user - // id: ActivityManager.getCurrentUser() requires privileged permissions. - return UserHandle.getUserHandleForUid(Process.myUid()).getIdentifier(); - } - }; - } - - private void initTestVars() { - mPermissionsList.clear(); - mReturnPermission = createPermissionAnswer(); - mWifiScanAllowApps = AppOpsManager.MODE_ERRORED; - mUid = OTHER_USER_UID; - mThrowSecurityException = true; - mMockApplInfo.targetSdkVersion = Build.VERSION_CODES.M; - mIsLocationEnabled = false; - mCurrentUid = Process.myUid(); - mCoarseLocationPermission = PackageManager.PERMISSION_DENIED; - mFineLocationPermission = PackageManager.PERMISSION_DENIED; - mAllowCoarseLocationApps = AppOpsManager.MODE_ERRORED; - mAllowFineLocationApps = AppOpsManager.MODE_ERRORED; - mNetworkSettingsPermission = PackageManager.PERMISSION_DENIED; - } - - private void setupMockInterface() { - Binder.restoreCallingIdentity((((long) mUid) << 32) | Binder.getCallingPid()); - doAnswer(mReturnPermission).when(mMockContext).checkPermission( - anyString(), anyInt(), anyInt()); - when(mMockUserManager.isSameProfileGroup(UserHandle.SYSTEM, - UserHandle.getUserHandleForUid(MANAGED_PROFILE_UID))) - .thenReturn(true); - when(mMockContext.checkPermission(mManifestStringCoarse, -1, mUid)) - .thenReturn(mCoarseLocationPermission); - when(mMockContext.checkPermission(mManifestStringFine, -1, mUid)) - .thenReturn(mFineLocationPermission); - when(mMockContext.checkPermission(NETWORK_SETTINGS, -1, mUid)) - .thenReturn(mNetworkSettingsPermission); - when(mLocationManager.isLocationEnabledForUser(any())).thenReturn(mIsLocationEnabled); - } - - private Answer<Integer> createPermissionAnswer() { - return new Answer<Integer>() { - @Override - public Integer answer(InvocationOnMock invocation) { - int myUid = (int) invocation.getArguments()[1]; - String myPermission = (String) invocation.getArguments()[0]; - mPermissionsList.get(myPermission); - if (mPermissionsList.containsKey(myPermission)) { - int uid = mPermissionsList.get(myPermission); - if (myUid == uid) { - return PackageManager.PERMISSION_GRANTED; - } - } - return PackageManager.PERMISSION_DENIED; - } - }; - } - - @Test - public void testEnforceLocationPermission_HasAllPermissions_BeforeQ() throws Exception { - mIsLocationEnabled = true; - mThrowSecurityException = false; - mCoarseLocationPermission = PackageManager.PERMISSION_GRANTED; - mAllowCoarseLocationApps = AppOpsManager.MODE_ALLOWED; - mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED; - mUid = mCurrentUid; - setupTestCase(); - - final int result = - mChecker.checkLocationPermissionWithDetailInfo( - TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null); - assertEquals(LocationPermissionChecker.SUCCEEDED, result); - } - - @Test - public void testEnforceLocationPermission_HasAllPermissions_AfterQ() throws Exception { - mMockApplInfo.targetSdkVersion = Build.VERSION_CODES.Q; - mIsLocationEnabled = true; - mThrowSecurityException = false; - mUid = mCurrentUid; - mFineLocationPermission = PackageManager.PERMISSION_GRANTED; - mAllowFineLocationApps = AppOpsManager.MODE_ALLOWED; - mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED; - setupTestCase(); - - final int result = - mChecker.checkLocationPermissionWithDetailInfo( - TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null); - assertEquals(LocationPermissionChecker.SUCCEEDED, result); - } - - @Test - public void testEnforceLocationPermission_PkgNameAndUidMismatch() throws Exception { - mThrowSecurityException = true; - mIsLocationEnabled = true; - mFineLocationPermission = PackageManager.PERMISSION_GRANTED; - mAllowFineLocationApps = AppOpsManager.MODE_ALLOWED; - mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED; - setupTestCase(); - - assertThrows(SecurityException.class, - () -> mChecker.checkLocationPermissionWithDetailInfo( - TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null)); - } - - @Test - public void testenforceCanAccessScanResults_NoCoarseLocationPermission() throws Exception { - mThrowSecurityException = false; - mIsLocationEnabled = true; - setupTestCase(); - - final int result = - mChecker.checkLocationPermissionWithDetailInfo( - TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null); - assertEquals(LocationPermissionChecker.ERROR_LOCATION_PERMISSION_MISSING, result); - } - - @Test - public void testenforceCanAccessScanResults_NoFineLocationPermission() throws Exception { - mThrowSecurityException = false; - mMockApplInfo.targetSdkVersion = Build.VERSION_CODES.Q; - mIsLocationEnabled = true; - mCoarseLocationPermission = PackageManager.PERMISSION_GRANTED; - mAllowFineLocationApps = AppOpsManager.MODE_ERRORED; - mUid = MANAGED_PROFILE_UID; - setupTestCase(); - - final int result = - mChecker.checkLocationPermissionWithDetailInfo( - TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null); - assertEquals(LocationPermissionChecker.ERROR_LOCATION_PERMISSION_MISSING, result); - verify(mMockAppOps, never()).noteOp(anyInt(), anyInt(), anyString()); - } - - @Test - public void testenforceCanAccessScanResults_LocationModeDisabled() throws Exception { - mThrowSecurityException = false; - mUid = MANAGED_PROFILE_UID; - mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED; - mPermissionsList.put(mInteractAcrossUsersFullPermission, mUid); - mIsLocationEnabled = false; - - setupTestCase(); - - final int result = - mChecker.checkLocationPermissionWithDetailInfo( - TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null); - assertEquals(LocationPermissionChecker.ERROR_LOCATION_MODE_OFF, result); - } - - @Test - public void testenforceCanAccessScanResults_LocationModeDisabledHasNetworkSettings() - throws Exception { - mThrowSecurityException = false; - mIsLocationEnabled = false; - mNetworkSettingsPermission = PackageManager.PERMISSION_GRANTED; - setupTestCase(); - - final int result = - mChecker.checkLocationPermissionWithDetailInfo( - TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null); - assertEquals(LocationPermissionChecker.SUCCEEDED, result); - } - - - private static void assertThrows(Class<? extends Exception> exceptionClass, Runnable r) { - try { - r.run(); - Assert.fail("Expected " + exceptionClass + " to be thrown."); - } catch (Exception exception) { - assertTrue(exceptionClass.isInstance(exception)); - } - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/MacAddressUtilsTest.java b/common/tests/unit/src/com/android/net/module/util/MacAddressUtilsTest.java deleted file mode 100644 index 25507563..00000000 --- a/common/tests/unit/src/com/android/net/module/util/MacAddressUtilsTest.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2019 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.net.module.util; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import android.net.MacAddress; - -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -public final class MacAddressUtilsTest { - - // Matches WifiInfo.DEFAULT_MAC_ADDRESS - private static final MacAddress DEFAULT_MAC_ADDRESS = - MacAddress.fromString("02:00:00:00:00:00"); - - @Test - public void testIsMulticastAddress() { - MacAddress[] multicastAddresses = { - // broadcast address - MacAddress.fromString("ff:ff:ff:ff:ff:ff"), - MacAddress.fromString("07:00:d3:56:8a:c4"), - MacAddress.fromString("33:33:aa:bb:cc:dd"), - }; - MacAddress[] unicastAddresses = { - // all zero address - MacAddress.fromString("00:00:00:00:00:00"), - MacAddress.fromString("00:01:44:55:66:77"), - MacAddress.fromString("08:00:22:33:44:55"), - MacAddress.fromString("06:00:00:00:00:00"), - }; - - for (MacAddress mac : multicastAddresses) { - String msg = mac.toString() + " expected to be a multicast address"; - assertTrue(msg, MacAddressUtils.isMulticastAddress(mac)); - } - for (MacAddress mac : unicastAddresses) { - String msg = mac.toString() + " expected not to be a multicast address"; - assertFalse(msg, MacAddressUtils.isMulticastAddress(mac)); - } - } - - @Test - public void testMacAddressRandomGeneration() { - final int iterations = 1000; - - for (int i = 0; i < iterations; i++) { - MacAddress mac = MacAddressUtils.createRandomUnicastAddress(); - String stringRepr = mac.toString(); - - assertTrue(stringRepr + " expected to be a locally assigned address", - mac.isLocallyAssigned()); - assertEquals(MacAddress.TYPE_UNICAST, mac.getAddressType()); - assertFalse(mac.equals(DEFAULT_MAC_ADDRESS)); - } - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/NetUtilsTest.java b/common/tests/unit/src/com/android/net/module/util/NetUtilsTest.java deleted file mode 100644 index 9e635c21..00000000 --- a/common/tests/unit/src/com/android/net/module/util/NetUtilsTest.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2019 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.net.module.util; - -import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import android.net.InetAddresses; -import android.net.IpPrefix; -import android.net.RouteInfo; - -import androidx.test.runner.AndroidJUnit4; - -import com.android.testutils.DevSdkIgnoreRule; -import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.InetAddress; -import java.util.ArrayList; -import java.util.List; - -@RunWith(AndroidJUnit4.class) -public final class NetUtilsTest { - @Rule - public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule(); - - private static final InetAddress V4_ADDR1 = toInetAddress("75.208.7.1"); - private static final InetAddress V4_ADDR2 = toInetAddress("75.208.7.2"); - private static final InetAddress V6_ADDR1 = toInetAddress("2001:0db8:85a3::8a2e:0370:7334"); - private static final InetAddress V6_ADDR2 = toInetAddress("2001:0db8:85a3::8a2e:0370:7335"); - - private static final InetAddress V4_GATEWAY = toInetAddress("75.208.8.1"); - private static final InetAddress V6_GATEWAY = toInetAddress("fe80::6:0000:613"); - - private static final InetAddress V4_DEST = toInetAddress("75.208.8.15"); - private static final InetAddress V6_DEST = toInetAddress("2001:db8:cafe::123"); - - private static final RouteInfo V4_EXPECTED = new RouteInfo(new IpPrefix("75.208.8.0/24"), - V4_GATEWAY, "wlan0"); - private static final RouteInfo V6_EXPECTED = new RouteInfo(new IpPrefix("2001:db8:cafe::/64"), - V6_GATEWAY, "wlan0"); - - private static InetAddress toInetAddress(String addr) { - return InetAddresses.parseNumericAddress(addr); - } - - @Test - public void testAddressTypeMatches() { - assertTrue(NetUtils.addressTypeMatches(V4_ADDR1, V4_ADDR2)); - assertTrue(NetUtils.addressTypeMatches(V6_ADDR1, V6_ADDR2)); - assertFalse(NetUtils.addressTypeMatches(V4_ADDR1, V6_ADDR1)); - assertFalse(NetUtils.addressTypeMatches(V6_ADDR1, V4_ADDR1)); - } - - @Test - public void testSelectBestRoute() { - final List<RouteInfo> routes = new ArrayList<>(); - - RouteInfo route = NetUtils.selectBestRoute(null, V4_DEST); - assertNull(route); - route = NetUtils.selectBestRoute(routes, null); - assertNull(route); - - route = NetUtils.selectBestRoute(routes, V4_DEST); - assertNull(route); - - routes.add(V4_EXPECTED); - // "75.208.0.0/16" is not an expected result since it is not the longest prefix. - routes.add(new RouteInfo(new IpPrefix("75.208.0.0/16"), V4_GATEWAY, "wlan0")); - routes.add(new RouteInfo(new IpPrefix("75.208.7.0/24"), V4_GATEWAY, "wlan0")); - - routes.add(V6_EXPECTED); - // "2001:db8::/32" is not an expected result since it is not the longest prefix. - routes.add(new RouteInfo(new IpPrefix("2001:db8::/32"), V6_GATEWAY, "wlan0")); - routes.add(new RouteInfo(new IpPrefix("2001:db8:beef::/64"), V6_GATEWAY, "wlan0")); - - // Verify expected v4 route is selected - route = NetUtils.selectBestRoute(routes, V4_DEST); - assertEquals(V4_EXPECTED, route); - - // Verify expected v6 route is selected - route = NetUtils.selectBestRoute(routes, V6_DEST); - assertEquals(V6_EXPECTED, route); - - // Remove expected v4 route - routes.remove(V4_EXPECTED); - route = NetUtils.selectBestRoute(routes, V4_DEST); - assertNotEquals(V4_EXPECTED, route); - - // Remove expected v6 route - routes.remove(V6_EXPECTED); - route = NetUtils.selectBestRoute(routes, V4_DEST); - assertNotEquals(V6_EXPECTED, route); - } - - @Test @IgnoreUpTo(SC_V2) - public void testSelectBestRouteWithExcludedRoutes() { - final List<RouteInfo> routes = new ArrayList<>(); - - routes.add(V4_EXPECTED); - routes.add(new RouteInfo(new IpPrefix("75.208.0.0/16"), V4_GATEWAY, "wlan0")); - routes.add(new RouteInfo(new IpPrefix("75.208.7.0/24"), V4_GATEWAY, "wlan0")); - - routes.add(V6_EXPECTED); - routes.add(new RouteInfo(new IpPrefix("2001:db8::/32"), V6_GATEWAY, "wlan0")); - routes.add(new RouteInfo(new IpPrefix("2001:db8:beef::/64"), V6_GATEWAY, "wlan0")); - - // After adding excluded v4 route with longer prefix, expected result is null. - routes.add(new RouteInfo(new IpPrefix("75.208.8.0/28"), null /* gateway */, "wlan0", - RouteInfo.RTN_THROW)); - RouteInfo route = NetUtils.selectBestRoute(routes, V4_DEST); - assertNull(route); - - // After adding excluded v6 route with longer prefix, expected result is null. - routes.add(new RouteInfo(new IpPrefix("2001:db8:cafe::/96"), null /* gateway */, "wlan0", - RouteInfo.RTN_THROW)); - route = NetUtils.selectBestRoute(routes, V6_DEST); - assertNull(route); - } -} - diff --git a/common/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt b/common/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt deleted file mode 100644 index 958f45f4..00000000 --- a/common/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) 2020 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.net.module.util - -import android.annotation.TargetApi -import android.net.NetworkCapabilities -import android.net.NetworkCapabilities.NET_CAPABILITY_BIP -import android.net.NetworkCapabilities.NET_CAPABILITY_CBS -import android.net.NetworkCapabilities.NET_CAPABILITY_EIMS -import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET -import android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID -import android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH -import android.net.NetworkCapabilities.TRANSPORT_CELLULAR -import android.net.NetworkCapabilities.TRANSPORT_ETHERNET -import android.net.NetworkCapabilities.TRANSPORT_TEST -import android.net.NetworkCapabilities.TRANSPORT_VPN -import android.net.NetworkCapabilities.TRANSPORT_WIFI -import android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE -import android.os.Build -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import com.android.modules.utils.build.SdkLevel -import com.android.net.module.util.NetworkCapabilitiesUtils.RESTRICTED_CAPABILITIES -import com.android.net.module.util.NetworkCapabilitiesUtils.UNRESTRICTED_CAPABILITIES -import com.android.net.module.util.NetworkCapabilitiesUtils.getDisplayTransport -import org.junit.Test -import org.junit.runner.RunWith -import java.lang.IllegalArgumentException -import kotlin.test.assertEquals -import kotlin.test.assertFailsWith -import kotlin.test.assertFalse -import kotlin.test.assertTrue - -@RunWith(AndroidJUnit4::class) -@SmallTest -class NetworkCapabilitiesUtilsTest { - - @Test - fun testGetAccountingTransport() { - assertEquals(TRANSPORT_WIFI, getDisplayTransport(intArrayOf(TRANSPORT_WIFI))) - assertEquals(TRANSPORT_CELLULAR, getDisplayTransport(intArrayOf(TRANSPORT_CELLULAR))) - assertEquals(TRANSPORT_BLUETOOTH, getDisplayTransport(intArrayOf(TRANSPORT_BLUETOOTH))) - assertEquals(TRANSPORT_ETHERNET, getDisplayTransport(intArrayOf(TRANSPORT_ETHERNET))) - assertEquals(TRANSPORT_WIFI_AWARE, getDisplayTransport(intArrayOf(TRANSPORT_WIFI_AWARE))) - - assertEquals(TRANSPORT_VPN, getDisplayTransport( - intArrayOf(TRANSPORT_VPN, TRANSPORT_WIFI))) - assertEquals(TRANSPORT_VPN, getDisplayTransport( - intArrayOf(TRANSPORT_CELLULAR, TRANSPORT_VPN))) - - assertEquals(TRANSPORT_WIFI, getDisplayTransport( - intArrayOf(TRANSPORT_ETHERNET, TRANSPORT_WIFI))) - assertEquals(TRANSPORT_ETHERNET, getDisplayTransport( - intArrayOf(TRANSPORT_ETHERNET, TRANSPORT_TEST))) - - assertFailsWith(IllegalArgumentException::class) { - getDisplayTransport(intArrayOf()) - } - } - - // NetworkCapabilities constructor and Builder are not available until R. Mark TargetApi to - // ignore the linter error since it's used in only unit test. - @Test @TargetApi(Build.VERSION_CODES.R) - fun testInferRestrictedCapability() { - val nc = NetworkCapabilities() - // Default capabilities don't have restricted capability. - assertFalse(NetworkCapabilitiesUtils.inferRestrictedCapability(nc)) - // If there is a force restricted capability, then the network capabilities is restricted. - nc.addCapability(NET_CAPABILITY_OEM_PAID) - nc.addCapability(NET_CAPABILITY_INTERNET) - assertTrue(NetworkCapabilitiesUtils.inferRestrictedCapability(nc)) - // Except for the force restricted capability, if there is any unrestricted capability in - // capabilities, then the network capabilities is not restricted. - nc.removeCapability(NET_CAPABILITY_OEM_PAID) - nc.addCapability(NET_CAPABILITY_CBS) - assertFalse(NetworkCapabilitiesUtils.inferRestrictedCapability(nc)) - // Except for the force restricted capability, the network capabilities will only be treated - // as restricted when there is no any unrestricted capability. - nc.removeCapability(NET_CAPABILITY_INTERNET) - assertTrue(NetworkCapabilitiesUtils.inferRestrictedCapability(nc)) - if (!SdkLevel.isAtLeastS()) return - // BIP deserves its specific test because it's the first capability over 30, meaning the - // shift will overflow - nc.removeCapability(NET_CAPABILITY_CBS) - nc.addCapability(NET_CAPABILITY_BIP) - assertTrue(NetworkCapabilitiesUtils.inferRestrictedCapability(nc)) - } - - @Test - fun testRestrictedUnrestrictedCapabilities() { - // verify EIMS is restricted - assertEquals((1 shl NET_CAPABILITY_EIMS).toLong() and RESTRICTED_CAPABILITIES, - (1 shl NET_CAPABILITY_EIMS).toLong()) - - // verify CBS is also restricted - assertEquals((1 shl NET_CAPABILITY_CBS).toLong() and RESTRICTED_CAPABILITIES, - (1 shl NET_CAPABILITY_CBS).toLong()) - - // verify BIP is also restricted - // BIP is not available in R and before, but the BIP constant is inlined so - // this test can still run on R. - assertEquals((1L shl NET_CAPABILITY_BIP) and RESTRICTED_CAPABILITIES, - (1L shl NET_CAPABILITY_BIP)) - - // verify default is not restricted - assertEquals((1 shl NET_CAPABILITY_INTERNET).toLong() and RESTRICTED_CAPABILITIES, 0) - - assertTrue(RESTRICTED_CAPABILITIES > 0) - - // just to see - assertEquals(RESTRICTED_CAPABILITIES and UNRESTRICTED_CAPABILITIES, 0) - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/NetworkIdentityUtilsTest.kt b/common/tests/unit/src/com/android/net/module/util/NetworkIdentityUtilsTest.kt deleted file mode 100644 index 2904e123..00000000 --- a/common/tests/unit/src/com/android/net/module/util/NetworkIdentityUtilsTest.kt +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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.net.module.util - -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import com.android.net.module.util.NetworkIdentityUtils.scrubSubscriberId -import com.android.net.module.util.NetworkIdentityUtils.scrubSubscriberIds -import com.android.testutils.assertContainsStringsExactly -import org.junit.Test -import org.junit.runner.RunWith -import kotlin.test.assertEquals -import kotlin.test.assertNull - -@RunWith(AndroidJUnit4::class) -@SmallTest -class NetworkIdentityUtilsTest { - @Test - fun testScrubSubscriberId() { - assertEquals("123456...", scrubSubscriberId("1234567890123")) - assertEquals("123456...", scrubSubscriberId("1234567")) - assertEquals("123...", scrubSubscriberId("123")) - assertEquals("...", scrubSubscriberId("")) - assertEquals("null", scrubSubscriberId(null)) - } - - @Test - fun testScrubSubscriberIds() { - assertContainsStringsExactly(scrubSubscriberIds(arrayOf("1234567", "", null))!!, - "123456...", "...", "null") - assertContainsStringsExactly(scrubSubscriberIds(arrayOf("12345"))!!, "12345...") - assertContainsStringsExactly(scrubSubscriberIds(arrayOf())!!) - assertNull(scrubSubscriberIds(null)) - } -}
\ No newline at end of file diff --git a/common/tests/unit/src/com/android/net/module/util/NetworkStatsUtilsTest.kt b/common/tests/unit/src/com/android/net/module/util/NetworkStatsUtilsTest.kt deleted file mode 100644 index 2785ea90..00000000 --- a/common/tests/unit/src/com/android/net/module/util/NetworkStatsUtilsTest.kt +++ /dev/null @@ -1,142 +0,0 @@ -/* - * 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.net.module.util - -import android.net.NetworkStats -import android.text.TextUtils -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import org.junit.Test -import org.junit.runner.RunWith -import kotlin.test.assertEquals -import kotlin.test.assertFailsWith -import org.mockito.Mockito.doReturn -import org.mockito.Mockito.mock - -@RunWith(AndroidJUnit4::class) -@SmallTest -class NetworkStatsUtilsTest { - @Test - fun testMultiplySafeByRational() { - // Verify basic cases that the method equals to a * b / c. - assertEquals(3 * 5 / 2, NetworkStatsUtils.multiplySafeByRational(3, 5, 2)) - - // Verify input with zeros. - assertEquals(0 * 7 / 3, NetworkStatsUtils.multiplySafeByRational(0, 7, 3)) - assertEquals(7 * 0 / 3, NetworkStatsUtils.multiplySafeByRational(7, 0, 3)) - assertEquals(0 * 0 / 1, NetworkStatsUtils.multiplySafeByRational(0, 0, 1)) - assertEquals(0, NetworkStatsUtils.multiplySafeByRational(0, Long.MAX_VALUE, Long.MAX_VALUE)) - assertEquals(0, NetworkStatsUtils.multiplySafeByRational(Long.MAX_VALUE, 0, Long.MAX_VALUE)) - assertFailsWith<ArithmeticException> { - NetworkStatsUtils.multiplySafeByRational(7, 3, 0) - } - assertFailsWith<ArithmeticException> { - NetworkStatsUtils.multiplySafeByRational(0, 0, 0) - } - - // Verify cases where a * b overflows. - assertEquals(101, NetworkStatsUtils.multiplySafeByRational( - 101, Long.MAX_VALUE, Long.MAX_VALUE)) - assertEquals(721, NetworkStatsUtils.multiplySafeByRational( - Long.MAX_VALUE, 721, Long.MAX_VALUE)) - assertEquals(Long.MAX_VALUE, NetworkStatsUtils.multiplySafeByRational( - Long.MAX_VALUE, Long.MAX_VALUE, Long.MAX_VALUE)) - assertFailsWith<ArithmeticException> { - NetworkStatsUtils.multiplySafeByRational(Long.MAX_VALUE, Long.MAX_VALUE, 0) - } - } - - @Test - fun testConstrain() { - assertFailsWith<IllegalArgumentException> { - NetworkStatsUtils.constrain(5, 6, 3) // low > high - } - assertEquals(3, NetworkStatsUtils.constrain(5, 1, 3)) - assertEquals(3, NetworkStatsUtils.constrain(3, 1, 3)) - assertEquals(2, NetworkStatsUtils.constrain(2, 1, 3)) - assertEquals(1, NetworkStatsUtils.constrain(1, 1, 3)) - assertEquals(1, NetworkStatsUtils.constrain(0, 1, 3)) - - assertEquals(11, NetworkStatsUtils.constrain(15, 11, 11)) - assertEquals(11, NetworkStatsUtils.constrain(11, 11, 11)) - assertEquals(11, NetworkStatsUtils.constrain(1, 11, 11)) - } - - @Test - fun testBucketToEntry() { - val bucket = makeMockBucket(android.app.usage.NetworkStats.Bucket.UID_ALL, - android.app.usage.NetworkStats.Bucket.TAG_NONE, - android.app.usage.NetworkStats.Bucket.STATE_DEFAULT, - android.app.usage.NetworkStats.Bucket.METERED_YES, - android.app.usage.NetworkStats.Bucket.ROAMING_NO, - android.app.usage.NetworkStats.Bucket.DEFAULT_NETWORK_ALL, 1024, 8, 2048, 12) - val entry = NetworkStatsUtils.fromBucket(bucket) - val expectedEntry = NetworkStats.Entry(null /* IFACE_ALL */, NetworkStats.UID_ALL, - NetworkStats.SET_DEFAULT, NetworkStats.TAG_NONE, NetworkStats.METERED_YES, - NetworkStats.ROAMING_NO, NetworkStats.DEFAULT_NETWORK_ALL, 1024, 8, 2048, 12, - 0 /* operations */) - - // TODO: Use assertEquals once all downstreams accept null iface in - // NetworkStats.Entry#equals. - assertEntryEquals(expectedEntry, entry) - } - - private fun makeMockBucket( - uid: Int, - tag: Int, - state: Int, - metered: Int, - roaming: Int, - defaultNetwork: Int, - rxBytes: Long, - rxPackets: Long, - txBytes: Long, - txPackets: Long - ): android.app.usage.NetworkStats.Bucket { - val ret: android.app.usage.NetworkStats.Bucket = - mock(android.app.usage.NetworkStats.Bucket::class.java) - doReturn(uid).`when`(ret).getUid() - doReturn(tag).`when`(ret).getTag() - doReturn(state).`when`(ret).getState() - doReturn(metered).`when`(ret).getMetered() - doReturn(roaming).`when`(ret).getRoaming() - doReturn(defaultNetwork).`when`(ret).getDefaultNetworkStatus() - doReturn(rxBytes).`when`(ret).getRxBytes() - doReturn(rxPackets).`when`(ret).getRxPackets() - doReturn(txBytes).`when`(ret).getTxBytes() - doReturn(txPackets).`when`(ret).getTxPackets() - return ret - } - - /** - * Assert that the two {@link NetworkStats.Entry} are equals. - */ - private fun assertEntryEquals(left: NetworkStats.Entry, right: NetworkStats.Entry) { - TextUtils.equals(left.iface, right.iface) - assertEquals(left.uid, right.uid) - assertEquals(left.set, right.set) - assertEquals(left.tag, right.tag) - assertEquals(left.metered, right.metered) - assertEquals(left.roaming, right.roaming) - assertEquals(left.defaultNetwork, right.defaultNetwork) - assertEquals(left.rxBytes, right.rxBytes) - assertEquals(left.rxPackets, right.rxPackets) - assertEquals(left.txBytes, right.txBytes) - assertEquals(left.txPackets, right.txPackets) - assertEquals(left.operations, right.operations) - } -}
\ No newline at end of file diff --git a/common/tests/unit/src/com/android/net/module/util/PacketBuilderTest.java b/common/tests/unit/src/com/android/net/module/util/PacketBuilderTest.java deleted file mode 100644 index e40cd6b6..00000000 --- a/common/tests/unit/src/com/android/net/module/util/PacketBuilderTest.java +++ /dev/null @@ -1,935 +0,0 @@ -/* - * 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.net.module.util; - -import static android.system.OsConstants.IPPROTO_IP; -import static android.system.OsConstants.IPPROTO_IPV6; -import static android.system.OsConstants.IPPROTO_TCP; -import static android.system.OsConstants.IPPROTO_UDP; - -import static com.android.net.module.util.NetworkStackConstants.ETHER_TYPE_IPV4; -import static com.android.net.module.util.NetworkStackConstants.ETHER_TYPE_IPV6; -import static com.android.net.module.util.NetworkStackConstants.IPV4_HEADER_MIN_LEN; -import static com.android.net.module.util.NetworkStackConstants.TCPHDR_ACK; -import static com.android.net.module.util.NetworkStackConstants.TCP_HEADER_MIN_LEN; -import static com.android.net.module.util.NetworkStackConstants.UDP_HEADER_LEN; -import static com.android.testutils.MiscAsserts.assertThrows; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import android.net.InetAddresses; -import android.net.MacAddress; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.net.module.util.structs.EthernetHeader; -import com.android.net.module.util.structs.Ipv4Header; -import com.android.net.module.util.structs.Ipv6Header; -import com.android.net.module.util.structs.TcpHeader; -import com.android.net.module.util.structs.UdpHeader; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.io.IOException; -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.nio.ByteBuffer; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class PacketBuilderTest { - private static final MacAddress SRC_MAC = MacAddress.fromString("11:22:33:44:55:66"); - private static final MacAddress DST_MAC = MacAddress.fromString("aa:bb:cc:dd:ee:ff"); - private static final Inet4Address IPV4_SRC_ADDR = addr4("192.0.2.1"); - private static final Inet4Address IPV4_DST_ADDR = addr4("198.51.100.1"); - private static final Inet6Address IPV6_SRC_ADDR = addr6("2001:db8::1"); - private static final Inet6Address IPV6_DST_ADDR = addr6("2001:db8::2"); - private static final short SRC_PORT = 9876; - private static final short DST_PORT = 433; - private static final short SEQ_NO = 13579; - private static final short ACK_NO = 24680; - private static final byte TYPE_OF_SERVICE = 0; - private static final short ID = 27149; - private static final short FLAGS_AND_FRAGMENT_OFFSET = (short) 0x4000; // flags=DF, offset=0 - private static final byte TIME_TO_LIVE = (byte) 0x40; - private static final short WINDOW = (short) 0x2000; - private static final short URGENT_POINTER = 0; - // version=6, traffic class=0x80, flowlabel=0x515ca; - private static final int VERSION_TRAFFICCLASS_FLOWLABEL = 0x680515ca; - private static final short HOP_LIMIT = 0x40; - private static final ByteBuffer DATA = ByteBuffer.wrap(new byte[] { - (byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef - }); - - private static final byte[] TEST_PACKET_ETHERHDR_IPV4HDR_TCPHDR = - new byte[] { - // packet = (scapy.Ether(src="11:22:33:44:55:66", dst="aa:bb:cc:dd:ee:ff", - // type='IPv4') / - // scapy.IP(src="192.0.2.1", dst="198.51.100.1", - // tos=0, id=27149, flags='DF') / - // scapy.TCP(sport=9876, dport=433, seq=13579, ack=24680, - // flags='A', window=8192, urgptr=0)) - // Ether header - (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd, - (byte) 0xee, (byte) 0xff, (byte) 0x11, (byte) 0x22, - (byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66, - (byte) 0x08, (byte) 0x00, - // IPv4 header - (byte) 0x45, (byte) 0x00, (byte) 0x00, (byte) 0x28, - (byte) 0x6a, (byte) 0x0d, (byte) 0x40, (byte) 0x00, - (byte) 0x40, (byte) 0x06, (byte) 0xe4, (byte) 0x8c, - (byte) 0xc0, (byte) 0x00, (byte) 0x02, (byte) 0x01, - (byte) 0xc6, (byte) 0x33, (byte) 0x64, (byte) 0x01, - // TCP header - (byte) 0x26, (byte) 0x94, (byte) 0x01, (byte) 0xb1, - (byte) 0x00, (byte) 0x00, (byte) 0x35, (byte) 0x0b, - (byte) 0x00, (byte) 0x00, (byte) 0x60, (byte) 0x68, - (byte) 0x50, (byte) 0x10, (byte) 0x20, (byte) 0x00, - (byte) 0xe5, (byte) 0xe5, (byte) 0x00, (byte) 0x00 - }; - - private static final byte[] TEST_PACKET_ETHERHDR_IPV4HDR_TCPHDR_DATA = - new byte[] { - // packet = (scapy.Ether(src="11:22:33:44:55:66", dst="aa:bb:cc:dd:ee:ff", - // type='IPv4') / - // scapy.IP(src="192.0.2.1", dst="198.51.100.1", - // tos=0, id=27149, flags='DF') / - // scapy.TCP(sport=9876, dport=433, seq=13579, ack=24680, - // flags='A', window=8192, urgptr=0) / - // b'\xde\xad\xbe\xef') - // Ether header - (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd, - (byte) 0xee, (byte) 0xff, (byte) 0x11, (byte) 0x22, - (byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66, - (byte) 0x08, (byte) 0x00, - // IPv4 header - (byte) 0x45, (byte) 0x00, (byte) 0x00, (byte) 0x2c, - (byte) 0x6a, (byte) 0x0d, (byte) 0x40, (byte) 0x00, - (byte) 0x40, (byte) 0x06, (byte) 0xe4, (byte) 0x88, - (byte) 0xc0, (byte) 0x00, (byte) 0x02, (byte) 0x01, - (byte) 0xc6, (byte) 0x33, (byte) 0x64, (byte) 0x01, - // TCP header - (byte) 0x26, (byte) 0x94, (byte) 0x01, (byte) 0xb1, - (byte) 0x00, (byte) 0x00, (byte) 0x35, (byte) 0x0b, - (byte) 0x00, (byte) 0x00, (byte) 0x60, (byte) 0x68, - (byte) 0x50, (byte) 0x10, (byte) 0x20, (byte) 0x00, - (byte) 0x48, (byte) 0x44, (byte) 0x00, (byte) 0x00, - // Data - (byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef - }; - - private static final byte[] TEST_PACKET_IPV4HDR_TCPHDR = - new byte[] { - // packet = (scapy.IP(src="192.0.2.1", dst="198.51.100.1", - // tos=0, id=27149, flags='DF') / - // scapy.TCP(sport=9876, dport=433, seq=13579, ack=24680, - // flags='A', window=8192, urgptr=0)) - // IPv4 header - (byte) 0x45, (byte) 0x00, (byte) 0x00, (byte) 0x28, - (byte) 0x6a, (byte) 0x0d, (byte) 0x40, (byte) 0x00, - (byte) 0x40, (byte) 0x06, (byte) 0xe4, (byte) 0x8c, - (byte) 0xc0, (byte) 0x00, (byte) 0x02, (byte) 0x01, - (byte) 0xc6, (byte) 0x33, (byte) 0x64, (byte) 0x01, - // TCP header - (byte) 0x26, (byte) 0x94, (byte) 0x01, (byte) 0xb1, - (byte) 0x00, (byte) 0x00, (byte) 0x35, (byte) 0x0b, - (byte) 0x00, (byte) 0x00, (byte) 0x60, (byte) 0x68, - (byte) 0x50, (byte) 0x10, (byte) 0x20, (byte) 0x00, - (byte) 0xe5, (byte) 0xe5, (byte) 0x00, (byte) 0x00 - }; - - private static final byte[] TEST_PACKET_IPV4HDR_TCPHDR_DATA = - new byte[] { - // packet = (scapy.IP(src="192.0.2.1", dst="198.51.100.1", - // tos=0, id=27149, flags='DF') / - // scapy.TCP(sport=9876, dport=433, seq=13579, ack=24680, - // flags='A', window=8192, urgptr=0) / - // b'\xde\xad\xbe\xef') - // IPv4 header - (byte) 0x45, (byte) 0x00, (byte) 0x00, (byte) 0x2c, - (byte) 0x6a, (byte) 0x0d, (byte) 0x40, (byte) 0x00, - (byte) 0x40, (byte) 0x06, (byte) 0xe4, (byte) 0x88, - (byte) 0xc0, (byte) 0x00, (byte) 0x02, (byte) 0x01, - (byte) 0xc6, (byte) 0x33, (byte) 0x64, (byte) 0x01, - // TCP header - (byte) 0x26, (byte) 0x94, (byte) 0x01, (byte) 0xb1, - (byte) 0x00, (byte) 0x00, (byte) 0x35, (byte) 0x0b, - (byte) 0x00, (byte) 0x00, (byte) 0x60, (byte) 0x68, - (byte) 0x50, (byte) 0x10, (byte) 0x20, (byte) 0x00, - (byte) 0x48, (byte) 0x44, (byte) 0x00, (byte) 0x00, - // Data - (byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef - }; - - private static final byte[] TEST_PACKET_ETHERHDR_IPV4HDR_UDPHDR = - new byte[] { - // packet = (scapy.Ether(src="11:22:33:44:55:66", dst="aa:bb:cc:dd:ee:ff", - // type='IPv4') / - // scapy.IP(src="192.0.2.1", dst="198.51.100.1", - // tos=0, id=27149, flags='DF') / - // scapy.UDP(sport=9876, dport=433)) - // Ether header - (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd, - (byte) 0xee, (byte) 0xff, (byte) 0x11, (byte) 0x22, - (byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66, - (byte) 0x08, (byte) 0x00, - // IP header - (byte) 0x45, (byte) 0x00, (byte) 0x00, (byte) 0x1c, - (byte) 0x6a, (byte) 0x0d, (byte) 0x40, (byte) 0x00, - (byte) 0x40, (byte) 0x11, (byte) 0xe4, (byte) 0x8d, - (byte) 0xc0, (byte) 0x00, (byte) 0x02, (byte) 0x01, - (byte) 0xc6, (byte) 0x33, (byte) 0x64, (byte) 0x01, - // UDP header - (byte) 0x26, (byte) 0x94, (byte) 0x01, (byte) 0xb1, - (byte) 0x00, (byte) 0x08, (byte) 0xeb, (byte) 0x62 - }; - - private static final byte[] TEST_PACKET_ETHERHDR_IPV4HDR_UDPHDR_DATA = - new byte[] { - // packet = (scapy.Ether(src="11:22:33:44:55:66", dst="aa:bb:cc:dd:ee:ff", - // type='IPv4') / - // scapy.IP(src="192.0.2.1", dst="198.51.100.1", - // tos=0, id=27149, flags='DF') / - // scapy.UDP(sport=9876, dport=433) / - // b'\xde\xad\xbe\xef') - // Ether header - (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd, - (byte) 0xee, (byte) 0xff, (byte) 0x11, (byte) 0x22, - (byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66, - (byte) 0x08, (byte) 0x00, - // IP header - (byte) 0x45, (byte) 0x00, (byte) 0x00, (byte) 0x20, - (byte) 0x6a, (byte) 0x0d, (byte) 0x40, (byte) 0x00, - (byte) 0x40, (byte) 0x11, (byte) 0xe4, (byte) 0x89, - (byte) 0xc0, (byte) 0x00, (byte) 0x02, (byte) 0x01, - (byte) 0xc6, (byte) 0x33, (byte) 0x64, (byte) 0x01, - // UDP header - (byte) 0x26, (byte) 0x94, (byte) 0x01, (byte) 0xb1, - (byte) 0x00, (byte) 0x0c, (byte) 0x4d, (byte) 0xbd, - // Data - (byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef - }; - - private static final byte[] TEST_PACKET_IPV4HDR_UDPHDR = - new byte[] { - // packet = (scapy.IP(src="192.0.2.1", dst="198.51.100.1", - // tos=0, id=27149, flags='DF') / - // scapy.UDP(sport=9876, dport=433)) - // IP header - (byte) 0x45, (byte) 0x00, (byte) 0x00, (byte) 0x1c, - (byte) 0x6a, (byte) 0x0d, (byte) 0x40, (byte) 0x00, - (byte) 0x40, (byte) 0x11, (byte) 0xe4, (byte) 0x8d, - (byte) 0xc0, (byte) 0x00, (byte) 0x02, (byte) 0x01, - (byte) 0xc6, (byte) 0x33, (byte) 0x64, (byte) 0x01, - // UDP header - (byte) 0x26, (byte) 0x94, (byte) 0x01, (byte) 0xb1, - (byte) 0x00, (byte) 0x08, (byte) 0xeb, (byte) 0x62 - }; - - private static final byte[] TEST_PACKET_IPV4HDR_UDPHDR_DATA = - new byte[] { - // packet = (scapy.IP(src="192.0.2.1", dst="198.51.100.1", - // tos=0, id=27149, flags='DF') / - // scapy.UDP(sport=9876, dport=433) / - // b'\xde\xad\xbe\xef') - // IP header - (byte) 0x45, (byte) 0x00, (byte) 0x00, (byte) 0x20, - (byte) 0x6a, (byte) 0x0d, (byte) 0x40, (byte) 0x00, - (byte) 0x40, (byte) 0x11, (byte) 0xe4, (byte) 0x89, - (byte) 0xc0, (byte) 0x00, (byte) 0x02, (byte) 0x01, - (byte) 0xc6, (byte) 0x33, (byte) 0x64, (byte) 0x01, - // UDP header - (byte) 0x26, (byte) 0x94, (byte) 0x01, (byte) 0xb1, - (byte) 0x00, (byte) 0x0c, (byte) 0x4d, (byte) 0xbd, - // Data - (byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef - }; - - private static final byte[] TEST_PACKET_ETHERHDR_IPV6HDR_UDPHDR = - new byte[] { - // packet = (scapy.Ether(src="11:22:33:44:55:66", dst="aa:bb:cc:dd:ee:ff", - // type='IPv6') / - // scapy.IPv6(src="2001:db8::1", dst="2001:db8::2", tc=0x80, - // fl=0x515ca, hlim=0x40) / - // scapy.UDP(sport=9876, dport=433)) - // Ether header - (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd, - (byte) 0xee, (byte) 0xff, (byte) 0x11, (byte) 0x22, - (byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66, - (byte) 0x86, (byte) 0xdd, - // IP header - (byte) 0x68, (byte) 0x05, (byte) 0x15, (byte) 0xca, - (byte) 0x00, (byte) 0x08, (byte) 0x11, (byte) 0x40, - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, - // UDP header - (byte) 0x26, (byte) 0x94, (byte) 0x01, (byte) 0xb1, - (byte) 0x00, (byte) 0x08, (byte) 0x7c, (byte) 0x24 - }; - - private static final byte[] TEST_PACKET_ETHERHDR_IPV6HDR_UDPHDR_DATA = - new byte[] { - // packet = (scapy.Ether(src="11:22:33:44:55:66", dst="aa:bb:cc:dd:ee:ff", - // type='IPv6') / - // scapy.IPv6(src="2001:db8::1", dst="2001:db8::2", tc=0x80, - // fl=0x515ca, hlim=0x40) / - // scapy.UDP(sport=9876, dport=433) / - // b'\xde\xad\xbe\xef') - // Ether header - (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd, - (byte) 0xee, (byte) 0xff, (byte) 0x11, (byte) 0x22, - (byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66, - (byte) 0x86, (byte) 0xdd, - // IP header - (byte) 0x68, (byte) 0x05, (byte) 0x15, (byte) 0xca, - (byte) 0x00, (byte) 0x0c, (byte) 0x11, (byte) 0x40, - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, - // UDP header - (byte) 0x26, (byte) 0x94, (byte) 0x01, (byte) 0xb1, - (byte) 0x00, (byte) 0x0c, (byte) 0xde, (byte) 0x7e, - // Data - (byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef - }; - - private static final byte[] TEST_PACKET_ETHERHDR_IPV6HDR_TCPHDR_DATA = - new byte[] { - // packet = (scapy.Ether(src="11:22:33:44:55:66", dst="aa:bb:cc:dd:ee:ff", - // type='IPv6') / - // scapy.IPv6(src="2001:db8::1", dst="2001:db8::2", tc=0x80, - // fl=0x515ca, hlim=0x40) / - // scapy.TCP(sport=9876, dport=433, seq=13579, ack=24680, - // flags='A', window=8192, urgptr=0) / - // b'\xde\xad\xbe\xef') - // Ether header - (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd, - (byte) 0xee, (byte) 0xff, (byte) 0x11, (byte) 0x22, - (byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66, - (byte) 0x86, (byte) 0xdd, - // IPv6 header - (byte) 0x68, (byte) 0x05, (byte) 0x15, (byte) 0xca, - (byte) 0x00, (byte) 0x18, (byte) 0x06, (byte) 0x40, - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, - // TCP header - (byte) 0x26, (byte) 0x94, (byte) 0x01, (byte) 0xb1, - (byte) 0x00, (byte) 0x00, (byte) 0x35, (byte) 0x0b, - (byte) 0x00, (byte) 0x00, (byte) 0x60, (byte) 0x68, - (byte) 0x50, (byte) 0x10, (byte) 0x20, (byte) 0x00, - (byte) 0xd9, (byte) 0x05, (byte) 0x00, (byte) 0x00, - // Data - (byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef - }; - - private static final byte[] TEST_PACKET_ETHERHDR_IPV6HDR_TCPHDR = - new byte[] { - // packet = (scapy.Ether(src="11:22:33:44:55:66", dst="aa:bb:cc:dd:ee:ff", - // type='IPv6') / - // scapy.IPv6(src="2001:db8::1", dst="2001:db8::2", tc=0x80, - // fl=0x515ca, hlim=0x40) / - // scapy.TCP(sport=9876, dport=433, seq=13579, ack=24680, - // flags='A', window=8192, urgptr=0)) - // Ether header - (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd, - (byte) 0xee, (byte) 0xff, (byte) 0x11, (byte) 0x22, - (byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66, - (byte) 0x86, (byte) 0xdd, - // IPv6 header - (byte) 0x68, (byte) 0x05, (byte) 0x15, (byte) 0xca, - (byte) 0x00, (byte) 0x14, (byte) 0x06, (byte) 0x40, - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, - // TCP header - (byte) 0x26, (byte) 0x94, (byte) 0x01, (byte) 0xb1, - (byte) 0x00, (byte) 0x00, (byte) 0x35, (byte) 0x0b, - (byte) 0x00, (byte) 0x00, (byte) 0x60, (byte) 0x68, - (byte) 0x50, (byte) 0x10, (byte) 0x20, (byte) 0x00, - (byte) 0x76, (byte) 0xa7, (byte) 0x00, (byte) 0x00 - }; - - private static final byte[] TEST_PACKET_IPV6HDR_TCPHDR_DATA = - new byte[] { - // packet = (scapy.IPv6(src="2001:db8::1", dst="2001:db8::2", tc=0x80, - // fl=0x515ca, hlim=0x40) / - // scapy.TCP(sport=9876, dport=433, seq=13579, ack=24680, - // flags='A', window=8192, urgptr=0) / - // b'\xde\xad\xbe\xef') - // IPv6 header - (byte) 0x68, (byte) 0x05, (byte) 0x15, (byte) 0xca, - (byte) 0x00, (byte) 0x18, (byte) 0x06, (byte) 0x40, - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, - // TCP header - (byte) 0x26, (byte) 0x94, (byte) 0x01, (byte) 0xb1, - (byte) 0x00, (byte) 0x00, (byte) 0x35, (byte) 0x0b, - (byte) 0x00, (byte) 0x00, (byte) 0x60, (byte) 0x68, - (byte) 0x50, (byte) 0x10, (byte) 0x20, (byte) 0x00, - (byte) 0xd9, (byte) 0x05, (byte) 0x00, (byte) 0x00, - // Data - (byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef - }; - - private static final byte[] TEST_PACKET_IPV6HDR_TCPHDR = - new byte[] { - // packet = (scapy.IPv6(src="2001:db8::1", dst="2001:db8::2", tc=0x80, - // fl=0x515ca, hlim=0x40) / - // scapy.TCP(sport=9876, dport=433, seq=13579, ack=24680, - // flags='A', window=8192, urgptr=0)) - // IPv6 header - (byte) 0x68, (byte) 0x05, (byte) 0x15, (byte) 0xca, - (byte) 0x00, (byte) 0x14, (byte) 0x06, (byte) 0x40, - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, - // TCP header - (byte) 0x26, (byte) 0x94, (byte) 0x01, (byte) 0xb1, - (byte) 0x00, (byte) 0x00, (byte) 0x35, (byte) 0x0b, - (byte) 0x00, (byte) 0x00, (byte) 0x60, (byte) 0x68, - (byte) 0x50, (byte) 0x10, (byte) 0x20, (byte) 0x00, - (byte) 0x76, (byte) 0xa7, (byte) 0x00, (byte) 0x00 - }; - - private static final byte[] TEST_PACKET_IPV6HDR_UDPHDR = - new byte[] { - // packet = (scapy.IPv6(src="2001:db8::1", dst="2001:db8::2", tc=0x80, - // fl=0x515ca, hlim=0x40) / - // scapy.UDP(sport=9876, dport=433)) - // IP header - (byte) 0x68, (byte) 0x05, (byte) 0x15, (byte) 0xca, - (byte) 0x00, (byte) 0x08, (byte) 0x11, (byte) 0x40, - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, - // UDP header - (byte) 0x26, (byte) 0x94, (byte) 0x01, (byte) 0xb1, - (byte) 0x00, (byte) 0x08, (byte) 0x7c, (byte) 0x24 - }; - - private static final byte[] TEST_PACKET_IPV6HDR_UDPHDR_DATA = - new byte[] { - // packet = (scapy.IPv6(src="2001:db8::1", dst="2001:db8::2", tc=0x80, - // fl=0x515ca, hlim=0x40) / - // scapy.UDP(sport=9876, dport=433) / - // b'\xde\xad\xbe\xef') - // IP header - (byte) 0x68, (byte) 0x05, (byte) 0x15, (byte) 0xca, - (byte) 0x00, (byte) 0x0c, (byte) 0x11, (byte) 0x40, - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, - // UDP header - (byte) 0x26, (byte) 0x94, (byte) 0x01, (byte) 0xb1, - (byte) 0x00, (byte) 0x0c, (byte) 0xde, (byte) 0x7e, - // Data - (byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef - }; - - /** - * Build a packet which has ether header, IP header, TCP/UDP header and data. - * The ethernet header and data are optional. Note that both source mac address and - * destination mac address are required for ethernet header. - * - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Layer 2 header (EthernetHeader) | (optional) - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Layer 3 header (Ipv4Header, Ipv6Header) | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Layer 4 header (TcpHeader, UdpHeader) | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Payload | (optional) - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * - * @param srcMac source MAC address. used by L2 ether header. - * @param dstMac destination MAC address. used by L2 ether header. - * @param l3proto the layer 3 protocol. Only {@code IPPROTO_IP} and {@code IPPROTO_IPV6} - * currently supported. - * @param l4proto the layer 4 protocol. Only {@code IPPROTO_TCP} and {@code IPPROTO_UDP} - * currently supported. - * @param payload the payload. - */ - @NonNull - private ByteBuffer buildPacket(@Nullable final MacAddress srcMac, - @Nullable final MacAddress dstMac, final int l3proto, final int l4proto, - @Nullable final ByteBuffer payload) - throws Exception { - if (l3proto != IPPROTO_IP && l3proto != IPPROTO_IPV6) { - fail("Unsupported layer 3 protocol " + l3proto); - } - - if (l4proto != IPPROTO_TCP && l4proto != IPPROTO_UDP) { - fail("Unsupported layer 4 protocol " + l4proto); - } - - final boolean hasEther = (srcMac != null && dstMac != null); - final int payloadLen = (payload == null) ? 0 : payload.limit(); - final ByteBuffer buffer = PacketBuilder.allocate(hasEther, l3proto, l4proto, - payloadLen); - final PacketBuilder packetBuilder = new PacketBuilder(buffer); - - // [1] Build ether header. - if (hasEther) { - final int etherType = (l3proto == IPPROTO_IP) ? ETHER_TYPE_IPV4 : ETHER_TYPE_IPV6; - packetBuilder.writeL2Header(srcMac, dstMac, (short) etherType); - } - - // [2] Build IP header. - if (l3proto == IPPROTO_IP) { - packetBuilder.writeIpv4Header(TYPE_OF_SERVICE, ID, FLAGS_AND_FRAGMENT_OFFSET, - TIME_TO_LIVE, (byte) l4proto, IPV4_SRC_ADDR, IPV4_DST_ADDR); - } else if (l3proto == IPPROTO_IPV6) { - packetBuilder.writeIpv6Header(VERSION_TRAFFICCLASS_FLOWLABEL, - (byte) l4proto, HOP_LIMIT, IPV6_SRC_ADDR, IPV6_DST_ADDR); - } - - // [3] Build TCP or UDP header. - if (l4proto == IPPROTO_TCP) { - packetBuilder.writeTcpHeader(SRC_PORT, DST_PORT, SEQ_NO, ACK_NO, - TCPHDR_ACK, WINDOW, URGENT_POINTER); - } else if (l4proto == IPPROTO_UDP) { - packetBuilder.writeUdpHeader(SRC_PORT, DST_PORT); - } - - // [4] Build payload. - if (payload != null) { - buffer.put(payload); - // in case data might be reused by caller, restore the position and - // limit of bytebuffer. - payload.clear(); - } - - return packetBuilder.finalizePacket(); - } - - /** - * Check ethernet header. - * - * @param l3proto the layer 3 protocol. Only {@code IPPROTO_IP} and {@code IPPROTO_IPV6} - * currently supported. - * @param actual the packet to check. - */ - private void checkEtherHeader(final int l3proto, final ByteBuffer actual) { - if (l3proto != IPPROTO_IP && l3proto != IPPROTO_IPV6) { - fail("Unsupported layer 3 protocol " + l3proto); - } - - final EthernetHeader eth = Struct.parse(EthernetHeader.class, actual); - assertEquals(SRC_MAC, eth.srcMac); - assertEquals(DST_MAC, eth.dstMac); - final int expectedEtherType = (l3proto == IPPROTO_IP) ? ETHER_TYPE_IPV4 : ETHER_TYPE_IPV6; - assertEquals(expectedEtherType, eth.etherType); - } - - /** - * Check IPv4 header. - * - * @param l4proto the layer 4 protocol. Only {@code IPPROTO_TCP} and {@code IPPROTO_UDP} - * currently supported. - * @param hasData true if the packet has data payload; false otherwise. - * @param actual the packet to check. - */ - private void checkIpv4Header(final int l4proto, final boolean hasData, - final ByteBuffer actual) { - if (l4proto != IPPROTO_TCP && l4proto != IPPROTO_UDP) { - fail("Unsupported layer 4 protocol " + l4proto); - } - - final Ipv4Header ipv4Header = Struct.parse(Ipv4Header.class, actual); - assertEquals(Ipv4Header.IPHDR_VERSION_IHL, ipv4Header.vi); - assertEquals(TYPE_OF_SERVICE, ipv4Header.tos); - assertEquals(ID, ipv4Header.id); - assertEquals(FLAGS_AND_FRAGMENT_OFFSET, ipv4Header.flagsAndFragmentOffset); - assertEquals(TIME_TO_LIVE, ipv4Header.ttl); - assertEquals(IPV4_SRC_ADDR, ipv4Header.srcIp); - assertEquals(IPV4_DST_ADDR, ipv4Header.dstIp); - - final int dataLength = hasData ? DATA.limit() : 0; - if (l4proto == IPPROTO_TCP) { - assertEquals(IPV4_HEADER_MIN_LEN + TCP_HEADER_MIN_LEN + dataLength, - ipv4Header.totalLength); - assertEquals((byte) IPPROTO_TCP, ipv4Header.protocol); - assertEquals(hasData ? (short) 0xe488 : (short) 0xe48c, ipv4Header.checksum); - } else if (l4proto == IPPROTO_UDP) { - assertEquals(IPV4_HEADER_MIN_LEN + UDP_HEADER_LEN + dataLength, - ipv4Header.totalLength); - assertEquals((byte) IPPROTO_UDP, ipv4Header.protocol); - assertEquals(hasData ? (short) 0xe489 : (short) 0xe48d, ipv4Header.checksum); - } - } - - /** - * Check IPv6 header. - * - * @param l4proto the layer 4 protocol. Only {@code IPPROTO_TCP} and {@code IPPROTO_UDP} - * currently supported. - * @param hasData true if the packet has data payload; false otherwise. - * @param actual the packet to check. - */ - private void checkIpv6Header(final int l4proto, final boolean hasData, - final ByteBuffer actual) { - if (l4proto != IPPROTO_TCP && l4proto != IPPROTO_UDP) { - fail("Unsupported layer 4 protocol " + l4proto); - } - - final Ipv6Header ipv6Header = Struct.parse(Ipv6Header.class, actual); - - assertEquals(VERSION_TRAFFICCLASS_FLOWLABEL, ipv6Header.vtf); - assertEquals(HOP_LIMIT, ipv6Header.hopLimit); - assertEquals(IPV6_SRC_ADDR, ipv6Header.srcIp); - assertEquals(IPV6_DST_ADDR, ipv6Header.dstIp); - - final int dataLength = hasData ? DATA.limit() : 0; - if (l4proto == IPPROTO_TCP) { - assertEquals(TCP_HEADER_MIN_LEN + dataLength, ipv6Header.payloadLength); - assertEquals((byte) IPPROTO_TCP, ipv6Header.nextHeader); - } else if (l4proto == IPPROTO_UDP) { - assertEquals(UDP_HEADER_LEN + dataLength, ipv6Header.payloadLength); - assertEquals((byte) IPPROTO_UDP, ipv6Header.nextHeader); - } - } - - /** - * Check TCP packet. - * - * @param hasEther true if the packet has ether header; false otherwise. - * @param l3proto the layer 3 protocol. Only {@code IPPROTO_IP} and {@code IPPROTO_IPV6} - * currently supported. - * @param hasData true if the packet has data payload; false otherwise. - * @param actual the packet to check. - */ - private void checkTcpPacket(final boolean hasEther, final int l3proto, final boolean hasData, - final ByteBuffer actual) { - if (l3proto != IPPROTO_IP && l3proto != IPPROTO_IPV6) { - fail("Unsupported layer 3 protocol " + l3proto); - } - - // [1] Check ether header. - if (hasEther) { - checkEtherHeader(l3proto, actual); - } - - // [2] Check IP header. - if (l3proto == IPPROTO_IP) { - checkIpv4Header(IPPROTO_TCP, hasData, actual); - } else if (l3proto == IPPROTO_IPV6) { - checkIpv6Header(IPPROTO_TCP, hasData, actual); - } - - // [3] Check TCP header. - final TcpHeader tcpHeader = Struct.parse(TcpHeader.class, actual); - assertEquals(SRC_PORT, tcpHeader.srcPort); - assertEquals(DST_PORT, tcpHeader.dstPort); - assertEquals(SEQ_NO, tcpHeader.seq); - assertEquals(ACK_NO, tcpHeader.ack); - assertEquals((short) 0x5010 /* offset=5(*4bytes), control bits=ACK */, - tcpHeader.dataOffsetAndControlBits); - assertEquals(WINDOW, tcpHeader.window); - assertEquals(URGENT_POINTER, tcpHeader.urgentPointer); - if (l3proto == IPPROTO_IP) { - assertEquals(hasData ? (short) 0x4844 : (short) 0xe5e5, tcpHeader.checksum); - } else if (l3proto == IPPROTO_IPV6) { - assertEquals(hasData ? (short) 0xd905 : (short) 0x76a7, tcpHeader.checksum); - } - - // [4] Check payload. - if (hasData) { - assertEquals(0xdeadbeef, actual.getInt()); - } - } - - /** - * Check UDP packet. - * - * @param hasEther true if the packet has ether header; false otherwise. - * @param l3proto the layer 3 protocol. Only {@code IPPROTO_IP} and {@code IPPROTO_IPV6} - * currently supported. - * @param hasData true if the packet has data payload; false otherwise. - * @param actual the packet to check. - */ - private void checkUdpPacket(final boolean hasEther, final int l3proto, final boolean hasData, - final ByteBuffer actual) { - if (l3proto != IPPROTO_IP && l3proto != IPPROTO_IPV6) { - fail("Unsupported layer 3 protocol " + l3proto); - } - - // [1] Check ether header. - if (hasEther) { - checkEtherHeader(l3proto, actual); - } - - // [2] Check IP header. - if (l3proto == IPPROTO_IP) { - checkIpv4Header(IPPROTO_UDP, hasData, actual); - } else if (l3proto == IPPROTO_IPV6) { - checkIpv6Header(IPPROTO_UDP, hasData, actual); - } - - // [3] Check UDP header. - final UdpHeader udpHeader = Struct.parse(UdpHeader.class, actual); - assertEquals(SRC_PORT, udpHeader.srcPort); - assertEquals(DST_PORT, udpHeader.dstPort); - final int dataLength = hasData ? DATA.limit() : 0; - assertEquals(UDP_HEADER_LEN + dataLength, udpHeader.length); - if (l3proto == IPPROTO_IP) { - assertEquals(hasData ? (short) 0x4dbd : (short) 0xeb62, udpHeader.checksum); - } else if (l3proto == IPPROTO_IPV6) { - assertEquals(hasData ? (short) 0xde7e : (short) 0x7c24, udpHeader.checksum); - } - - // [4] Check payload. - if (hasData) { - assertEquals(0xdeadbeef, actual.getInt()); - } - } - - @Test - public void testBuildPacketEtherIPv4Tcp() throws Exception { - final ByteBuffer packet = buildPacket(SRC_MAC, DST_MAC, IPPROTO_IP, IPPROTO_TCP, - null /* data */); - checkTcpPacket(true /* hasEther */, IPPROTO_IP, false /* hasData */, packet); - assertArrayEquals(TEST_PACKET_ETHERHDR_IPV4HDR_TCPHDR, packet.array()); - } - - @Test - public void testBuildPacketEtherIPv4TcpData() throws Exception { - final ByteBuffer packet = buildPacket(SRC_MAC, DST_MAC, IPPROTO_IP, IPPROTO_TCP, DATA); - checkTcpPacket(true /* hasEther */, IPPROTO_IP, true /* hasData */, packet); - assertArrayEquals(TEST_PACKET_ETHERHDR_IPV4HDR_TCPHDR_DATA, - packet.array()); - } - - @Test - public void testBuildPacketIPv4Tcp() throws Exception { - final ByteBuffer packet = buildPacket(null /* srcMac */, null /* dstMac */, - IPPROTO_IP, IPPROTO_TCP, null /* data */); - checkTcpPacket(false /* hasEther */, IPPROTO_IP, false /* hasData */, packet); - assertArrayEquals(TEST_PACKET_IPV4HDR_TCPHDR, packet.array()); - } - - @Test - public void testBuildPacketIPv4TcpData() throws Exception { - final ByteBuffer packet = buildPacket(null /* srcMac */, null /* dstMac */, - IPPROTO_IP, IPPROTO_TCP, DATA); - checkTcpPacket(false /* hasEther */, IPPROTO_IP, true /* hasData */, packet); - assertArrayEquals(TEST_PACKET_IPV4HDR_TCPHDR_DATA, packet.array()); - } - - @Test - public void testBuildPacketEtherIPv4Udp() throws Exception { - final ByteBuffer packet = buildPacket(SRC_MAC, DST_MAC, IPPROTO_IP, IPPROTO_UDP, - null /* data */); - checkUdpPacket(true /* hasEther */, IPPROTO_IP, false /* hasData */, packet); - assertArrayEquals(TEST_PACKET_ETHERHDR_IPV4HDR_UDPHDR, packet.array()); - } - - @Test - public void testBuildPacketEtherIPv4UdpData() throws Exception { - final ByteBuffer packet = buildPacket(SRC_MAC, DST_MAC, IPPROTO_IP, IPPROTO_UDP, DATA); - checkUdpPacket(true /* hasEther */, IPPROTO_IP, true /* hasData */, packet); - assertArrayEquals(TEST_PACKET_ETHERHDR_IPV4HDR_UDPHDR_DATA, packet.array()); - } - - @Test - public void testBuildPacketIPv4Udp() throws Exception { - final ByteBuffer packet = buildPacket(null /* srcMac */, null /* dstMac */, - IPPROTO_IP, IPPROTO_UDP, null /*data*/); - checkUdpPacket(false /* hasEther */, IPPROTO_IP, false /* hasData */, packet); - assertArrayEquals(TEST_PACKET_IPV4HDR_UDPHDR, packet.array()); - } - - @Test - public void testBuildPacketIPv4UdpData() throws Exception { - final ByteBuffer packet = buildPacket(null /* srcMac */, null /* dstMac */, - IPPROTO_IP, IPPROTO_UDP, DATA); - checkUdpPacket(false /* hasEther */, IPPROTO_IP, true /* hasData */, packet); - assertArrayEquals(TEST_PACKET_IPV4HDR_UDPHDR_DATA, packet.array()); - } - - @Test - public void testBuildPacketEtherIPv6TcpData() throws Exception { - final ByteBuffer packet = buildPacket(SRC_MAC, DST_MAC, IPPROTO_IPV6, IPPROTO_TCP, DATA); - checkTcpPacket(true /* hasEther */, IPPROTO_IPV6, true /* hasData */, packet); - assertArrayEquals(TEST_PACKET_ETHERHDR_IPV6HDR_TCPHDR_DATA, - packet.array()); - } - - @Test - public void testBuildPacketEtherIPv6Tcp() throws Exception { - final ByteBuffer packet = buildPacket(SRC_MAC, DST_MAC, IPPROTO_IPV6, IPPROTO_TCP, - null /*data*/); - checkTcpPacket(true /* hasEther */, IPPROTO_IPV6, false /* hasData */, packet); - assertArrayEquals(TEST_PACKET_ETHERHDR_IPV6HDR_TCPHDR, - packet.array()); - } - - @Test - public void testBuildPacketIPv6TcpData() throws Exception { - final ByteBuffer packet = buildPacket(null /* srcMac */, null /* dstMac */, IPPROTO_IPV6, - IPPROTO_TCP, DATA); - checkTcpPacket(false /* hasEther */, IPPROTO_IPV6, true /* hasData */, packet); - assertArrayEquals(TEST_PACKET_IPV6HDR_TCPHDR_DATA, packet.array()); - } - - @Test - public void testBuildPacketIPv6Tcp() throws Exception { - final ByteBuffer packet = buildPacket(null /* srcMac */, null /* dstMac */, IPPROTO_IPV6, - IPPROTO_TCP, null /*data*/); - checkTcpPacket(false /* hasEther */, IPPROTO_IPV6, false /* hasData */, packet); - assertArrayEquals(TEST_PACKET_IPV6HDR_TCPHDR, packet.array()); - } - - @Test - public void testBuildPacketEtherIPv6Udp() throws Exception { - final ByteBuffer packet = buildPacket(SRC_MAC, DST_MAC, IPPROTO_IPV6, IPPROTO_UDP, - null /* data */); - checkUdpPacket(true /* hasEther */, IPPROTO_IPV6, false /* hasData */, packet); - assertArrayEquals(TEST_PACKET_ETHERHDR_IPV6HDR_UDPHDR, packet.array()); - } - - @Test - public void testBuildPacketEtherIPv6UdpData() throws Exception { - final ByteBuffer packet = buildPacket(SRC_MAC, DST_MAC, IPPROTO_IPV6, IPPROTO_UDP, - DATA); - checkUdpPacket(true /* hasEther */, IPPROTO_IPV6, true /* hasData */, packet); - assertArrayEquals(TEST_PACKET_ETHERHDR_IPV6HDR_UDPHDR_DATA, packet.array()); - } - - @Test - public void testBuildPacketIPv6Udp() throws Exception { - final ByteBuffer packet = buildPacket(null /* srcMac */, null /* dstMac */, - IPPROTO_IPV6, IPPROTO_UDP, null /*data*/); - checkUdpPacket(false /* hasEther */, IPPROTO_IPV6, false /* hasData */, packet); - assertArrayEquals(TEST_PACKET_IPV6HDR_UDPHDR, packet.array()); - } - - @Test - public void testBuildPacketIPv6UdpData() throws Exception { - final ByteBuffer packet = buildPacket(null /* srcMac */, null /* dstMac */, - IPPROTO_IPV6, IPPROTO_UDP, DATA); - checkUdpPacket(false /* hasEther */, IPPROTO_IPV6, true /* hasData */, packet); - assertArrayEquals(TEST_PACKET_IPV6HDR_UDPHDR_DATA, packet.array()); - } - - @Test - public void testFinalizePacketWithoutIpv4Header() throws Exception { - final ByteBuffer buffer = PacketBuilder.allocate(false /* hasEther */, IPPROTO_IP, - IPPROTO_TCP, 0 /* payloadLen */); - final PacketBuilder packetBuilder = new PacketBuilder(buffer); - packetBuilder.writeTcpHeader(SRC_PORT, DST_PORT, SEQ_NO, ACK_NO, - TCPHDR_ACK, WINDOW, URGENT_POINTER); - assertThrows("java.io.IOException: Packet is missing IPv4 header", IOException.class, - () -> packetBuilder.finalizePacket()); - } - - @Test - public void testFinalizePacketWithoutL4Header() throws Exception { - final ByteBuffer buffer = PacketBuilder.allocate(false /* hasEther */, IPPROTO_IP, - IPPROTO_TCP, 0 /* payloadLen */); - final PacketBuilder packetBuilder = new PacketBuilder(buffer); - packetBuilder.writeIpv4Header(TYPE_OF_SERVICE, ID, FLAGS_AND_FRAGMENT_OFFSET, - TIME_TO_LIVE, (byte) IPPROTO_TCP, IPV4_SRC_ADDR, IPV4_DST_ADDR); - assertThrows("java.io.IOException: Packet is missing neither TCP nor UDP header", - IOException.class, () -> packetBuilder.finalizePacket()); - } - - @Test - public void testWriteL2HeaderToInsufficientBuffer() throws Exception { - final PacketBuilder packetBuilder = new PacketBuilder(ByteBuffer.allocate(1)); - assertThrows(IOException.class, - () -> packetBuilder.writeL2Header(SRC_MAC, DST_MAC, (short) ETHER_TYPE_IPV4)); - } - - @Test - public void testWriteIpv4HeaderToInsufficientBuffer() throws Exception { - final PacketBuilder packetBuilder = new PacketBuilder(ByteBuffer.allocate(1)); - assertThrows(IOException.class, - () -> packetBuilder.writeIpv4Header(TYPE_OF_SERVICE, ID, FLAGS_AND_FRAGMENT_OFFSET, - TIME_TO_LIVE, (byte) IPPROTO_TCP, IPV4_SRC_ADDR, IPV4_DST_ADDR)); - } - - @Test - public void testWriteTcpHeaderToInsufficientBuffer() throws Exception { - final PacketBuilder packetBuilder = new PacketBuilder(ByteBuffer.allocate(1)); - assertThrows(IOException.class, - () -> packetBuilder.writeTcpHeader(SRC_PORT, DST_PORT, SEQ_NO, ACK_NO, - TCPHDR_ACK, WINDOW, URGENT_POINTER)); - } - - @Test - public void testWriteUdpHeaderToInsufficientBuffer() throws Exception { - final PacketBuilder packetBuilder = new PacketBuilder(ByteBuffer.allocate(1)); - assertThrows(IOException.class, () -> packetBuilder.writeUdpHeader(SRC_PORT, DST_PORT)); - } - - private static Inet4Address addr4(String addr) { - return (Inet4Address) InetAddresses.parseNumericAddress(addr); - } - - private static Inet6Address addr6(String addr) { - return (Inet6Address) InetAddresses.parseNumericAddress(addr); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/PacketReaderTest.java b/common/tests/unit/src/com/android/net/module/util/PacketReaderTest.java deleted file mode 100644 index 459801c2..00000000 --- a/common/tests/unit/src/com/android/net/module/util/PacketReaderTest.java +++ /dev/null @@ -1,245 +0,0 @@ -/* - * 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.net.module.util; - -import static android.system.OsConstants.AF_INET6; -import static android.system.OsConstants.IPPROTO_UDP; -import static android.system.OsConstants.SOCK_DGRAM; -import static android.system.OsConstants.SOCK_NONBLOCK; -import static android.system.OsConstants.SOL_SOCKET; -import static android.system.OsConstants.SO_SNDTIMEO; - -import static com.android.net.module.util.PacketReader.DEFAULT_RECV_BUF_SIZE; -import static com.android.testutils.MiscAsserts.assertThrows; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import android.os.Handler; -import android.os.HandlerThread; -import android.system.ErrnoException; -import android.system.Os; -import android.system.StructTimeval; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.io.FileDescriptor; -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.SocketException; -import java.util.Arrays; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -/** - * Tests for PacketReader. - * - * @hide - */ -@RunWith(AndroidJUnit4.class) -@SmallTest -public class PacketReaderTest { - static final InetAddress LOOPBACK6 = Inet6Address.getLoopbackAddress(); - static final StructTimeval TIMEO = StructTimeval.fromMillis(500); - - // TODO : reassigning the latch voids its synchronization properties, which means this - // scheme just doesn't work. Latches almost always need to be final to work. - protected CountDownLatch mLatch; - protected FileDescriptor mLocalSocket; - protected InetSocketAddress mLocalSockName; - protected byte[] mLastRecvBuf; - protected boolean mStopped; - protected HandlerThread mHandlerThread; - protected PacketReader mReceiver; - - class UdpLoopbackReader extends PacketReader { - UdpLoopbackReader(Handler h) { - super(h); - } - - @Override - protected FileDescriptor createFd() { - FileDescriptor s = null; - try { - s = Os.socket(AF_INET6, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP); - Os.bind(s, LOOPBACK6, 0); - mLocalSockName = (InetSocketAddress) Os.getsockname(s); - Os.setsockoptTimeval(s, SOL_SOCKET, SO_SNDTIMEO, TIMEO); - } catch (ErrnoException | SocketException e) { - closeFd(s); - throw new RuntimeException("Failed to create FD", e); - } - - mLocalSocket = s; - return s; - } - - @Override - protected void handlePacket(byte[] recvbuf, int length) { - mLastRecvBuf = Arrays.copyOf(recvbuf, length); - mLatch.countDown(); - } - - @Override - protected void onStart() { - mStopped = false; - mLatch.countDown(); - } - - @Override - protected void onStop() { - mStopped = true; - mLatch.countDown(); - } - }; - - @Before - public void setUp() { - resetLatch(); - mLocalSocket = null; - mLocalSockName = null; - mLastRecvBuf = null; - mStopped = false; - - mHandlerThread = new HandlerThread(PacketReaderTest.class.getSimpleName()); - mHandlerThread.start(); - } - - @After - public void tearDown() throws Exception { - if (mReceiver != null) { - mHandlerThread.getThreadHandler().post(() -> mReceiver.stop()); - waitForActivity(); - } - mReceiver = null; - mHandlerThread.quit(); - mHandlerThread = null; - } - - void resetLatch() { - mLatch = new CountDownLatch(1); - } - - void waitForActivity() throws Exception { - try { - mLatch.await(1000, TimeUnit.MILLISECONDS); - } finally { - resetLatch(); - } - } - - void sendPacket(byte[] contents) throws Exception { - final DatagramSocket sender = new DatagramSocket(); - sender.connect(mLocalSockName); - sender.send(new DatagramPacket(contents, contents.length)); - sender.close(); - } - - @Test - public void testBasicWorking() throws Exception { - final Handler h = mHandlerThread.getThreadHandler(); - mReceiver = new UdpLoopbackReader(h); - - h.post(() -> mReceiver.start()); - waitForActivity(); - assertTrue(mLocalSockName != null); - assertEquals(LOOPBACK6, mLocalSockName.getAddress()); - assertTrue(0 < mLocalSockName.getPort()); - assertTrue(mLocalSocket != null); - assertFalse(mStopped); - - final byte[] one = "one 1".getBytes("UTF-8"); - sendPacket(one); - waitForActivity(); - assertEquals(1, mReceiver.numPacketsReceived()); - assertTrue(Arrays.equals(one, mLastRecvBuf)); - assertFalse(mStopped); - - final byte[] two = "two 2".getBytes("UTF-8"); - sendPacket(two); - waitForActivity(); - assertEquals(2, mReceiver.numPacketsReceived()); - assertTrue(Arrays.equals(two, mLastRecvBuf)); - assertFalse(mStopped); - - h.post(() -> mReceiver.stop()); - waitForActivity(); - assertEquals(2, mReceiver.numPacketsReceived()); - assertTrue(Arrays.equals(two, mLastRecvBuf)); - assertTrue(mStopped); - mReceiver = null; - } - - class NullPacketReader extends PacketReader { - NullPacketReader(Handler h, int recvbufsize) { - super(h, recvbufsize); - } - - @Override - public FileDescriptor createFd() { - return null; - } - } - - @Test - public void testMinimalRecvBufSize() throws Exception { - final Handler h = mHandlerThread.getThreadHandler(); - - for (int i : new int[] { -1, 0, 1, DEFAULT_RECV_BUF_SIZE - 1 }) { - final PacketReader b = new NullPacketReader(h, i); - assertEquals(DEFAULT_RECV_BUF_SIZE, b.recvBufSize()); - } - } - - @Test - public void testStartingFromWrongThread() throws Exception { - final Handler h = mHandlerThread.getThreadHandler(); - final PacketReader b = new NullPacketReader(h, DEFAULT_RECV_BUF_SIZE); - assertThrows(IllegalStateException.class, () -> b.start()); - } - - @Test - public void testStoppingFromWrongThread() throws Exception { - final Handler h = mHandlerThread.getThreadHandler(); - final PacketReader b = new NullPacketReader(h, DEFAULT_RECV_BUF_SIZE); - assertThrows(IllegalStateException.class, () -> b.stop()); - } - - @Test - public void testSuccessToCreateSocket() throws Exception { - final Handler h = mHandlerThread.getThreadHandler(); - final PacketReader b = new UdpLoopbackReader(h); - h.post(() -> assertTrue(b.start())); - } - - @Test - public void testFailToCreateSocket() throws Exception { - final Handler h = mHandlerThread.getThreadHandler(); - final PacketReader b = new NullPacketReader(h, DEFAULT_RECV_BUF_SIZE); - h.post(() -> assertFalse(b.start())); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/PerUidCounterTest.kt b/common/tests/unit/src/com/android/net/module/util/PerUidCounterTest.kt deleted file mode 100644 index 321fe594..00000000 --- a/common/tests/unit/src/com/android/net/module/util/PerUidCounterTest.kt +++ /dev/null @@ -1,142 +0,0 @@ -/* - * 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.net.module.util - -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import org.junit.Test -import org.junit.runner.RunWith -import kotlin.test.assertEquals -import kotlin.test.assertFailsWith - -@RunWith(AndroidJUnit4::class) -@SmallTest -class PerUidCounterTest { - private val UID_A = 1000 - private val UID_B = 1001 - private val UID_C = 1002 - - @Test - fun testCounterMaximum() { - assertFailsWith<IllegalArgumentException> { - PerUidCounter(-1) - } - assertFailsWith<IllegalArgumentException> { - PerUidCounter(0) - } - - val testLimit = 1000 - val testCounter = PerUidCounter(testLimit) - assertEquals(0, testCounter[UID_A]) - repeat(testLimit) { - testCounter.incrementCountOrThrow(UID_A) - } - assertEquals(testLimit, testCounter[UID_A]) - assertFailsWith<IllegalStateException> { - testCounter.incrementCountOrThrow(UID_A) - } - assertEquals(testLimit, testCounter[UID_A]) - } - - @Test - fun testIncrementCountOrThrow() { - val counter = PerUidCounter(3) - - // Verify the counters work independently. - counter.incrementCountOrThrow(UID_A) - counter.incrementCountOrThrow(UID_B) - counter.incrementCountOrThrow(UID_B) - counter.incrementCountOrThrow(UID_A) - counter.incrementCountOrThrow(UID_A) - assertEquals(3, counter[UID_A]) - assertEquals(2, counter[UID_B]) - assertFailsWith<IllegalStateException> { - counter.incrementCountOrThrow(UID_A) - } - counter.incrementCountOrThrow(UID_B) - assertFailsWith<IllegalStateException> { - counter.incrementCountOrThrow(UID_B) - } - - // Verify exception can be triggered again. - assertFailsWith<IllegalStateException> { - counter.incrementCountOrThrow(UID_A) - } - assertFailsWith<IllegalStateException> { - repeat(3) { - counter.incrementCountOrThrow(UID_A) - } - } - assertEquals(3, counter[UID_A]) - assertEquals(3, counter[UID_B]) - assertEquals(0, counter[UID_C]) - } - - @Test - fun testDecrementCountOrThrow() { - val counter = PerUidCounter(3) - - // Verify the count cannot go below zero. - assertFailsWith<IllegalStateException> { - counter.decrementCountOrThrow(UID_A) - } - assertFailsWith<IllegalStateException> { - repeat(5) { - counter.decrementCountOrThrow(UID_A) - } - } - - // Verify the counters work independently. - counter.incrementCountOrThrow(UID_A) - counter.incrementCountOrThrow(UID_B) - assertEquals(1, counter[UID_A]) - assertEquals(1, counter[UID_B]) - assertFailsWith<IllegalStateException> { - repeat(3) { - counter.decrementCountOrThrow(UID_A) - } - } - assertFailsWith<IllegalStateException> { - counter.decrementCountOrThrow(UID_A) - } - assertEquals(0, counter[UID_A]) - assertEquals(1, counter[UID_B]) - - // Verify mixing increment and decrement. - val largeCounter = PerUidCounter(100) - repeat(90) { - largeCounter.incrementCountOrThrow(UID_A) - } - repeat(70) { - largeCounter.decrementCountOrThrow(UID_A) - } - repeat(80) { - largeCounter.incrementCountOrThrow(UID_A) - } - assertFailsWith<IllegalStateException> { - largeCounter.incrementCountOrThrow(UID_A) - } - assertEquals(100, largeCounter[UID_A]) - repeat(100) { - largeCounter.decrementCountOrThrow(UID_A) - } - assertFailsWith<IllegalStateException> { - largeCounter.decrementCountOrThrow(UID_A) - } - assertEquals(0, largeCounter[UID_A]) - } -}
\ No newline at end of file diff --git a/common/tests/unit/src/com/android/net/module/util/PermissionUtilsTest.kt b/common/tests/unit/src/com/android/net/module/util/PermissionUtilsTest.kt deleted file mode 100644 index 1b6cbcb0..00000000 --- a/common/tests/unit/src/com/android/net/module/util/PermissionUtilsTest.kt +++ /dev/null @@ -1,127 +0,0 @@ -/* - * 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.net.module.util - -import android.Manifest.permission.NETWORK_STACK -import android.content.Context -import android.content.pm.PackageManager -import android.content.pm.PackageManager.PERMISSION_DENIED -import android.content.pm.PackageManager.PERMISSION_GRANTED -import android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import com.android.net.module.util.PermissionUtils.checkAnyPermissionOf -import com.android.net.module.util.PermissionUtils.enforceAnyPermissionOf -import com.android.net.module.util.PermissionUtils.enforceNetworkStackPermission -import com.android.net.module.util.PermissionUtils.enforceNetworkStackPermissionOr -import com.android.net.module.util.PermissionUtils.enforceSystemFeature -import org.junit.Assert -import org.junit.Assert.assertFalse -import org.junit.Assert.assertTrue -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.ArgumentMatchers -import org.mockito.ArgumentMatchers.any -import org.mockito.Mockito.doReturn -import org.mockito.Mockito.mock -import kotlin.test.assertEquals -import kotlin.test.assertFailsWith - -/** Tests for PermissionUtils */ -@RunWith(AndroidJUnit4::class) -@SmallTest -class PermissionUtilsTest { - private val TEST_PERMISSION1 = "android.permission.TEST_PERMISSION1" - private val TEST_PERMISSION2 = "android.permission.TEST_PERMISSION2" - private val context = mock(Context::class.java) - private val packageManager = mock(PackageManager::class.java) - - @Before - fun setup() { - doReturn(packageManager).`when`(context).packageManager - } - - @Test - fun testEnforceAnyPermissionOf() { - doReturn(PERMISSION_GRANTED).`when`(context).checkCallingOrSelfPermission(TEST_PERMISSION1) - doReturn(PERMISSION_DENIED).`when`(context).checkCallingOrSelfPermission(TEST_PERMISSION2) - assertTrue(checkAnyPermissionOf(context, TEST_PERMISSION1, TEST_PERMISSION2)) - enforceAnyPermissionOf(context, TEST_PERMISSION1, TEST_PERMISSION2) - - doReturn(PERMISSION_DENIED).`when`(context).checkCallingOrSelfPermission(TEST_PERMISSION1) - doReturn(PERMISSION_GRANTED).`when`(context).checkCallingOrSelfPermission(TEST_PERMISSION2) - assertTrue(checkAnyPermissionOf(context, TEST_PERMISSION1, TEST_PERMISSION2)) - enforceAnyPermissionOf(context, TEST_PERMISSION1, TEST_PERMISSION2) - - doReturn(PERMISSION_DENIED).`when`(context).checkCallingOrSelfPermission(any()) - assertFalse(checkAnyPermissionOf(context, TEST_PERMISSION1, TEST_PERMISSION2)) - assertFailsWith<SecurityException>("Expect fail but permission granted.") { - enforceAnyPermissionOf(context, TEST_PERMISSION1, TEST_PERMISSION2) } - } - - @Test - fun testEnforceNetworkStackPermissionOr() { - doReturn(PERMISSION_GRANTED).`when`(context).checkCallingOrSelfPermission(NETWORK_STACK) - doReturn(PERMISSION_DENIED).`when`(context) - .checkCallingOrSelfPermission(PERMISSION_MAINLINE_NETWORK_STACK) - enforceNetworkStackPermission(context) - enforceNetworkStackPermissionOr(context, TEST_PERMISSION1) - - doReturn(PERMISSION_DENIED).`when`(context).checkCallingOrSelfPermission(NETWORK_STACK) - doReturn(PERMISSION_GRANTED).`when`(context) - .checkCallingOrSelfPermission(PERMISSION_MAINLINE_NETWORK_STACK) - enforceNetworkStackPermission(context) - enforceNetworkStackPermissionOr(context, TEST_PERMISSION2) - - doReturn(PERMISSION_DENIED).`when`(context).checkCallingOrSelfPermission(NETWORK_STACK) - doReturn(PERMISSION_DENIED).`when`(context) - .checkCallingOrSelfPermission(PERMISSION_MAINLINE_NETWORK_STACK) - doReturn(PERMISSION_GRANTED).`when`(context).checkCallingOrSelfPermission(TEST_PERMISSION1) - assertFailsWith<SecurityException>("Expect fail but permission granted.") { - enforceNetworkStackPermission(context) } - enforceNetworkStackPermissionOr(context, TEST_PERMISSION1) - - doReturn(PERMISSION_DENIED).`when`(context).checkCallingOrSelfPermission(any()) - assertFailsWith<SecurityException>("Expect fail but permission granted.") { - enforceNetworkStackPermission(context) } - assertFailsWith<SecurityException>("Expect fail but permission granted.") { - enforceNetworkStackPermissionOr(context, TEST_PERMISSION2) } - } - - private fun mockHasSystemFeature(featureName: String, hasFeature: Boolean) { - doReturn(hasFeature).`when`(packageManager) - .hasSystemFeature(ArgumentMatchers.eq(featureName)) - } - - @Test - fun testEnforceSystemFeature() { - val systemFeature = "test.system.feature" - val exceptionMessage = "test exception message" - mockHasSystemFeature(featureName = systemFeature, hasFeature = false) - val e = assertFailsWith<UnsupportedOperationException>("Should fail without feature") { - enforceSystemFeature(context, systemFeature, exceptionMessage) } - assertEquals(exceptionMessage, e.message) - - mockHasSystemFeature(featureName = systemFeature, hasFeature = true) - try { - enforceSystemFeature(context, systemFeature, "") - } catch (e: UnsupportedOperationException) { - Assert.fail("Exception should have not been thrown with system feature enabled") - } - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/SharedLogTest.java b/common/tests/unit/src/com/android/net/module/util/SharedLogTest.java deleted file mode 100644 index aa1bfee4..00000000 --- a/common/tests/unit/src/com/android/net/module/util/SharedLogTest.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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.net.module.util; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.io.ByteArrayOutputStream; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.function.Consumer; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class SharedLogTest { - private static final String TIMESTAMP_PATTERN = "\\d{2}:\\d{2}:\\d{2}"; - private static final String TIMESTAMP = "HH:MM:SS"; - private static final String TAG = "top"; - - @Test - public void testBasicOperation() { - final SharedLog logTop = new SharedLog(TAG); - assertTrue(TAG.equals(logTop.getTag())); - - logTop.mark("first post!"); - - final SharedLog logLevel2a = logTop.forSubComponent("twoA"); - final SharedLog logLevel2b = logTop.forSubComponent("twoB"); - logLevel2b.e("2b or not 2b"); - logLevel2b.e("No exception", null); - logLevel2b.e("Wait, here's one", new Exception("Test")); - logLevel2a.w("second post?"); - - final SharedLog logLevel3 = logLevel2a.forSubComponent("three"); - logTop.log("still logging"); - logLevel2b.e(new Exception("Got another exception")); - logLevel3.i("3 >> 2"); - logLevel2a.mark("ok: last post"); - logTop.logf("finished!"); - - final String[] expected = { - " - MARK first post!", - " - [twoB] ERROR 2b or not 2b", - " - [twoB] ERROR No exception", - // No stacktrace in shared log, only in logcat - " - [twoB] ERROR Wait, here's one: Test", - " - [twoA] WARN second post?", - " - still logging", - " - [twoB] ERROR java.lang.Exception: Got another exception", - " - [twoA.three] 3 >> 2", - " - [twoA] MARK ok: last post", - " - finished!", - }; - // Verify the logs are all there and in the correct order. - assertDumpLogs(expected, logTop); - - // In fact, because they all share the same underlying LocalLog, - // every subcomponent SharedLog's dump() is identical. - assertDumpLogs(expected, logLevel2a); - assertDumpLogs(expected, logLevel2b); - assertDumpLogs(expected, logLevel3); - } - - private static void assertDumpLogs(String[] expected, SharedLog log) { - verifyLogLines(expected, dump(log)); - verifyLogLines(reverse(expected), reverseDump(log)); - } - - private static String dump(SharedLog log) { - return getSharedLogString(pw -> log.dump(null /* fd */, pw, null /* args */)); - } - - private static String reverseDump(SharedLog log) { - return getSharedLogString(pw -> log.reverseDump(pw)); - } - - private static String[] reverse(String[] ary) { - final List<String> ls = new ArrayList<>(Arrays.asList(ary)); - Collections.reverse(ls); - return ls.toArray(new String[ary.length]); - } - - private static String getSharedLogString(Consumer<PrintWriter> functor) { - final ByteArrayOutputStream ostream = new ByteArrayOutputStream(); - final PrintWriter pw = new PrintWriter(ostream, true); - functor.accept(pw); - - final String dumpOutput = ostream.toString(); - assertNotNull(dumpOutput); - assertFalse("".equals(dumpOutput)); - return dumpOutput; - } - - private static void verifyLogLines(String[] expected, String gottenLogs) { - final String[] lines = gottenLogs.split("\n"); - assertEquals(expected.length, lines.length); - - for (int i = 0; i < expected.length; i++) { - String got = lines[i]; - String want = expected[i]; - assertTrue(String.format("'%s' did not contain '%s'", got, want), got.endsWith(want)); - assertTrue(String.format("'%s' did not contain a %s timestamp", got, TIMESTAMP), - got.replaceFirst(TIMESTAMP_PATTERN, TIMESTAMP).contains(TIMESTAMP)); - } - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/StructTest.java b/common/tests/unit/src/com/android/net/module/util/StructTest.java deleted file mode 100644 index b4da0439..00000000 --- a/common/tests/unit/src/com/android/net/module/util/StructTest.java +++ /dev/null @@ -1,1075 +0,0 @@ -/* - * Copyright (C) 2020 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.net.module.util; - -import static com.android.testutils.MiscAsserts.assertThrows; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertTrue; - -import android.annotation.SuppressLint; -import android.net.InetAddresses; -import android.net.IpPrefix; -import android.net.MacAddress; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.net.module.util.Struct.Field; -import com.android.net.module.util.Struct.Type; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.math.BigInteger; -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.nio.BufferOverflowException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.Arrays; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class StructTest { - - // IPv6, 0 bytes of options, ifindex 15715755: 0x00efcdab, type 134 (RA), code 0, padding. - private static final String HDR_EMPTY = "0a00" + "0000" + "abcdef00" + "8600000000000000"; - - // UBE16: 0xfeff, UBE32: 0xfeffffff, UBE64: 0xfeffffffffffffff, UBE63: 0x7effffffffffffff - private static final String NETWORK_ORDER_MSG = "feff" + "feffffff" + "feffffffffffffff" - + "7effffffffffffff"; - - // S8: 0x7f, S16: 0x7fff, S32: 0x7fffffff, S64: 0x7fffffffffffffff - private static final String SIGNED_DATA = "7f" + "ff7f" + "ffffff7f" + "ffffffffffffff7f"; - - // nS8: 0x81, nS16: 0x8001, nS32: 0x80000001, nS64: 800000000000000001 - private static final String SIGNED_NEGATIVE_DATA = "81" + "0180" + "01000080" - + "0100000000000080"; - - // U8: 0xff, U16: 0xffff, U32: 0xffffffff, U64: 0xffffffffffffffff, U63: 0x7fffffffffffffff, - // U63: 0xffffffffffffffff(-1L) - private static final String UNSIGNED_DATA = "ff" + "ffff" + "ffffffff" + "ffffffffffffffff" - + "ffffffffffffff7f" + "ffffffffffffffff"; - - // PREF64 option, 2001:db8:3:4:5:6::/96, lifetime: 10064 - private static final String OPT_PREF64 = "2750" + "20010db80003000400050006"; - private static final byte[] TEST_PREFIX64 = new byte[]{ - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, (byte) 0x00, (byte) 0x03, - (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x05, (byte) 0x00, (byte) 0x06, - }; - - private static final Inet4Address TEST_IPV4_ADDRESS = - (Inet4Address) InetAddresses.parseNumericAddress("192.168.100.1"); - private static final Inet6Address TEST_IPV6_ADDRESS = - (Inet6Address) InetAddresses.parseNumericAddress("2001:db8:3:4:5:6:7:8"); - - private <T> T doParsingMessageTest(final String hexString, final Class<T> clazz, - final ByteOrder order) { - final ByteBuffer buf = toByteBuffer(hexString); - buf.order(order); - return Struct.parse(clazz, buf); - } - - public static class HeaderMsgWithConstructor extends Struct { - static int sType; - static int sLength; - - @Field(order = 0, type = Type.U8, padding = 1) - public final short mFamily; - @Field(order = 1, type = Type.U16) - public final int mLen; - @Field(order = 2, type = Type.S32) - public final int mIfindex; - @Field(order = 3, type = Type.U8) - public final short mIcmpType; - @Field(order = 4, type = Type.U8, padding = 6) - public final short mIcmpCode; - - HeaderMsgWithConstructor(final short family, final int len, final int ifindex, - final short type, final short code) { - mFamily = family; - mLen = len; - mIfindex = ifindex; - mIcmpType = type; - mIcmpCode = code; - } - } - - private void verifyHeaderParsing(final HeaderMsgWithConstructor msg) { - assertEquals(10, msg.mFamily); - assertEquals(0, msg.mLen); - assertEquals(15715755, msg.mIfindex); - assertEquals(134, msg.mIcmpType); - assertEquals(0, msg.mIcmpCode); - - assertEquals(16, Struct.getSize(HeaderMsgWithConstructor.class)); - assertArrayEquals(toByteBuffer(HDR_EMPTY).array(), - msg.writeToBytes(ByteOrder.LITTLE_ENDIAN)); - } - - @Test - public void testClassWithExplicitConstructor() { - final HeaderMsgWithConstructor msg = doParsingMessageTest(HDR_EMPTY, - HeaderMsgWithConstructor.class, ByteOrder.LITTLE_ENDIAN); - verifyHeaderParsing(msg); - } - - public static class HeaderMsgWithoutConstructor extends Struct { - static int sType; - static int sLength; - - @Field(order = 0, type = Type.U8, padding = 1) - public short mFamily; - @Field(order = 1, type = Type.U16) - public int mLen; - @Field(order = 2, type = Type.S32) - public int mIfindex; - @Field(order = 3, type = Type.U8) - public short mIcmpType; - @Field(order = 4, type = Type.U8, padding = 6) - public short mIcmpCode; - } - - @Test - public void testClassWithDefaultConstructor() { - final HeaderMsgWithoutConstructor msg = doParsingMessageTest(HDR_EMPTY, - HeaderMsgWithoutConstructor.class, ByteOrder.LITTLE_ENDIAN); - assertEquals(10, msg.mFamily); - assertEquals(0, msg.mLen); - assertEquals(15715755, msg.mIfindex); - assertEquals(134, msg.mIcmpType); - assertEquals(0, msg.mIcmpCode); - - assertEquals(16, Struct.getSize(HeaderMsgWithoutConstructor.class)); - assertArrayEquals(toByteBuffer(HDR_EMPTY).array(), - msg.writeToBytes(ByteOrder.LITTLE_ENDIAN)); - } - - public static class HeaderMessage { - @Field(order = 0, type = Type.U8, padding = 1) - short mFamily; - @Field(order = 1, type = Type.U16) - int mLen; - @Field(order = 2, type = Type.S32) - int mIfindex; - @Field(order = 3, type = Type.U8) - short mIcmpType; - @Field(order = 4, type = Type.U8, padding = 6) - short mIcmpCode; - } - - @Test - public void testInvalidClass_NotSubClass() { - final ByteBuffer buf = toByteBuffer(HDR_EMPTY); - assertThrows(IllegalArgumentException.class, () -> Struct.parse(HeaderMessage.class, buf)); - } - - public static class HeaderMessageMissingAnnotation extends Struct { - @Field(order = 0, type = Type.U8, padding = 1) - short mFamily; - @Field(order = 1, type = Type.U16) - int mLen; - int mIfindex; - @Field(order = 2, type = Type.U8) - short mIcmpType; - @Field(order = 3, type = Type.U8, padding = 6) - short mIcmpCode; - } - - @Test - public void testInvalidClass_MissingAnnotationField() { - final ByteBuffer buf = toByteBuffer(HDR_EMPTY); - assertThrows(IllegalArgumentException.class, - () -> Struct.parse(HeaderMessageMissingAnnotation.class, buf)); - } - - public static class NetworkOrderMessage extends Struct { - @Field(order = 0, type = Type.UBE16) - public final int mUBE16; - @Field(order = 1, type = Type.UBE32) - public final long mUBE32; - @Field(order = 2, type = Type.UBE64) - public final BigInteger mUBE64; - @Field(order = 3, type = Type.UBE63) - public final long mUBE63; - - NetworkOrderMessage(final int be16, final long be32, final BigInteger be64, - final long be63) { - mUBE16 = be16; - mUBE32 = be32; - mUBE64 = be64; - mUBE63 = be63; - } - } - - @Test - public void testNetworkOrder() { - final NetworkOrderMessage msg = doParsingMessageTest(NETWORK_ORDER_MSG, - NetworkOrderMessage.class, ByteOrder.LITTLE_ENDIAN); - assertEquals(65279, msg.mUBE16); - assertEquals(4278190079L, msg.mUBE32); - assertEquals(new BigInteger("18374686479671623679"), msg.mUBE64); - assertEquals(9151314442816847871L, msg.mUBE63); - - assertEquals(22, Struct.getSize(NetworkOrderMessage.class)); - assertArrayEquals(toByteBuffer(NETWORK_ORDER_MSG).array(), - msg.writeToBytes(ByteOrder.LITTLE_ENDIAN)); - } - - public static class UnsignedDataMessage extends Struct { - @Field(order = 0, type = Type.U8) - public final short mU8; - @Field(order = 1, type = Type.U16) - public final int mU16; - @Field(order = 2, type = Type.U32) - public final long mU32; - @Field(order = 3, type = Type.U64) - public final BigInteger mU64; - @Field(order = 4, type = Type.U63) - public final long mU63; - @Field(order = 5, type = Type.U63) - public final long mLU64; // represent U64 data with U63 type - - UnsignedDataMessage(final short u8, final int u16, final long u32, final BigInteger u64, - final long u63, final long lu64) { - mU8 = u8; - mU16 = u16; - mU32 = u32; - mU64 = u64; - mU63 = u63; - mLU64 = lu64; - } - } - - @Test - public void testUnsignedData() { - final UnsignedDataMessage msg = doParsingMessageTest(UNSIGNED_DATA, - UnsignedDataMessage.class, ByteOrder.LITTLE_ENDIAN); - assertEquals(255, msg.mU8); - assertEquals(65535, msg.mU16); - assertEquals(4294967295L, msg.mU32); - assertEquals(new BigInteger("18446744073709551615"), msg.mU64); - assertEquals(9223372036854775807L, msg.mU63); - assertEquals(-1L, msg.mLU64); - - assertEquals(31, Struct.getSize(UnsignedDataMessage.class)); - assertArrayEquals(toByteBuffer(UNSIGNED_DATA).array(), - msg.writeToBytes(ByteOrder.LITTLE_ENDIAN)); - } - - public static class U64DataMessage extends Struct { - @Field(order = 0, type = Type.U64) long mU64; - } - - @Test - public void testInvalidType_U64WithLongPrimitive() { - assertThrows(IllegalArgumentException.class, - () -> Struct.parse(U64DataMessage.class, toByteBuffer("ffffffffffffffff"))); - } - - // BigInteger U64: 0x0000000000001234, BigInteger UBE64: 0x0000000000001234, BigInteger U64: 0 - private static final String SMALL_VALUE_BIGINTEGER = "3412000000000000" + "0000000000001234" - + "0000000000000000"; - - public static class SmallValueBigInteger extends Struct { - @Field(order = 0, type = Type.U64) public final BigInteger mSmallValue; - @Field(order = 1, type = Type.UBE64) public final BigInteger mBSmallValue; - @Field(order = 2, type = Type.U64) public final BigInteger mZero; - - SmallValueBigInteger(final BigInteger smallValue, final BigInteger bSmallValue, - final BigInteger zero) { - mSmallValue = smallValue; - mBSmallValue = bSmallValue; - mZero = zero; - } - } - - @Test - public void testBigIntegerSmallValueOrZero() { - final SmallValueBigInteger msg = doParsingMessageTest(SMALL_VALUE_BIGINTEGER, - SmallValueBigInteger.class, ByteOrder.LITTLE_ENDIAN); - assertEquals(new BigInteger("4660"), msg.mSmallValue); - assertEquals(new BigInteger("4660"), msg.mBSmallValue); - assertEquals(new BigInteger("0"), msg.mZero); - - assertEquals(24, Struct.getSize(SmallValueBigInteger.class)); - assertArrayEquals(toByteBuffer(SMALL_VALUE_BIGINTEGER).array(), - msg.writeToBytes(ByteOrder.LITTLE_ENDIAN)); - } - - public static class SignedDataMessage extends Struct { - @Field(order = 0, type = Type.S8) - public final byte mS8; - @Field(order = 1, type = Type.S16) - public final short mS16; - @Field(order = 2, type = Type.S32) - public final int mS32; - @Field(order = 3, type = Type.S64) - public final long mS64; - - SignedDataMessage(final byte s8, final short s16, final int s32, final long s64) { - mS8 = s8; - mS16 = s16; - mS32 = s32; - mS64 = s64; - } - } - - @Test - public void testSignedPositiveData() { - final SignedDataMessage msg = doParsingMessageTest(SIGNED_DATA, SignedDataMessage.class, - ByteOrder.LITTLE_ENDIAN); - assertEquals(127, msg.mS8); - assertEquals(32767, msg.mS16); - assertEquals(2147483647, msg.mS32); - assertEquals(9223372036854775807L, msg.mS64); - - assertEquals(15, Struct.getSize(SignedDataMessage.class)); - assertArrayEquals(toByteBuffer(SIGNED_DATA).array(), - msg.writeToBytes(ByteOrder.LITTLE_ENDIAN)); - } - - @Test - public void testSignedNegativeData() { - final SignedDataMessage msg = doParsingMessageTest(SIGNED_NEGATIVE_DATA, - SignedDataMessage.class, ByteOrder.LITTLE_ENDIAN); - assertEquals(-127, msg.mS8); - assertEquals(-32767, msg.mS16); - assertEquals(-2147483647, msg.mS32); - assertEquals(-9223372036854775807L, msg.mS64); - - assertEquals(15, Struct.getSize(SignedDataMessage.class)); - assertArrayEquals(toByteBuffer(SIGNED_NEGATIVE_DATA).array(), - msg.writeToBytes(ByteOrder.LITTLE_ENDIAN)); - } - - public static class HeaderMessageWithDuplicateOrder extends Struct { - @Field(order = 0, type = Type.U8, padding = 1) - short mFamily; - @Field(order = 1, type = Type.U16) - int mLen; - @Field(order = 2, type = Type.S32) - int mIfindex; - @Field(order = 2, type = Type.U8) - short mIcmpType; - @Field(order = 3, type = Type.U8, padding = 6) - short mIcmpCode; - } - - @Test - public void testInvalidClass_DuplicateFieldOrder() { - final ByteBuffer buf = toByteBuffer(HDR_EMPTY); - assertThrows(IllegalArgumentException.class, - () -> Struct.parse(HeaderMessageWithDuplicateOrder.class, buf)); - } - - public static class HeaderMessageWithNegativeOrder extends Struct { - @Field(order = 0, type = Type.U8, padding = 1) - short mFamily; - @Field(order = 1, type = Type.U16) - int mLen; - @Field(order = 2, type = Type.S32) - int mIfindex; - @Field(order = 3, type = Type.U8) - short mIcmpType; - @Field(order = -4, type = Type.U8, padding = 6) - short mIcmpCode; - } - - @Test - public void testInvalidClass_NegativeFieldOrder() { - final ByteBuffer buf = toByteBuffer(HDR_EMPTY); - assertThrows(IllegalArgumentException.class, - () -> Struct.parse(HeaderMessageWithNegativeOrder.class, buf)); - } - - public static class HeaderMessageOutOfIndexBounds extends Struct { - @Field(order = 0, type = Type.U8, padding = 1) - short mFamily; - @Field(order = 1, type = Type.U16) - int mLen; - @Field(order = 2, type = Type.S32) - int mIfindex; - @Field(order = 3, type = Type.U8) - short mIcmpType; - @Field(order = 5, type = Type.U8, padding = 6) - short mIcmpCode; - } - - @Test - public void testInvalidClass_OutOfIndexBounds() { - final ByteBuffer buf = toByteBuffer(HDR_EMPTY); - assertThrows(IllegalArgumentException.class, - () -> Struct.parse(HeaderMessageOutOfIndexBounds.class, buf)); - } - - public static class HeaderMessageMismatchedPrimitiveType extends Struct { - @Field(order = 0, type = Type.U8, padding = 1) - short mFamily; - @Field(order = 1, type = Type.U16) - short mLen; // should be integer - @Field(order = 2, type = Type.S32) - int mIfindex; - @Field(order = 3, type = Type.U8) - short mIcmpType; - @Field(order = 4, type = Type.U8, padding = 6) - short mIcmpCode; - } - - @Test - public void testInvalidClass_MismatchedPrimitiveDataType() { - final ByteBuffer buf = toByteBuffer(HDR_EMPTY); - assertThrows(IllegalArgumentException.class, - () -> Struct.parse(HeaderMessageMismatchedPrimitiveType.class, buf)); - } - - public static class PrefixMessage extends Struct { - @Field(order = 0, type = Type.UBE16) - public final int mLifetime; - @Field(order = 1, type = Type.ByteArray, arraysize = 12) - public final byte[] mPrefix; - - PrefixMessage(final int lifetime, final byte[] prefix) { - mLifetime = lifetime; - mPrefix = prefix; - } - } - - @SuppressLint("NewApi") - private void verifyPrefixByteArrayParsing(final PrefixMessage msg) throws Exception { - // The original PREF64 option message has just 12 bytes for prefix byte array - // (Highest 96 bits of the Prefix), copyOf pads the 128-bits IPv6 address with - // prefix and 4-bytes zeros. - final InetAddress addr = InetAddress.getByAddress(Arrays.copyOf(msg.mPrefix, 16)); - final IpPrefix prefix = new IpPrefix(addr, 96); - assertEquals(10064, msg.mLifetime); - assertTrue(prefix.equals(new IpPrefix("2001:db8:3:4:5:6::/96"))); - - assertEquals(14, Struct.getSize(PrefixMessage.class)); - assertArrayEquals(toByteBuffer(OPT_PREF64).array(), - msg.writeToBytes(ByteOrder.LITTLE_ENDIAN)); - } - - public static class PrefixMessageWithZeroLengthArray extends Struct { - @Field(order = 0, type = Type.UBE16) - final int mLifetime; - @Field(order = 1, type = Type.ByteArray, arraysize = 0) - final byte[] mPrefix; - - PrefixMessageWithZeroLengthArray(final int lifetime, final byte[] prefix) { - mLifetime = lifetime; - mPrefix = prefix; - } - } - - @Test - public void testInvalidClass_ZeroLengthByteArray() { - final ByteBuffer buf = toByteBuffer(OPT_PREF64); - assertThrows(IllegalArgumentException.class, - () -> Struct.parse(PrefixMessageWithZeroLengthArray.class, buf)); - } - - @Test - public void testPrefixArrayField() throws Exception { - final PrefixMessage msg = doParsingMessageTest(OPT_PREF64, PrefixMessage.class, - ByteOrder.LITTLE_ENDIAN); - verifyPrefixByteArrayParsing(msg); - } - - public static class HeaderMessageWithMutableField extends Struct { - @Field(order = 0, type = Type.U8, padding = 1) - final short mFamily; - @Field(order = 1, type = Type.U16) - final int mLen; - @Field(order = 2, type = Type.S32) - int mIfindex; - @Field(order = 3, type = Type.U8) - short mIcmpType; - @Field(order = 4, type = Type.U8, padding = 6) - final short mIcmpCode; - - HeaderMessageWithMutableField(final short family, final int len, final short code) { - mFamily = family; - mLen = len; - mIcmpCode = code; - } - } - - @Test - public void testMixMutableAndImmutableFields() { - final ByteBuffer buf = toByteBuffer(HDR_EMPTY); - assertThrows(IllegalArgumentException.class, - () -> Struct.parse(HeaderMessageWithMutableField.class, buf)); - } - - public static class HeaderMsgWithStaticConstant extends Struct { - private static final String TAG = "HeaderMessage"; - private static final int FIELD_COUNT = 5; - - @Field(order = 0, type = Type.U8, padding = 1) - public final short mFamily; - @Field(order = 1, type = Type.U16) - public final int mLen; - @Field(order = 2, type = Type.S32) - public final int mIfindex; - @Field(order = 3, type = Type.U8) - public final short mIcmpType; - @Field(order = 4, type = Type.U8, padding = 6) - public final short mIcmpCode; - - HeaderMsgWithStaticConstant(final short family, final int len, final int ifindex, - final short type, final short code) { - mFamily = family; - mLen = len; - mIfindex = ifindex; - mIcmpType = type; - mIcmpCode = code; - } - } - - @Test - public void testStaticConstantField() { - final HeaderMsgWithStaticConstant msg = doParsingMessageTest(HDR_EMPTY, - HeaderMsgWithStaticConstant.class, ByteOrder.LITTLE_ENDIAN); - assertEquals(10, msg.mFamily); - assertEquals(0, msg.mLen); - assertEquals(15715755, msg.mIfindex); - assertEquals(134, msg.mIcmpType); - assertEquals(0, msg.mIcmpCode); - - assertEquals(16, Struct.getSize(HeaderMsgWithStaticConstant.class)); - assertArrayEquals(toByteBuffer(HDR_EMPTY).array(), - msg.writeToBytes(ByteOrder.LITTLE_ENDIAN)); - } - - public static class MismatchedConstructor extends Struct { - @Field(order = 0, type = Type.U16) final int mInt1; - @Field(order = 1, type = Type.U16) final int mInt2; - MismatchedConstructor(String int1, String int2) { - mInt1 = Integer.valueOf(int1); - mInt2 = Integer.valueOf(int2); - } - } - - @Test - public void testMisMatchedConstructor() { - final ByteBuffer buf = toByteBuffer("1234" + "5678"); - assertThrows(IllegalArgumentException.class, - () -> Struct.parse(MismatchedConstructor.class, buf)); - } - - public static class ClassWithTwoConstructors extends Struct { - @Field(order = 0, type = Type.U16) public final int mInt1; - @Field(order = 1, type = Type.U16) public final int mInt2; - ClassWithTwoConstructors(String int1, String int2) { - mInt1 = Integer.valueOf(int1); - mInt2 = Integer.valueOf(int2); - } - ClassWithTwoConstructors(int int1, int int2) { - mInt1 = int1; - mInt2 = int2; - } - } - - @Test - public void testClassWithTwoConstructors() { - final ClassWithTwoConstructors msg = doParsingMessageTest("1234" + "5678", - ClassWithTwoConstructors.class, ByteOrder.LITTLE_ENDIAN); - assertEquals(13330 /* 0x3412 */, msg.mInt1); - assertEquals(30806 /* 0x7856 */, msg.mInt2); - - assertEquals(4, Struct.getSize(ClassWithTwoConstructors.class)); - assertArrayEquals(toByteBuffer("1234" + "5678").array(), - msg.writeToBytes(ByteOrder.LITTLE_ENDIAN)); - } - - @Test - public void testInvalidOutputByteBuffer_ZeroCapacity() { - final ByteBuffer output = ByteBuffer.allocate(0); - output.order(ByteOrder.LITTLE_ENDIAN); - final HeaderMsgWithConstructor msg = doParsingMessageTest(HDR_EMPTY, - HeaderMsgWithConstructor.class, ByteOrder.LITTLE_ENDIAN); - assertThrows(BufferOverflowException.class, () -> msg.writeToByteBuffer(output)); - } - - @Test - public void testConsecutiveWrites() { - final HeaderMsgWithConstructor msg1 = doParsingMessageTest(HDR_EMPTY, - HeaderMsgWithConstructor.class, ByteOrder.LITTLE_ENDIAN); - final PrefixMessage msg2 = doParsingMessageTest(OPT_PREF64, PrefixMessage.class, - ByteOrder.LITTLE_ENDIAN); - - int size = Struct.getSize(HeaderMsgWithConstructor.class) - + Struct.getSize(PrefixMessage.class); - final ByteBuffer output = ByteBuffer.allocate(size); - output.order(ByteOrder.LITTLE_ENDIAN); - - msg1.writeToByteBuffer(output); - msg2.writeToByteBuffer(output); - output.flip(); - - final ByteBuffer concat = ByteBuffer.allocate(size).put(toByteBuffer(HDR_EMPTY)) - .put(toByteBuffer(OPT_PREF64)); - assertArrayEquals(output.array(), concat.array()); - } - - @Test - public void testClassesParsedFromCache() throws Exception { - for (int i = 0; i < 100; i++) { - final HeaderMsgWithConstructor msg1 = doParsingMessageTest(HDR_EMPTY, - HeaderMsgWithConstructor.class, ByteOrder.LITTLE_ENDIAN); - verifyHeaderParsing(msg1); - - final PrefixMessage msg2 = doParsingMessageTest(OPT_PREF64, PrefixMessage.class, - ByteOrder.LITTLE_ENDIAN); - verifyPrefixByteArrayParsing(msg2); - } - } - - public static class BigEndianDataMessage extends Struct { - @Field(order = 0, type = Type.S32) public int mInt1; - @Field(order = 1, type = Type.S32) public int mInt2; - @Field(order = 2, type = Type.UBE16) public int mInt3; - @Field(order = 3, type = Type.U16) public int mInt4; - @Field(order = 4, type = Type.U64) public BigInteger mBigInteger1; - @Field(order = 5, type = Type.UBE64) public BigInteger mBigInteger2; - @Field(order = 6, type = Type.S64) public long mLong; - } - - private static final String BIG_ENDIAN_DATA = "00000001" + "fffffffe" + "fffe" + "fffe" - + "ff00004500002301" + "ff00004500002301" + "ff00004500002301"; - - @Test - public void testBigEndianByteBuffer() { - final BigEndianDataMessage msg = doParsingMessageTest(BIG_ENDIAN_DATA, - BigEndianDataMessage.class, ByteOrder.BIG_ENDIAN); - - assertEquals(1, msg.mInt1); - assertEquals(-2, msg.mInt2); - assertEquals(65534, msg.mInt3); - assertEquals(65534, msg.mInt4); - assertEquals(new BigInteger("18374686776024376065"), msg.mBigInteger1); - assertEquals(new BigInteger("18374686776024376065"), msg.mBigInteger2); - assertEquals(0xff00004500002301L, msg.mLong); - - assertEquals(36, Struct.getSize(BigEndianDataMessage.class)); - assertArrayEquals(toByteBuffer(BIG_ENDIAN_DATA).array(), - msg.writeToBytes(ByteOrder.BIG_ENDIAN)); - } - - private ByteBuffer toByteBuffer(final String hexString) { - return ByteBuffer.wrap(HexDump.hexStringToByteArray(hexString)); - } - - public static class MacAddressMessage extends Struct { - public @Field(order = 0, type = Type.EUI48) final MacAddress mMac1; - public @Field(order = 1, type = Type.EUI48) final MacAddress mMac2; - - MacAddressMessage(final MacAddress mac1, final MacAddress mac2) { - this.mMac1 = mac1; - this.mMac2 = mac2; - } - } - - @Test - public void testMacAddressType() { - final MacAddressMessage msg = doParsingMessageTest("001122334455" + "ffffffffffff", - MacAddressMessage.class, ByteOrder.BIG_ENDIAN); - - assertEquals(MacAddress.fromString("00:11:22:33:44:55"), msg.mMac1); - assertEquals(MacAddress.fromString("ff:ff:ff:ff:ff:ff"), msg.mMac2); - - assertEquals(12, Struct.getSize(MacAddressMessage.class)); - assertArrayEquals(toByteBuffer("001122334455" + "ffffffffffff").array(), - msg.writeToBytes(ByteOrder.BIG_ENDIAN)); - } - - public static class BadMacAddressType extends Struct { - @Field(order = 0, type = Type.EUI48) byte[] mMac; - } - - @Test - public void testIncorrectType_EUI48WithByteArray() { - assertThrows(IllegalArgumentException.class, - () -> Struct.parse(BadMacAddressType.class, toByteBuffer("ffffffffffff"))); - } - - @Test - public void testStructToByteArrayRoundTrip() { - final SignedDataMessage littleEndianMsg = doParsingMessageTest(SIGNED_DATA, - SignedDataMessage.class, ByteOrder.LITTLE_ENDIAN); - assertArrayEquals(toByteBuffer(SIGNED_DATA).array(), - littleEndianMsg.writeToBytes(ByteOrder.LITTLE_ENDIAN)); - - final SignedDataMessage bigEndianMsg = doParsingMessageTest(SIGNED_DATA, - SignedDataMessage.class, ByteOrder.BIG_ENDIAN); - assertArrayEquals(toByteBuffer(SIGNED_DATA).array(), - bigEndianMsg.writeToBytes(ByteOrder.BIG_ENDIAN)); - - final SignedDataMessage nativeOrderMsg = ByteOrder.nativeOrder().equals( - ByteOrder.LITTLE_ENDIAN) ? littleEndianMsg : bigEndianMsg; - assertArrayEquals(toByteBuffer(SIGNED_DATA).array(), - nativeOrderMsg.writeToBytes()); - } - - @Test - public void testStructToByteArray() { - final SignedDataMessage msg = new SignedDataMessage((byte) -5, (short) 42, (int) 0xff000004, - (long) 0xff000004ff000005L); - final String leHexString = "fb" + "2a00" + "040000ff" + "050000ff040000ff"; - final String beHexString = "fb" + "002a" + "ff000004" + "ff000004ff000005"; - final String hexString = ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN) - ? leHexString : beHexString; - assertArrayEquals(toByteBuffer(hexString).array(), msg.writeToBytes()); - } - - public static class IpAddressMessage extends Struct { - @Field(order = 0, type = Type.Ipv4Address) public final Inet4Address ipv4Address; - @Field(order = 1, type = Type.Ipv6Address) public final Inet6Address ipv6Address; - - IpAddressMessage(final Inet4Address ipv4Address, final Inet6Address ipv6Address) { - this.ipv4Address = ipv4Address; - this.ipv6Address = ipv6Address; - } - } - - @Test - public void testIpAddressType() { - final IpAddressMessage msg = doParsingMessageTest("c0a86401" - + "20010db8000300040005000600070008", IpAddressMessage.class, ByteOrder.BIG_ENDIAN); - - assertEquals(TEST_IPV4_ADDRESS, msg.ipv4Address); - assertEquals(TEST_IPV6_ADDRESS, msg.ipv6Address); - - assertEquals(20, Struct.getSize(IpAddressMessage.class)); - assertArrayEquals(toByteBuffer("c0a86401" + "20010db8000300040005000600070008").array(), - msg.writeToBytes(ByteOrder.BIG_ENDIAN)); - } - - public static class WrongIpAddressType extends Struct { - @Field(order = 0, type = Type.Ipv4Address) public byte[] ipv4Address; - @Field(order = 1, type = Type.Ipv6Address) public byte[] ipv6Address; - } - - @Test - public void testIncorrectType_IpAddressWithByteArray() { - assertThrows(IllegalArgumentException.class, - () -> Struct.parse(WrongIpAddressType.class, - toByteBuffer("c0a86401" + "20010db8000300040005000600070008"))); - } - - public static class FullTypeMessage extends Struct { - @Field(order = 0, type = Type.U8) public final short u8; - @Field(order = 1, type = Type.U16) public final int u16; - @Field(order = 2, type = Type.U32) public final long u32; - @Field(order = 3, type = Type.U63) public final long u63; - @Field(order = 4, type = Type.U64) public final BigInteger u64; - @Field(order = 5, type = Type.S8) public final byte s8; - @Field(order = 6, type = Type.S16) public final short s16; - @Field(order = 7, type = Type.S32) public final int s32; - @Field(order = 8, type = Type.S64) public final long s64; - @Field(order = 9, type = Type.UBE16) public final int ube16; - @Field(order = 10, type = Type.UBE32) public final long ube32; - @Field(order = 11, type = Type.UBE63) public final long ube63; - @Field(order = 12, type = Type.UBE64) public final BigInteger ube64; - @Field(order = 13, type = Type.ByteArray, arraysize = 12) public final byte[] bytes; - @Field(order = 14, type = Type.EUI48) public final MacAddress eui48; - @Field(order = 15, type = Type.Ipv4Address) public final Inet4Address ipv4Address; - @Field(order = 16, type = Type.Ipv6Address) public final Inet6Address ipv6Address; - - FullTypeMessage(final short u8, final int u16, final long u32, final long u63, - final BigInteger u64, final byte s8, final short s16, final int s32, final long s64, - final int ube16, final long ube32, final long ube63, final BigInteger ube64, - final byte[] bytes, final MacAddress eui48, final Inet4Address ipv4Address, - final Inet6Address ipv6Address) { - this.u8 = u8; - this.u16 = u16; - this.u32 = u32; - this.u63 = u63; - this.u64 = u64; - this.s8 = s8; - this.s16 = s16; - this.s32 = s32; - this.s64 = s64; - this.ube16 = ube16; - this.ube32 = ube32; - this.ube63 = ube63; - this.ube64 = ube64; - this.bytes = bytes; - this.eui48 = eui48; - this.ipv4Address = ipv4Address; - this.ipv6Address = ipv6Address; - } - } - - private static final String FULL_TYPE_DATA = "ff" + "ffff" + "ffffffff" + "7fffffffffffffff" - + "ffffffffffffffff" + "7f" + "7fff" + "7fffffff" + "7fffffffffffffff" + "7fff" - + "7fffffff" + "7fffffffffffffff" + "ffffffffffffffff" + "20010db80003000400050006" - + "001122334455" + "c0a86401" + "20010db8000300040005000600070008"; - private static final String FULL_TYPE_DATA_DIFF_MAC = "ff" + "ffff" + "ffffffff" - + "7fffffffffffffff" + "ffffffffffffffff" + "7f" + "7fff" + "7fffffff" - + "7fffffffffffffff" + "7fff" + "7fffffff" + "7fffffffffffffff" + "ffffffffffffffff" - + "20010db80003000400050006" + "112233445566" - + "c0a86401" + "20010db8000300040005000600070008"; - private static final String FULL_TYPE_DATA_DIFF_LONG = "ff" + "ffff" + "ffffffff" - + "7ffffffffffffffe" + "ffffffffffffffff" + "7f" + "7fff" + "7fffffff" - + "7fffffffffffffff" + "7fff" + "7fffffff" + "7fffffffffffffff" + "ffffffffffffffff" - + "20010db80003000400050006" + "001122334455" - + "c0a86401" + "20010db8000300040005000600070008"; - private static final String FULL_TYPE_DATA_DIFF_INTEGER = "ff" + "ffff" + "ffffffff" - + "7fffffffffffffff" + "ffffffffffffffff" + "7f" + "7fff" + "7fffffff" - + "7fffffffffffffff" + "7fff" + "ffffff7f" + "7fffffffffffffff" + "ffffffffffffffff" - + "20010db80003000400050006" + "001122334455" - + "c0a86401" + "20010db8000300040005000600070008"; - private static final String FULL_TYPE_DATA_DIFF_IPV4 = "ff" + "ffff" + "ffffffff" - + "7fffffffffffffff" + "ffffffffffffffff" + "7f" + "7fff" + "7fffffff" - + "7fffffffffffffff" + "7fff" + "ffffff7f" + "7fffffffffffffff" + "ffffffffffffffff" - + "20010db80003000400050006" + "001122334455" - + "c0a81010" + "20010db8000300040005000600070008"; - private static final String FULL_TYPE_DATA_DIFF_IPV6 = "ff" + "ffff" + "ffffffff" - + "7fffffffffffffff" + "ffffffffffffffff" + "7f" + "7fff" + "7fffffff" - + "7fffffffffffffff" + "7fff" + "ffffff7f" + "7fffffffffffffff" + "ffffffffffffffff" - + "20010db80003000400050006" + "001122334455" - + "c0a86401" + "20010db800030004000500060007000a"; - @Test - public void testStructClass_equals() { - final FullTypeMessage msg = doParsingMessageTest(FULL_TYPE_DATA, FullTypeMessage.class, - ByteOrder.BIG_ENDIAN); - - assertEquals(255, msg.u8); - assertEquals(65535, msg.u16); - assertEquals(4294967295L, msg.u32); - assertEquals(9223372036854775807L, msg.u63); - assertEquals(new BigInteger("18446744073709551615"), msg.u64); - assertEquals(127, msg.s8); - assertEquals(32767, msg.s16); - assertEquals(2147483647, msg.s32); - assertEquals(9223372036854775807L, msg.s64); - assertEquals(32767, msg.ube16); - assertEquals(2147483647, msg.ube32); - assertEquals(9223372036854775807L, msg.ube63); - assertEquals(new BigInteger("18446744073709551615"), msg.ube64); - assertArrayEquals(TEST_PREFIX64, msg.bytes); - assertEquals(MacAddress.fromString("00:11:22:33:44:55"), msg.eui48); - assertEquals(TEST_IPV4_ADDRESS, msg.ipv4Address); - assertEquals(TEST_IPV6_ADDRESS, msg.ipv6Address); - - assertEquals(98, msg.getSize(FullTypeMessage.class)); - assertArrayEquals(toByteBuffer(FULL_TYPE_DATA).array(), - msg.writeToBytes(ByteOrder.BIG_ENDIAN)); - - final FullTypeMessage msg1 = new FullTypeMessage((short) 0xff, (int) 0xffff, - (long) 0xffffffffL, (long) 0x7fffffffffffffffL, - new BigInteger("18446744073709551615"), (byte) 0x7f, (short) 0x7fff, - (int) 0x7fffffff, (long) 0x7fffffffffffffffL, (int) 0x7fff, (long) 0x7fffffffL, - (long) 0x7fffffffffffffffL, new BigInteger("18446744073709551615"), TEST_PREFIX64, - MacAddress.fromString("00:11:22:33:44:55"), TEST_IPV4_ADDRESS, TEST_IPV6_ADDRESS); - assertTrue(msg.equals(msg1)); - } - - public static class FullTypeMessageWithDupType extends Struct { - @Field(order = 0, type = Type.U8) public final short u8; - @Field(order = 1, type = Type.U16) public final int u16; - @Field(order = 2, type = Type.U32) public final long u32; - @Field(order = 3, type = Type.S64) public final long u63; // old: U63, new: S64 - @Field(order = 4, type = Type.UBE64) public final BigInteger u64; // old: U64, new: UBE64 - @Field(order = 5, type = Type.S8) public final byte s8; - @Field(order = 6, type = Type.S16) public final short s16; - @Field(order = 7, type = Type.S32) public final int s32; - @Field(order = 8, type = Type.S64) public final long s64; - @Field(order = 9, type = Type.U16) public final int ube16; // old:UBE16, new: U16 - @Field(order = 10, type = Type.UBE32) public final long ube32; - @Field(order = 11, type = Type.UBE63) public final long ube63; - @Field(order = 12, type = Type.UBE64) public final BigInteger ube64; - @Field(order = 13, type = Type.ByteArray, arraysize = 12) public final byte[] bytes; - @Field(order = 14, type = Type.EUI48) public final MacAddress eui48; - @Field(order = 15, type = Type.Ipv4Address) public final Inet4Address ipv4Address; - @Field(order = 16, type = Type.Ipv6Address) public final Inet6Address ipv6Address; - - FullTypeMessageWithDupType(final short u8, final int u16, final long u32, final long u63, - final BigInteger u64, final byte s8, final short s16, final int s32, final long s64, - final int ube16, final long ube32, final long ube63, final BigInteger ube64, - final byte[] bytes, final MacAddress eui48, final Inet4Address ipv4Address, - final Inet6Address ipv6Address) { - this.u8 = u8; - this.u16 = u16; - this.u32 = u32; - this.u63 = u63; - this.u64 = u64; - this.s8 = s8; - this.s16 = s16; - this.s32 = s32; - this.s64 = s64; - this.ube16 = ube16; - this.ube32 = ube32; - this.ube63 = ube63; - this.ube64 = ube64; - this.bytes = bytes; - this.eui48 = eui48; - this.ipv4Address = ipv4Address; - this.ipv6Address = ipv6Address; - } - } - - @Test - public void testStructClass_notEqualWithDifferentClass() { - final FullTypeMessage msg = doParsingMessageTest(FULL_TYPE_DATA, FullTypeMessage.class, - ByteOrder.BIG_ENDIAN); - final FullTypeMessageWithDupType msg1 = doParsingMessageTest(FULL_TYPE_DATA, - FullTypeMessageWithDupType.class, ByteOrder.BIG_ENDIAN); - - assertFalse(msg.equals(msg1)); - } - - @Test - public void testStructClass_notEqualWithDifferentValue() { - final FullTypeMessage msg = doParsingMessageTest(FULL_TYPE_DATA, FullTypeMessage.class, - ByteOrder.BIG_ENDIAN); - - // With different MAC address. - final FullTypeMessage msg1 = doParsingMessageTest(FULL_TYPE_DATA_DIFF_MAC, - FullTypeMessage.class, ByteOrder.BIG_ENDIAN); - assertNotEquals(msg.eui48, msg1.eui48); - assertFalse(msg.equals(msg1)); - - // With different byte array. - final FullTypeMessage msg2 = doParsingMessageTest(FULL_TYPE_DATA, FullTypeMessage.class, - ByteOrder.BIG_ENDIAN); - msg2.bytes[5] = (byte) 42; // change one byte in the array. - assertFalse(msg.equals(msg2)); - - // With different Long primitive. - final FullTypeMessage msg3 = doParsingMessageTest(FULL_TYPE_DATA_DIFF_LONG, - FullTypeMessage.class, ByteOrder.BIG_ENDIAN); - assertNotEquals(msg.u63, msg3.u63); - assertFalse(msg.equals(msg3)); - - // With different Integer primitive. - final FullTypeMessage msg4 = doParsingMessageTest(FULL_TYPE_DATA_DIFF_INTEGER, - FullTypeMessage.class, ByteOrder.BIG_ENDIAN); - assertNotEquals(msg.ube32, msg4.ube32); - assertFalse(msg.equals(msg4)); - - // With different IPv4 address. - final FullTypeMessage msg5 = doParsingMessageTest(FULL_TYPE_DATA_DIFF_IPV4, - FullTypeMessage.class, ByteOrder.BIG_ENDIAN); - assertNotEquals(msg.ipv4Address, msg5.ipv4Address); - assertFalse(msg.equals(msg5)); - - // With different IPv6 address. - final FullTypeMessage msg6 = doParsingMessageTest(FULL_TYPE_DATA_DIFF_IPV6, - FullTypeMessage.class, ByteOrder.BIG_ENDIAN); - assertNotEquals(msg.ipv6Address, msg6.ipv6Address); - assertFalse(msg.equals(msg6)); - } - - @Test - public void testStructClass_toString() { - final String expected = "u8: 255, u16: 65535, u32: 4294967295," - + " u63: 9223372036854775807, u64: 18446744073709551615, s8: 127, s16: 32767," - + " s32: 2147483647, s64: 9223372036854775807, ube16: 32767, ube32: 2147483647," - + " ube63: 9223372036854775807, ube64: 18446744073709551615," - + " bytes: 0x20010DB80003000400050006," - + " eui48: 00:11:22:33:44:55," - + " ipv4Address: 192.168.100.1," - + " ipv6Address: 2001:db8:3:4:5:6:7:8"; - - final FullTypeMessage msg = doParsingMessageTest(FULL_TYPE_DATA, FullTypeMessage.class, - ByteOrder.BIG_ENDIAN); - assertEquals(expected, msg.toString()); - } - - @Test - public void testStructClass_toStringWithNullMember() { - final String expected = "u8: 255, u16: 65535, u32: 4294967295," - + " u63: 9223372036854775807, u64: null, s8: 127, s16: 32767," - + " s32: 2147483647, s64: 9223372036854775807, ube16: 32767, ube32: 2147483647," - + " ube63: 9223372036854775807, ube64: 18446744073709551615," - + " bytes: null, eui48: null, ipv4Address: 192.168.100.1," - + " ipv6Address: null"; - - final FullTypeMessage msg = new FullTypeMessage((short) 0xff, (int) 0xffff, - (long) 0xffffffffL, (long) 0x7fffffffffffffffL, - null /* u64 */, (byte) 0x7f, (short) 0x7fff, - (int) 0x7fffffff, (long) 0x7fffffffffffffffL, (int) 0x7fff, (long) 0x7fffffffL, - (long) 0x7fffffffffffffffL, new BigInteger("18446744073709551615"), - null /* bytes */, null /* eui48 */, TEST_IPV4_ADDRESS, null /* ipv6Address */); - assertEquals(expected, msg.toString()); - } - - @Test - public void testStructClass_hashcode() { - final FullTypeMessage msg = doParsingMessageTest(FULL_TYPE_DATA, FullTypeMessage.class, - ByteOrder.BIG_ENDIAN); - final FullTypeMessage msg1 = doParsingMessageTest(FULL_TYPE_DATA, FullTypeMessage.class, - ByteOrder.BIG_ENDIAN); - - assertNotEquals(0, msg.hashCode()); - assertNotEquals(0, msg1.hashCode()); - assertTrue(msg.equals(msg1)); - assertEquals(msg.hashCode(), msg1.hashCode()); - } - - public static class InvalidByteArray extends Struct { - @Field(order = 0, type = Type.ByteArray, arraysize = 12) public byte[] bytes; - } - - @Test - public void testStructClass_WrongByteArraySize() { - final InvalidByteArray msg = doParsingMessageTest("20010db80003000400050006", - InvalidByteArray.class, ByteOrder.BIG_ENDIAN); - - // Actual byte array size doesn't match the size declared in the annotation. - msg.bytes = new byte[16]; - assertThrows(IllegalStateException.class, () -> msg.writeToBytes()); - - final ByteBuffer output = ByteBuffer.allocate(Struct.getSize(InvalidByteArray.class)); - output.order(ByteOrder.LITTLE_ENDIAN); - assertThrows(IllegalStateException.class, () -> msg.writeToByteBuffer(output)); - } - - @Test - public void testStructClass_NullByteArray() { - final InvalidByteArray msg = doParsingMessageTest("20010db80003000400050006", - InvalidByteArray.class, ByteOrder.BIG_ENDIAN); - - msg.bytes = null; - assertThrows(NullPointerException.class, () -> msg.writeToBytes()); - - final ByteBuffer output = ByteBuffer.allocate(Struct.getSize(InvalidByteArray.class)); - output.order(ByteOrder.LITTLE_ENDIAN); - assertThrows(NullPointerException.class, () -> msg.writeToByteBuffer(output)); - } - - @Test - public void testStructClass_ParsingByteArrayAfterInitialization() { - InvalidByteArray msg = new InvalidByteArray(); - msg.bytes = new byte[]{(byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03}; - - // Although bytes member has been initialized with the length different with - // annotation size, parsing from ByteBuffer will get bytes member have the - // reference to byte array with correct size. - msg = doParsingMessageTest("20010db80003000400050006", InvalidByteArray.class, - ByteOrder.BIG_ENDIAN); - assertArrayEquals(TEST_PREFIX64, msg.bytes); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/TrackRecordTest.kt b/common/tests/unit/src/com/android/net/module/util/TrackRecordTest.kt deleted file mode 100644 index 8e320d0d..00000000 --- a/common/tests/unit/src/com/android/net/module/util/TrackRecordTest.kt +++ /dev/null @@ -1,447 +0,0 @@ -/* - * Copyright (C) 2019 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.net.module.util - -import com.android.testutils.ConcurrentInterpreter -import com.android.testutils.INTERPRET_TIME_UNIT -import com.android.testutils.InterpretException -import com.android.testutils.InterpretMatcher -import com.android.testutils.SyntaxException -import com.android.testutils.__FILE__ -import com.android.testutils.__LINE__ -import com.android.testutils.intArg -import com.android.testutils.strArg -import com.android.testutils.timeArg -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.JUnit4 -import java.util.concurrent.CyclicBarrier -import java.util.concurrent.TimeUnit -import java.util.concurrent.atomic.AtomicInteger -import kotlin.system.measureTimeMillis -import kotlin.test.assertEquals -import kotlin.test.assertFailsWith -import kotlin.test.assertFalse -import kotlin.test.assertNotEquals -import kotlin.test.assertNull -import kotlin.test.assertTrue -import kotlin.test.fail - -val TEST_VALUES = listOf(4, 13, 52, 94, 41, 68, 11, 13, 51, 0, 91, 94, 33, 98, 14) -const val ABSENT_VALUE = 2 -// Caution in changing these : some tests rely on the fact that TEST_TIMEOUT > 2 * SHORT_TIMEOUT -// and LONG_TIMEOUT > 2 * TEST_TIMEOUT -const val SHORT_TIMEOUT = 40L // ms -const val TEST_TIMEOUT = 200L // ms -const val LONG_TIMEOUT = 5000L // ms - -@RunWith(JUnit4::class) -class TrackRecordTest { - @Test - fun testAddAndSizeAndGet() { - val repeats = 22 // arbitrary - val record = ArrayTrackRecord<Int>() - assertEquals(0, record.size) - repeat(repeats) { i -> record.add(i + 2) } - assertEquals(repeats, record.size) - record.add(2) - assertEquals(repeats + 1, record.size) - - assertEquals(11, record[9]) - assertEquals(11, record.getOrNull(9)) - assertEquals(2, record[record.size - 1]) - assertEquals(2, record.getOrNull(record.size - 1)) - - assertFailsWith<IndexOutOfBoundsException> { record[800] } - assertFailsWith<IndexOutOfBoundsException> { record[-1] } - assertFailsWith<IndexOutOfBoundsException> { record[repeats + 1] } - assertNull(record.getOrNull(800)) - assertNull(record.getOrNull(-1)) - assertNull(record.getOrNull(repeats + 1)) - assertNull(record.getOrNull(800) { true }) - assertNull(record.getOrNull(-1) { true }) - assertNull(record.getOrNull(repeats + 1) { true }) - } - - @Test - fun testIndexOf() { - val record = ArrayTrackRecord<Int>() - TEST_VALUES.forEach { record.add(it) } - with(record) { - assertEquals(9, indexOf(0)) - assertEquals(9, lastIndexOf(0)) - assertEquals(1, indexOf(13)) - assertEquals(7, lastIndexOf(13)) - assertEquals(3, indexOf(94)) - assertEquals(11, lastIndexOf(94)) - assertEquals(-1, indexOf(ABSENT_VALUE)) - assertEquals(-1, lastIndexOf(ABSENT_VALUE)) - } - } - - @Test - fun testContains() { - val record = ArrayTrackRecord<Int>() - TEST_VALUES.forEach { record.add(it) } - TEST_VALUES.forEach { assertTrue(record.contains(it)) } - assertFalse(record.contains(ABSENT_VALUE)) - assertTrue(record.containsAll(TEST_VALUES)) - assertTrue(record.containsAll(TEST_VALUES.sorted())) - assertTrue(record.containsAll(TEST_VALUES.sortedDescending())) - assertTrue(record.containsAll(TEST_VALUES.distinct())) - assertTrue(record.containsAll(TEST_VALUES.subList(0, TEST_VALUES.size / 2))) - assertTrue(record.containsAll(TEST_VALUES.subList(0, TEST_VALUES.size / 2).sorted())) - assertTrue(record.containsAll(listOf())) - assertFalse(record.containsAll(listOf(ABSENT_VALUE))) - assertFalse(record.containsAll(TEST_VALUES + listOf(ABSENT_VALUE))) - } - - @Test - fun testEmpty() { - val record = ArrayTrackRecord<Int>() - assertTrue(record.isEmpty()) - record.add(1) - assertFalse(record.isEmpty()) - } - - @Test - fun testIterate() { - val record = ArrayTrackRecord<Int>() - record.forEach { fail("Expected nothing to iterate") } - TEST_VALUES.forEach { record.add(it) } - // zip relies on the iterator (this calls extension function Iterable#zip(Iterable)) - record.zip(TEST_VALUES).forEach { assertEquals(it.first, it.second) } - // Also test reverse iteration (to test hasPrevious() and friends) - record.reversed().zip(TEST_VALUES.reversed()).forEach { assertEquals(it.first, it.second) } - } - - @Test - fun testIteratorIsSnapshot() { - val record = ArrayTrackRecord<Int>() - TEST_VALUES.forEach { record.add(it) } - val iterator = record.iterator() - val expectedSize = record.size - record.add(ABSENT_VALUE) - record.add(ABSENT_VALUE) - var measuredSize = 0 - iterator.forEach { - ++measuredSize - assertNotEquals(ABSENT_VALUE, it) - } - assertEquals(expectedSize, measuredSize) - } - - @Test - fun testSublist() { - val record = ArrayTrackRecord<Int>() - TEST_VALUES.forEach { record.add(it) } - assertEquals(record.subList(3, record.size - 3), - TEST_VALUES.subList(3, TEST_VALUES.size - 3)) - } - - fun testPollReturnsImmediately(record: TrackRecord<Int>) { - record.add(4) - val elapsed = measureTimeMillis { assertEquals(4, record.poll(LONG_TIMEOUT, 0)) } - // Should not have waited at all, in fact. - assertTrue(elapsed < LONG_TIMEOUT) - record.add(7) - record.add(9) - // Can poll multiple times for the same position, in whatever order - assertEquals(9, record.poll(0, 2)) - assertEquals(7, record.poll(Long.MAX_VALUE, 1)) - assertEquals(9, record.poll(0, 2)) - assertEquals(4, record.poll(0, 0)) - assertEquals(9, record.poll(0, 2) { it > 5 }) - assertEquals(7, record.poll(0, 0) { it > 5 }) - } - - @Test - fun testPollReturnsImmediately() { - testPollReturnsImmediately(ArrayTrackRecord()) - testPollReturnsImmediately(ArrayTrackRecord<Int>().newReadHead()) - } - - @Test - fun testPollTimesOut() { - val record = ArrayTrackRecord<Int>() - var delay = measureTimeMillis { assertNull(record.poll(SHORT_TIMEOUT, 0)) } - assertTrue(delay >= SHORT_TIMEOUT, "Delay $delay < $SHORT_TIMEOUT") - delay = measureTimeMillis { assertNull(record.poll(SHORT_TIMEOUT, 0) { it < 10 }) } - assertTrue(delay >= SHORT_TIMEOUT) - } - - @Test - fun testConcurrentPollDisallowed() { - val failures = AtomicInteger(0) - val readHead = ArrayTrackRecord<Int>().newReadHead() - val barrier = CyclicBarrier(2) - Thread { - barrier.await(LONG_TIMEOUT, TimeUnit.MILLISECONDS) // barrier 1 - try { - readHead.poll(LONG_TIMEOUT) - } catch (e: ConcurrentModificationException) { - failures.incrementAndGet() - // Unblock the other thread - readHead.add(0) - } - }.start() - barrier.await() // barrier 1 - try { - readHead.poll(LONG_TIMEOUT) - } catch (e: ConcurrentModificationException) { - failures.incrementAndGet() - // Unblock the other thread - readHead.add(0) - } - // One of the threads must have gotten an exception. - assertEquals(failures.get(), 1) - } - - @Test - fun testPollWakesUp() { - val record = ArrayTrackRecord<Int>() - val barrier = CyclicBarrier(2) - Thread { - barrier.await(LONG_TIMEOUT, TimeUnit.MILLISECONDS) // barrier 1 - barrier.await() // barrier 2 - Thread.sleep(SHORT_TIMEOUT * 2) - record.add(31) - }.start() - barrier.await() // barrier 1 - // Should find the element in more than SHORT_TIMEOUT but less than TEST_TIMEOUT - var delay = measureTimeMillis { - barrier.await() // barrier 2 - assertEquals(31, record.poll(TEST_TIMEOUT, 0)) - } - assertTrue(delay in SHORT_TIMEOUT..TEST_TIMEOUT) - // Polling for an element already added in anothe thread (pos 0) : should return immediately - delay = measureTimeMillis { assertEquals(31, record.poll(TEST_TIMEOUT, 0)) } - assertTrue(delay < TEST_TIMEOUT, "Delay $delay > $TEST_TIMEOUT") - // Waiting for an element that never comes - delay = measureTimeMillis { assertNull(record.poll(SHORT_TIMEOUT, 1)) } - assertTrue(delay >= SHORT_TIMEOUT, "Delay $delay < $SHORT_TIMEOUT") - // Polling for an element that doesn't match what is already there - delay = measureTimeMillis { assertNull(record.poll(SHORT_TIMEOUT, 0) { it < 10 }) } - assertTrue(delay >= SHORT_TIMEOUT) - } - - // Just make sure the interpreter actually throws an exception when the spec - // does not conform to the behavior. The interpreter is just a tool to test a - // tool used for a tool for test, let's not have hundreds of tests for it ; - // if it's broken one of the tests using it will break. - @Test - fun testInterpreter() { - val interpretLine = __LINE__ + 2 - try { - TRTInterpreter.interpretTestSpec(useReadHeads = true, spec = """ - add(4) | poll(1, 0) = 5 - """) - fail("This spec should have thrown") - } catch (e: InterpretException) { - assertTrue(e.cause is AssertionError) - assertEquals(interpretLine + 1, e.stackTrace[0].lineNumber) - assertTrue(e.stackTrace[0].fileName.contains(__FILE__)) - assertTrue(e.stackTrace[0].methodName.contains("testInterpreter")) - assertTrue(e.stackTrace[0].methodName.contains("thread1")) - } - } - - @Test - fun testMultipleAdds() { - TRTInterpreter.interpretTestSpec(useReadHeads = false, spec = """ - add(2) | | | - | add(4) | | - | | add(6) | - | | | add(8) - poll(0, 0) = 2 time 0..1 | poll(0, 0) = 2 | poll(0, 0) = 2 | poll(0, 0) = 2 - poll(0, 1) = 4 time 0..1 | poll(0, 1) = 4 | poll(0, 1) = 4 | poll(0, 1) = 4 - poll(0, 2) = 6 time 0..1 | poll(0, 2) = 6 | poll(0, 2) = 6 | poll(0, 2) = 6 - poll(0, 3) = 8 time 0..1 | poll(0, 3) = 8 | poll(0, 3) = 8 | poll(0, 3) = 8 - """) - } - - @Test - fun testConcurrentAdds() { - TRTInterpreter.interpretTestSpec(useReadHeads = false, spec = """ - add(2) | add(4) | add(6) | add(8) - add(1) | add(3) | add(5) | add(7) - poll(0, 1) is even | poll(0, 0) is even | poll(0, 3) is even | poll(0, 2) is even - poll(0, 5) is odd | poll(0, 4) is odd | poll(0, 7) is odd | poll(0, 6) is odd - """) - } - - @Test - fun testMultiplePoll() { - TRTInterpreter.interpretTestSpec(useReadHeads = false, spec = """ - add(4) | poll(1, 0) = 4 - | poll(0, 1) = null time 0..1 - | poll(1, 1) = null time 1..2 - sleep; add(7) | poll(2, 1) = 7 time 1..2 - sleep; add(18) | poll(2, 2) = 18 time 1..2 - """) - } - - @Test - fun testMultiplePollWithPredicate() { - TRTInterpreter.interpretTestSpec(useReadHeads = false, spec = """ - | poll(1, 0) = null | poll(1, 0) = null - add(6) | poll(1, 0) = 6 | - add(11) | poll(1, 0) { > 20 } = null | poll(1, 0) { = 11 } = 11 - | poll(1, 0) { > 8 } = 11 | - """) - } - - @Test - fun testMultipleReadHeads() { - TRTInterpreter.interpretTestSpec(useReadHeads = true, spec = """ - | poll() = null | poll() = null | poll() = null - add(5) | | poll() = 5 | - | poll() = 5 | | - add(8) | poll() = 8 | poll() = 8 | - | | | poll() = 5 - | | | poll() = 8 - | | | poll() = null - | | poll() = null | - """) - } - - @Test - fun testReadHeadPollWithPredicate() { - TRTInterpreter.interpretTestSpec(useReadHeads = true, spec = """ - add(5) | poll() { < 0 } = null - | poll() { > 5 } = null - add(10) | - | poll() { = 5 } = null // The "5" was skipped in the previous line - add(15) | poll() { > 8 } = 15 // The "10" was skipped in the previous line - | poll(1, 0) { > 8 } = 10 // 10 is the first element after pos 0 matching > 8 - """) - } - - @Test - fun testPollImmediatelyAdvancesReadhead() { - TRTInterpreter.interpretTestSpec(useReadHeads = true, spec = """ - add(1) | add(2) | add(3) | add(4) - mark = 0 | poll(0) { > 3 } = 4 | | - poll(0) { > 10 } = null | | | - mark = 4 | | | - poll() = null | | | - """) - } - - @Test - fun testParallelReadHeads() { - TRTInterpreter.interpretTestSpec(useReadHeads = true, spec = """ - mark = 0 | mark = 0 | mark = 0 | mark = 0 - add(2) | | | - | add(4) | | - | | add(6) | - | | | add(8) - poll() = 2 | poll() = 2 | poll() = 2 | poll() = 2 - poll() = 4 | poll() = 4 | poll() = 4 | poll() = 4 - poll() = 6 | poll() = 6 | poll() = 6 | mark = 2 - poll() = 8 | poll() = 8 | mark = 3 | poll() = 6 - mark = 4 | mark = 4 | poll() = 8 | poll() = 8 - """) - } - - @Test - fun testPeek() { - TRTInterpreter.interpretTestSpec(useReadHeads = true, spec = """ - add(2) | | | - | add(4) | | - | | add(6) | - | | | add(8) - peek() = 2 | poll() = 2 | poll() = 2 | peek() = 2 - peek() = 2 | peek() = 4 | poll() = 4 | peek() = 2 - peek() = 2 | peek() = 4 | peek() = 6 | poll() = 2 - peek() = 2 | mark = 1 | mark = 2 | poll() = 4 - mark = 0 | peek() = 4 | peek() = 6 | peek() = 6 - poll() = 2 | poll() = 4 | poll() = 6 | poll() = 6 - poll() = 4 | mark = 2 | poll() = 8 | peek() = 8 - peek() = 6 | peek() = 6 | peek() = null | mark = 3 - """) - } -} - -private object TRTInterpreter : ConcurrentInterpreter<TrackRecord<Int>>(interpretTable) { - fun interpretTestSpec(spec: String, useReadHeads: Boolean) = if (useReadHeads) { - interpretTestSpec(spec, initial = ArrayTrackRecord(), - threadTransform = { (it as ArrayTrackRecord).newReadHead() }) - } else { - interpretTestSpec(spec, ArrayTrackRecord()) - } -} - -/* - * Quick ref of supported expressions : - * sleep(x) : sleeps for x time units and returns Unit ; sleep alone means sleep(1) - * add(x) : calls and returns TrackRecord#add. - * poll(time, pos) [{ predicate }] : calls and returns TrackRecord#poll(x time units, pos). - * Optionally, a predicate may be specified. - * poll() [{ predicate }] : calls and returns ReadHead#poll(1 time unit). Optionally, a predicate - * may be specified. - * EXPR = VALUE : asserts that EXPR equals VALUE. EXPR is interpreted. VALUE can either be the - * string "null" or an int. Returns Unit. - * EXPR time x..y : measures the time taken by EXPR and asserts it took at least x and at most - * y time units. - * predicate must be one of "= x", "< x" or "> x". - */ -private val interpretTable = listOf<InterpretMatcher<TrackRecord<Int>>>( - // Interpret "XXX is odd" : run XXX and assert its return value is odd ("even" works too) - Regex("(.*)\\s+is\\s+(even|odd)") to { i, t, r -> - i.interpret(r.strArg(1), t).also { - assertEquals((it as Int) % 2, if ("even" == r.strArg(2)) 0 else 1) - } - }, - // Interpret "add(XXX)" as TrackRecord#add(int) - Regex("""add\((\d+)\)""") to { i, t, r -> - t.add(r.intArg(1)) - }, - // Interpret "poll(x, y)" as TrackRecord#poll(timeout = x * INTERPRET_TIME_UNIT, pos = y) - // Accepts an optional {} argument for the predicate (see makePredicate for syntax) - Regex("""poll\((\d+),\s*(\d+)\)\s*(\{.*\})?""") to { i, t, r -> - t.poll(r.timeArg(1), r.intArg(2), makePredicate(r.strArg(3))) - }, - // ReadHead#poll. If this throws in the cast, the code is malformed and has passed "poll()" - // in a test that takes a TrackRecord that is not a ReadHead. It's technically possible to get - // the test code to not compile instead of throw, but it's vastly more complex and this will - // fail 100% at runtime any test that would not have compiled. - Regex("""poll\((\d+)?\)\s*(\{.*\})?""") to { i, t, r -> - (if (r.strArg(1).isEmpty()) INTERPRET_TIME_UNIT else r.timeArg(1)).let { time -> - (t as ArrayTrackRecord<Int>.ReadHead).poll(time, makePredicate(r.strArg(2))) - } - }, - // ReadHead#mark. The same remarks apply as with ReadHead#poll. - Regex("mark") to { i, t, _ -> (t as ArrayTrackRecord<Int>.ReadHead).mark }, - // ReadHead#peek. The same remarks apply as with ReadHead#poll. - Regex("peek\\(\\)") to { i, t, _ -> (t as ArrayTrackRecord<Int>.ReadHead).peek() } -) - -// Parses a { = x } or { < x } or { > x } string and returns the corresponding predicate -// Returns an always-true predicate for empty and null arguments -private fun makePredicate(spec: String?): (Int) -> Boolean { - if (spec.isNullOrEmpty()) return { true } - val match = Regex("""\{\s*([<>=])\s*(\d+)\s*\}""").matchEntire(spec) - ?: throw SyntaxException("Predicate \"${spec}\"") - val arg = match.intArg(2) - return when (match.strArg(1)) { - ">" -> { i -> i > arg } - "<" -> { i -> i < arg } - "=" -> { i -> i == arg } - else -> throw RuntimeException("How did \"${spec}\" match this regexp ?") - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/async/BufferedFileTest.java b/common/tests/unit/src/com/android/net/module/util/async/BufferedFileTest.java deleted file mode 100644 index 11a74f2c..00000000 --- a/common/tests/unit/src/com/android/net/module/util/async/BufferedFileTest.java +++ /dev/null @@ -1,376 +0,0 @@ -/* - * Copyright (C) 2023 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.net.module.util.async; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.ignoreStubs; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import android.os.ParcelFileDescriptor; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.testutils.async.ReadableDataAnswer; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class BufferedFileTest { - @Mock EventManager mockEventManager; - @Mock BufferedFile.Listener mockFileListener; - @Mock AsyncFile mockAsyncFile; - @Mock ParcelFileDescriptor mockParcelFileDescriptor; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - } - - @After - public void tearDown() throws Exception { - verifyNoMoreInteractions(ignoreStubs(mockFileListener, mockAsyncFile, mockEventManager)); - } - - @Test - public void onClosed() throws Exception { - final int inboundBufferSize = 1024; - final int outboundBufferSize = 768; - - final BufferedFile file = createFile(inboundBufferSize, outboundBufferSize); - - file.onClosed(mockAsyncFile); - - verify(mockFileListener).onBufferedFileClosed(); - } - - @Test - public void continueReadingAndClose() throws Exception { - final int inboundBufferSize = 1024; - final int outboundBufferSize = 768; - - final BufferedFile file = createFile(inboundBufferSize, outboundBufferSize); - - assertEquals(inboundBufferSize, file.getInboundBufferFreeSizeForTest()); - assertEquals(outboundBufferSize, file.getOutboundBufferFreeSize()); - - file.continueReading(); - verify(mockAsyncFile).enableReadEvents(true); - - file.close(); - verify(mockAsyncFile).close(); - } - - @Test - public void enqueueOutboundData() throws Exception { - final int inboundBufferSize = 10; - final int outboundBufferSize = 250; - - final BufferedFile file = createFile(inboundBufferSize, outboundBufferSize); - - final byte[] data1 = new byte[101]; - final byte[] data2 = new byte[102]; - data1[0] = (byte) 1; - data2[0] = (byte) 2; - - assertEquals(0, file.getOutboundBufferSize()); - - final int totalLen = data1.length + data2.length; - - when(mockAsyncFile.write(any(), anyInt(), anyInt())).thenReturn(0); - assertTrue(file.enqueueOutboundData(data1, 0, data1.length, null, 0, 0)); - verify(mockAsyncFile).enableWriteEvents(true); - - assertEquals(data1.length, file.getOutboundBufferSize()); - - checkAndResetMocks(); - - final ArgumentCaptor<byte[]> arrayCaptor = ArgumentCaptor.forClass(byte[].class); - final ArgumentCaptor<Integer> posCaptor = ArgumentCaptor.forClass(Integer.class); - final ArgumentCaptor<Integer> lenCaptor = ArgumentCaptor.forClass(Integer.class); - when(mockAsyncFile.write( - arrayCaptor.capture(), posCaptor.capture(), lenCaptor.capture())).thenReturn(totalLen); - - assertTrue(file.enqueueOutboundData(data2, 0, data2.length, null, 0, 0)); - - assertEquals(0, file.getInboundBuffer().size()); - assertEquals(0, file.getOutboundBufferSize()); - - assertEquals(0, posCaptor.getValue().intValue()); - assertEquals(totalLen, lenCaptor.getValue().intValue()); - assertEquals(data1[0], arrayCaptor.getValue()[0]); - assertEquals(data2[0], arrayCaptor.getValue()[data1.length]); - } - - @Test - public void enqueueOutboundData_combined() throws Exception { - final int inboundBufferSize = 10; - final int outboundBufferSize = 250; - - final BufferedFile file = createFile(inboundBufferSize, outboundBufferSize); - - final byte[] data1 = new byte[101]; - final byte[] data2 = new byte[102]; - data1[0] = (byte) 1; - data2[0] = (byte) 2; - - assertEquals(0, file.getOutboundBufferSize()); - - final int totalLen = data1.length + data2.length; - - final ArgumentCaptor<byte[]> arrayCaptor = ArgumentCaptor.forClass(byte[].class); - final ArgumentCaptor<Integer> posCaptor = ArgumentCaptor.forClass(Integer.class); - final ArgumentCaptor<Integer> lenCaptor = ArgumentCaptor.forClass(Integer.class); - when(mockAsyncFile.write( - arrayCaptor.capture(), posCaptor.capture(), lenCaptor.capture())).thenReturn(totalLen); - - assertTrue(file.enqueueOutboundData(data1, 0, data1.length, data2, 0, data2.length)); - - assertEquals(0, file.getInboundBuffer().size()); - assertEquals(0, file.getOutboundBufferSize()); - - assertEquals(0, posCaptor.getValue().intValue()); - assertEquals(totalLen, lenCaptor.getValue().intValue()); - assertEquals(data1[0], arrayCaptor.getValue()[0]); - assertEquals(data2[0], arrayCaptor.getValue()[data1.length]); - } - - @Test - public void enableWriteEvents() throws Exception { - final int inboundBufferSize = 10; - final int outboundBufferSize = 250; - - final BufferedFile file = createFile(inboundBufferSize, outboundBufferSize); - - final byte[] data1 = new byte[101]; - final byte[] data2 = new byte[102]; - final byte[] data3 = new byte[103]; - data1[0] = (byte) 1; - data2[0] = (byte) 2; - data3[0] = (byte) 3; - - assertEquals(0, file.getOutboundBufferSize()); - - // Write first 2 buffers, but fail to flush them, causing async write request. - final int data1And2Len = data1.length + data2.length; - when(mockAsyncFile.write(any(), eq(0), eq(data1And2Len))).thenReturn(0); - assertTrue(file.enqueueOutboundData(data1, 0, data1.length, data2, 0, data2.length)); - assertEquals(0, file.getInboundBuffer().size()); - assertEquals(data1And2Len, file.getOutboundBufferSize()); - verify(mockAsyncFile).enableWriteEvents(true); - - // Try to write 3rd buffers, which won't fit, then fail to flush. - when(mockAsyncFile.write(any(), eq(0), eq(data1And2Len))).thenReturn(0); - assertFalse(file.enqueueOutboundData(data3, 0, data3.length, null, 0, 0)); - assertEquals(0, file.getInboundBuffer().size()); - assertEquals(data1And2Len, file.getOutboundBufferSize()); - verify(mockAsyncFile, times(2)).enableWriteEvents(true); - - checkAndResetMocks(); - - // Simulate writeability event, and successfully flush. - final ArgumentCaptor<byte[]> arrayCaptor = ArgumentCaptor.forClass(byte[].class); - final ArgumentCaptor<Integer> posCaptor = ArgumentCaptor.forClass(Integer.class); - final ArgumentCaptor<Integer> lenCaptor = ArgumentCaptor.forClass(Integer.class); - when(mockAsyncFile.write(arrayCaptor.capture(), - posCaptor.capture(), lenCaptor.capture())).thenReturn(data1And2Len); - file.onWriteReady(mockAsyncFile); - verify(mockAsyncFile).enableWriteEvents(false); - verify(mockFileListener).onBufferedFileOutboundSpace(); - assertEquals(0, file.getOutboundBufferSize()); - - assertEquals(0, posCaptor.getValue().intValue()); - assertEquals(data1And2Len, lenCaptor.getValue().intValue()); - assertEquals(data1[0], arrayCaptor.getValue()[0]); - assertEquals(data2[0], arrayCaptor.getValue()[data1.length]); - - checkAndResetMocks(); - - // Now write, but fail to flush the third buffer. - when(mockAsyncFile.write(arrayCaptor.capture(), - posCaptor.capture(), lenCaptor.capture())).thenReturn(0); - assertTrue(file.enqueueOutboundData(data3, 0, data3.length, null, 0, 0)); - verify(mockAsyncFile).enableWriteEvents(true); - assertEquals(data3.length, file.getOutboundBufferSize()); - - assertEquals(data1And2Len, posCaptor.getValue().intValue()); - assertEquals(outboundBufferSize - data1And2Len, lenCaptor.getValue().intValue()); - assertEquals(data3[0], arrayCaptor.getValue()[data1And2Len]); - } - - @Test - public void read() throws Exception { - final int inboundBufferSize = 250; - final int outboundBufferSize = 10; - - final BufferedFile file = createFile(inboundBufferSize, outboundBufferSize); - - final byte[] data1 = new byte[101]; - final byte[] data2 = new byte[102]; - data1[0] = (byte) 1; - data2[0] = (byte) 2; - - final ReadableDataAnswer dataAnswer = new ReadableDataAnswer(data1, data2); - final ReadableByteBuffer inboundBuffer = file.getInboundBuffer(); - - when(mockAsyncFile.read(any(), anyInt(), anyInt())).thenAnswer(dataAnswer); - file.onReadReady(mockAsyncFile); - verify(mockAsyncFile).enableReadEvents(true); - verify(mockFileListener).onBufferedFileInboundData(eq(data1.length + data2.length)); - - assertEquals(0, file.getOutboundBufferSize()); - assertEquals(data1.length + data2.length, inboundBuffer.size()); - assertEquals((byte) 1, inboundBuffer.peek(0)); - assertEquals((byte) 2, inboundBuffer.peek(data1.length)); - } - - @Test - public void enableReadEvents() throws Exception { - final int inboundBufferSize = 250; - final int outboundBufferSize = 10; - - final BufferedFile file = createFile(inboundBufferSize, outboundBufferSize); - - final byte[] data1 = new byte[101]; - final byte[] data2 = new byte[102]; - final byte[] data3 = new byte[103]; - data1[0] = (byte) 1; - data2[0] = (byte) 2; - data3[0] = (byte) 3; - - final ReadableDataAnswer dataAnswer = new ReadableDataAnswer(data1, data2, data3); - final ReadableByteBuffer inboundBuffer = file.getInboundBuffer(); - - when(mockAsyncFile.read(any(), anyInt(), anyInt())).thenAnswer(dataAnswer); - file.onReadReady(mockAsyncFile); - verify(mockAsyncFile).enableReadEvents(false); - verify(mockFileListener).onBufferedFileInboundData(eq(inboundBufferSize)); - - assertEquals(0, file.getOutboundBufferSize()); - assertEquals(inboundBufferSize, inboundBuffer.size()); - assertEquals((byte) 1, inboundBuffer.peek(0)); - assertEquals((byte) 2, inboundBuffer.peek(data1.length)); - assertEquals((byte) 3, inboundBuffer.peek(data1.length + data2.length)); - - checkAndResetMocks(); - - // Cannot enable read events since the buffer is full. - file.continueReading(); - - checkAndResetMocks(); - - final byte[] tmp = new byte[inboundBufferSize]; - inboundBuffer.readBytes(tmp, 0, data1.length); - assertEquals(inboundBufferSize - data1.length, inboundBuffer.size()); - - file.continueReading(); - - inboundBuffer.readBytes(tmp, 0, data2.length); - assertEquals(inboundBufferSize - data1.length - data2.length, inboundBuffer.size()); - - when(mockAsyncFile.read(any(), anyInt(), anyInt())).thenAnswer(dataAnswer); - file.onReadReady(mockAsyncFile); - verify(mockAsyncFile, times(2)).enableReadEvents(true); - verify(mockFileListener).onBufferedFileInboundData( - eq(data1.length + data2.length + data3.length - inboundBufferSize)); - - assertEquals(data3.length, inboundBuffer.size()); - assertEquals((byte) 3, inboundBuffer.peek(0)); - } - - @Test - public void shutdownReading() throws Exception { - final int inboundBufferSize = 250; - final int outboundBufferSize = 10; - - final BufferedFile file = createFile(inboundBufferSize, outboundBufferSize); - - final byte[] data = new byte[100]; - final ReadableDataAnswer dataAnswer = new ReadableDataAnswer(data); - when(mockAsyncFile.read(any(), anyInt(), anyInt())).thenAnswer(dataAnswer); - - file.shutdownReading(); - file.onReadReady(mockAsyncFile); - - verify(mockAsyncFile).enableReadEvents(false); - - assertEquals(0, file.getInboundBuffer().size()); - assertEquals(data.length, dataAnswer.getRemainingSize()); - } - - @Test - public void shutdownReading_inCallback() throws Exception { - final int inboundBufferSize = 250; - final int outboundBufferSize = 10; - - final BufferedFile file = createFile(inboundBufferSize, outboundBufferSize); - - final byte[] data = new byte[100]; - final ReadableDataAnswer dataAnswer = new ReadableDataAnswer(data); - when(mockAsyncFile.read(any(), anyInt(), anyInt())).thenAnswer(dataAnswer); - - doAnswer(new Answer() { - @Override public Object answer(InvocationOnMock invocation) { - file.shutdownReading(); - return null; - }}).when(mockFileListener).onBufferedFileInboundData(anyInt()); - - file.onReadReady(mockAsyncFile); - - verify(mockAsyncFile).enableReadEvents(false); - - assertEquals(0, file.getInboundBuffer().size()); - assertEquals(0, dataAnswer.getRemainingSize()); - } - - private void checkAndResetMocks() { - verifyNoMoreInteractions(ignoreStubs(mockFileListener, mockAsyncFile, mockEventManager, - mockParcelFileDescriptor)); - reset(mockFileListener, mockAsyncFile, mockEventManager); - } - - private BufferedFile createFile( - int inboundBufferSize, int outboundBufferSize) throws Exception { - when(mockEventManager.registerFile(any(), any())).thenReturn(mockAsyncFile); - return BufferedFile.create( - mockEventManager, - FileHandle.fromFileDescriptor(mockParcelFileDescriptor), - mockFileListener, - inboundBufferSize, - outboundBufferSize); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/async/CircularByteBufferTest.java b/common/tests/unit/src/com/android/net/module/util/async/CircularByteBufferTest.java deleted file mode 100644 index 01abee2b..00000000 --- a/common/tests/unit/src/com/android/net/module/util/async/CircularByteBufferTest.java +++ /dev/null @@ -1,267 +0,0 @@ -/* - * 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.net.module.util.async; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.fail; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class CircularByteBufferTest { - @Test - public void writeBytes() { - final int capacity = 23; - CircularByteBuffer buffer = new CircularByteBuffer(capacity); - assertEquals(0, buffer.size()); - assertEquals(0, buffer.getDirectReadSize()); - assertEquals(capacity, buffer.freeSize()); - assertEquals(capacity, buffer.getDirectWriteSize()); - - final byte[] writeBuffer = new byte[15]; - buffer.writeBytes(writeBuffer, 0, writeBuffer.length); - - assertEquals(writeBuffer.length, buffer.size()); - assertEquals(writeBuffer.length, buffer.getDirectReadSize()); - assertEquals(capacity - writeBuffer.length, buffer.freeSize()); - assertEquals(capacity - writeBuffer.length, buffer.getDirectWriteSize()); - - buffer.clear(); - assertEquals(0, buffer.size()); - assertEquals(0, buffer.getDirectReadSize()); - assertEquals(capacity, buffer.freeSize()); - assertEquals(capacity, buffer.getDirectWriteSize()); - } - - @Test - public void writeBytes_withRollover() { - doTestReadWriteWithRollover(new BufferAccessor(false, false)); - } - - @Test - public void writeBytes_withFullBuffer() { - doTestReadWriteWithFullBuffer(new BufferAccessor(false, false)); - } - - @Test - public void directWriteBytes_withRollover() { - doTestReadWriteWithRollover(new BufferAccessor(true, true)); - } - - @Test - public void directWriteBytes_withFullBuffer() { - doTestReadWriteWithFullBuffer(new BufferAccessor(true, true)); - } - - private void doTestReadWriteWithFullBuffer(BufferAccessor accessor) { - CircularByteBuffer buffer = doTestReadWrite(accessor, 20, 5, 4); - - assertEquals(0, buffer.size()); - assertEquals(20, buffer.freeSize()); - } - - private void doTestReadWriteWithRollover(BufferAccessor accessor) { - // All buffer sizes are prime numbers to ensure that some read or write - // operations will roll over the end of the internal buffer. - CircularByteBuffer buffer = doTestReadWrite(accessor, 31, 13, 7); - - assertNotEquals(0, buffer.size()); - } - - private CircularByteBuffer doTestReadWrite(BufferAccessor accessor, - final int capacity, final int writeLen, final int readLen) { - CircularByteBuffer buffer = new CircularByteBuffer(capacity); - - final byte[] writeBuffer = new byte[writeLen + 2]; - final byte[] peekBuffer = new byte[readLen + 2]; - final byte[] readBuffer = new byte[readLen + 2]; - - final int numIterations = 1011; - final int maxRemaining = readLen - 1; - - int currentWriteSymbol = 0; - int expectedReadSymbol = 0; - int expectedSize = 0; - int totalWritten = 0; - int totalRead = 0; - - for (int i = 0; i < numIterations; i++) { - // Fill in with write buffers as much as possible. - while (buffer.freeSize() >= writeLen) { - currentWriteSymbol = fillTestBytes(writeBuffer, 1, writeLen, currentWriteSymbol); - accessor.writeBytes(buffer, writeBuffer, 1, writeLen); - - expectedSize += writeLen; - totalWritten += writeLen; - assertEquals(expectedSize, buffer.size()); - assertEquals(capacity - expectedSize, buffer.freeSize()); - } - - // Keep reading into read buffers while there's still data. - while (buffer.size() >= readLen) { - peekBuffer[1] = 0; - peekBuffer[2] = 0; - buffer.peekBytes(2, peekBuffer, 3, readLen - 2); - assertEquals(0, peekBuffer[1]); - assertEquals(0, peekBuffer[2]); - - peekBuffer[2] = buffer.peek(1); - - accessor.readBytes(buffer, readBuffer, 1, readLen); - peekBuffer[1] = readBuffer[1]; - - expectedReadSymbol = checkTestBytes( - readBuffer, 1, readLen, expectedReadSymbol, totalRead); - - assertArrayEquals(peekBuffer, readBuffer); - - expectedSize -= readLen; - totalRead += readLen; - assertEquals(expectedSize, buffer.size()); - assertEquals(capacity - expectedSize, buffer.freeSize()); - } - - if (buffer.size() > maxRemaining) { - fail("Too much data remaining: " + buffer.size()); - } - } - - final int maxWritten = capacity * numIterations; - final int minWritten = maxWritten / 2; - if (totalWritten < minWritten || totalWritten > maxWritten - || (totalWritten - totalRead) > maxRemaining) { - fail("Unexpected counts: read=" + totalRead + ", written=" + totalWritten - + ", minWritten=" + minWritten + ", maxWritten=" + maxWritten); - } - - return buffer; - } - - @Test - public void readBytes_overflow() { - CircularByteBuffer buffer = new CircularByteBuffer(23); - - final byte[] dataBuffer = new byte[15]; - buffer.writeBytes(dataBuffer, 0, dataBuffer.length - 2); - - try { - buffer.readBytes(dataBuffer, 0, dataBuffer.length); - assertTrue(false); - } catch (IllegalArgumentException e) { - // expected - } - - assertEquals(13, buffer.size()); - assertEquals(10, buffer.freeSize()); - } - - @Test - public void writeBytes_overflow() { - CircularByteBuffer buffer = new CircularByteBuffer(23); - - final byte[] dataBuffer = new byte[15]; - buffer.writeBytes(dataBuffer, 0, dataBuffer.length); - - try { - buffer.writeBytes(dataBuffer, 0, dataBuffer.length); - assertTrue(false); - } catch (IllegalArgumentException e) { - // expected - } - - assertEquals(15, buffer.size()); - assertEquals(8, buffer.freeSize()); - } - - private static int fillTestBytes(byte[] buffer, int pos, int len, int startValue) { - for (int i = 0; i < len; i++) { - buffer[pos + i] = (byte) (startValue & 0xFF); - startValue = (startValue + 1) % 256; - } - return startValue; - } - - private static int checkTestBytes( - byte[] buffer, int pos, int len, int startValue, int totalRead) { - for (int i = 0; i < len; i++) { - byte expectedValue = (byte) (startValue & 0xFF); - if (expectedValue != buffer[pos + i]) { - fail("Unexpected byte=" + (((int) buffer[pos + i]) & 0xFF) - + ", expected=" + (((int) expectedValue) & 0xFF) - + ", pos=" + (totalRead + i)); - } - startValue = (startValue + 1) % 256; - } - return startValue; - } - - private static final class BufferAccessor { - private final boolean mDirectRead; - private final boolean mDirectWrite; - - BufferAccessor(boolean directRead, boolean directWrite) { - mDirectRead = directRead; - mDirectWrite = directWrite; - } - - void writeBytes(CircularByteBuffer buffer, byte[] src, int pos, int len) { - if (mDirectWrite) { - while (len > 0) { - if (buffer.getDirectWriteSize() == 0) { - fail("Direct write size is zero: free=" + buffer.freeSize() - + ", size=" + buffer.size()); - } - int copyLen = Math.min(len, buffer.getDirectWriteSize()); - System.arraycopy(src, pos, buffer.getDirectWriteBuffer(), - buffer.getDirectWritePos(), copyLen); - buffer.accountForDirectWrite(copyLen); - len -= copyLen; - pos += copyLen; - } - } else { - buffer.writeBytes(src, pos, len); - } - } - - void readBytes(CircularByteBuffer buffer, byte[] dst, int pos, int len) { - if (mDirectRead) { - while (len > 0) { - if (buffer.getDirectReadSize() == 0) { - fail("Direct read size is zero: free=" + buffer.freeSize() - + ", size=" + buffer.size()); - } - int copyLen = Math.min(len, buffer.getDirectReadSize()); - System.arraycopy( - buffer.getDirectReadBuffer(), buffer.getDirectReadPos(), dst, pos, copyLen); - buffer.accountForDirectRead(copyLen); - len -= copyLen; - pos += copyLen; - } - } else { - buffer.readBytes(dst, pos, len); - } - } - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/ip/ConntrackMonitorTest.java b/common/tests/unit/src/com/android/net/module/util/ip/ConntrackMonitorTest.java deleted file mode 100644 index 7ee376c9..00000000 --- a/common/tests/unit/src/com/android/net/module/util/ip/ConntrackMonitorTest.java +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright (C) 2020 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.net.module.util.ip; - -import static android.system.OsConstants.AF_UNIX; -import static android.system.OsConstants.IPPROTO_TCP; -import static android.system.OsConstants.SOCK_DGRAM; - -import static com.android.net.module.util.netlink.ConntrackMessage.Tuple; -import static com.android.net.module.util.netlink.ConntrackMessage.TupleIpv4; -import static com.android.net.module.util.netlink.ConntrackMessage.TupleProto; -import static com.android.net.module.util.netlink.NetlinkConstants.IPCTNL_MSG_CT_DELETE; -import static com.android.net.module.util.netlink.NetlinkConstants.IPCTNL_MSG_CT_NEW; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.timeout; -import static org.mockito.Mockito.verify; - -import android.net.InetAddresses; -import android.os.ConditionVariable; -import android.os.Handler; -import android.os.HandlerThread; -import android.system.ErrnoException; -import android.system.Os; - -import androidx.annotation.NonNull; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.net.module.util.SharedLog; -import com.android.net.module.util.ip.ConntrackMonitor.ConntrackEvent; -import com.android.net.module.util.netlink.NetlinkConstants; -import com.android.net.module.util.netlink.NetlinkUtils; - -import libcore.util.HexEncoding; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.io.FileDescriptor; -import java.io.InterruptedIOException; -import java.net.Inet4Address; - -/** - * Tests for ConntrackMonitor. - */ -@RunWith(AndroidJUnit4.class) -@SmallTest -public class ConntrackMonitorTest { - private static final long TIMEOUT_MS = 10_000L; - - @Mock private SharedLog mLog; - @Mock private ConntrackMonitor.ConntrackEventConsumer mConsumer; - - private final HandlerThread mHandlerThread = new HandlerThread( - ConntrackMonitorTest.class.getSimpleName()); - - // Late init since the handler thread has been started. - private Handler mHandler; - private TestConntrackMonitor mConntrackMonitor; - - // A version of [ConntrackMonitor] that reads packets from the socket pair, and instead - // allows the test to write test packets to the socket pair via [sendMessage]. - private class TestConntrackMonitor extends ConntrackMonitor { - TestConntrackMonitor(@NonNull Handler h, @NonNull SharedLog log, - @NonNull ConntrackEventConsumer cb) { - super(h, log, cb); - - mReadFd = new FileDescriptor(); - mWriteFd = new FileDescriptor(); - try { - Os.socketpair(AF_UNIX, SOCK_DGRAM, 0, mWriteFd, mReadFd); - } catch (ErrnoException e) { - fail("Could not create socket pair: " + e); - } - } - - @Override - protected FileDescriptor createFd() { - return mReadFd; - } - - private void sendMessage(byte[] msg) { - mHandler.post(() -> { - try { - NetlinkUtils.sendMessage(mWriteFd, msg, 0 /* offset */, msg.length, - TIMEOUT_MS); - } catch (ErrnoException | InterruptedIOException e) { - fail("Unable to send netfilter message: " + e); - } - }); - } - - private final FileDescriptor mReadFd; - private final FileDescriptor mWriteFd; - } - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - - mHandlerThread.start(); - mHandler = new Handler(mHandlerThread.getLooper()); - - // ConntrackMonitor needs to be started from the handler thread. - final ConditionVariable initDone = new ConditionVariable(); - mHandler.post(() -> { - TestConntrackMonitor m = new TestConntrackMonitor(mHandler, mLog, mConsumer); - m.start(); - mConntrackMonitor = m; - - initDone.open(); - }); - if (!initDone.block(TIMEOUT_MS)) { - fail("... init monitor timed-out after " + TIMEOUT_MS + "ms"); - } - } - - @After - public void tearDown() throws Exception { - mHandlerThread.quitSafely(); - } - - public static final String CT_V4NEW_TCP_HEX = - // CHECKSTYLE:OFF IndentationCheck - // struct nlmsghdr - "8C000000" + // length = 140 - "0001" + // type = NFNL_SUBSYS_CTNETLINK (1) << 8 | IPCTNL_MSG_CT_NEW (0) - "0006" + // flags = NLM_F_CREATE (1 << 10) | NLM_F_EXCL (1 << 9) - "00000000" + // seqno = 0 - "00000000" + // pid = 0 - // struct nfgenmsg - "02" + // nfgen_family = AF_INET - "00" + // version = NFNETLINK_V0 - "1234" + // res_id = 0x1234 (big endian) - // struct nlattr - "3400" + // nla_len = 52 - "0180" + // nla_type = nested CTA_TUPLE_ORIG - // struct nlattr - "1400" + // nla_len = 20 - "0180" + // nla_type = nested CTA_TUPLE_IP - "0800 0100 C0A8500C" + // nla_type=CTA_IP_V4_SRC, ip=192.168.80.12 - "0800 0200 8C700874" + // nla_type=CTA_IP_V4_DST, ip=140.112.8.116 - // struct nlattr - "1C00" + // nla_len = 28 - "0280" + // nla_type = nested CTA_TUPLE_PROTO - "0500 0100 06 000000" + // nla_type=CTA_PROTO_NUM, proto=IPPROTO_TCP (6) - "0600 0200 F3F1 0000" + // nla_type=CTA_PROTO_SRC_PORT, port=62449 (big endian) - "0600 0300 01BB 0000" + // nla_type=CTA_PROTO_DST_PORT, port=443 (big endian) - // struct nlattr - "3400" + // nla_len = 52 - "0280" + // nla_type = nested CTA_TUPLE_REPLY - // struct nlattr - "1400" + // nla_len = 20 - "0180" + // nla_type = nested CTA_TUPLE_IP - "0800 0100 8C700874" + // nla_type=CTA_IP_V4_SRC, ip=140.112.8.116 - "0800 0200 6451B301" + // nla_type=CTA_IP_V4_DST, ip=100.81.179.1 - // struct nlattr - "1C00" + // nla_len = 28 - "0280" + // nla_type = nested CTA_TUPLE_PROTO - "0500 0100 06 000000" + // nla_type=CTA_PROTO_NUM, proto=IPPROTO_TCP (6) - "0600 0200 01BB 0000" + // nla_type=CTA_PROTO_SRC_PORT, port=443 (big endian) - "0600 0300 F3F1 0000" + // nla_type=CTA_PROTO_DST_PORT, port=62449 (big endian) - // struct nlattr - "0800" + // nla_len = 8 - "0300" + // nla_type = CTA_STATUS - "0000019e" + // nla_value = 0b110011110 (big endian) - // IPS_SEEN_REPLY (1 << 1) | IPS_ASSURED (1 << 2) | - // IPS_CONFIRMED (1 << 3) | IPS_SRC_NAT (1 << 4) | - // IPS_SRC_NAT_DONE (1 << 7) | IPS_DST_NAT_DONE (1 << 8) - // struct nlattr - "0800" + // nla_len = 8 - "0700" + // nla_type = CTA_TIMEOUT - "00000078"; // nla_value = 120 (big endian) - // CHECKSTYLE:ON IndentationCheck - public static final byte[] CT_V4NEW_TCP_BYTES = - HexEncoding.decode(CT_V4NEW_TCP_HEX.replaceAll(" ", "").toCharArray(), false); - - @NonNull - private ConntrackEvent makeTestConntrackEvent(short msgType, int status, int timeoutSec) { - final Inet4Address privateIp = - (Inet4Address) InetAddresses.parseNumericAddress("192.168.80.12"); - final Inet4Address remoteIp = - (Inet4Address) InetAddresses.parseNumericAddress("140.112.8.116"); - final Inet4Address publicIp = - (Inet4Address) InetAddresses.parseNumericAddress("100.81.179.1"); - - return new ConntrackEvent( - (short) (NetlinkConstants.NFNL_SUBSYS_CTNETLINK << 8 | msgType), - new Tuple(new TupleIpv4(privateIp, remoteIp), - new TupleProto((byte) IPPROTO_TCP, (short) 62449, (short) 443)), - new Tuple(new TupleIpv4(remoteIp, publicIp), - new TupleProto((byte) IPPROTO_TCP, (short) 443, (short) 62449)), - status, - timeoutSec); - } - - @Test - public void testConntrackEventNew() throws Exception { - final ConntrackEvent expectedEvent = makeTestConntrackEvent(IPCTNL_MSG_CT_NEW, - 0x19e /* status */, 120 /* timeoutSec */); - mConntrackMonitor.sendMessage(CT_V4NEW_TCP_BYTES); - verify(mConsumer, timeout(TIMEOUT_MS)).accept(eq(expectedEvent)); - } - - @Test - public void testConntrackEventEquals() { - final ConntrackEvent event1 = makeTestConntrackEvent(IPCTNL_MSG_CT_NEW, 1234 /* status */, - 5678 /* timeoutSec*/); - final ConntrackEvent event2 = makeTestConntrackEvent(IPCTNL_MSG_CT_NEW, 1234 /* status */, - 5678 /* timeoutSec*/); - assertEquals(event1, event2); - } - - @Test - public void testConntrackEventNotEquals() { - final ConntrackEvent e = makeTestConntrackEvent(IPCTNL_MSG_CT_NEW, 1234 /* status */, - 5678 /* timeoutSec*/); - - final ConntrackEvent typeNotEqual = new ConntrackEvent((short) (e.msgType + 1) /* diff */, - e.tupleOrig, e.tupleReply, e.status, e.timeoutSec); - assertNotEquals(e, typeNotEqual); - - final ConntrackEvent tupleOrigNotEqual = new ConntrackEvent(e.msgType, - null /* diff */, e.tupleReply, e.status, e.timeoutSec); - assertNotEquals(e, tupleOrigNotEqual); - - final ConntrackEvent tupleReplyNotEqual = new ConntrackEvent(e.msgType, - e.tupleOrig, null /* diff */, e.status, e.timeoutSec); - assertNotEquals(e, tupleReplyNotEqual); - - final ConntrackEvent statusNotEqual = new ConntrackEvent(e.msgType, - e.tupleOrig, e.tupleReply, e.status + 1 /* diff */, e.timeoutSec); - assertNotEquals(e, statusNotEqual); - - final ConntrackEvent timeoutSecNotEqual = new ConntrackEvent(e.msgType, - e.tupleOrig, e.tupleReply, e.status, e.timeoutSec + 1 /* diff */); - assertNotEquals(e, timeoutSecNotEqual); - } - - @Test - public void testToString() { - final ConntrackEvent event = makeTestConntrackEvent(IPCTNL_MSG_CT_NEW, - 0x198 /* status */, 120 /* timeoutSec */); - final String expected = "" - + "ConntrackEvent{" - + "msg_type{IPCTNL_MSG_CT_NEW}, " - + "tuple_orig{Tuple{IPPROTO_TCP: 192.168.80.12:62449 -> 140.112.8.116:443}}, " - + "tuple_reply{Tuple{IPPROTO_TCP: 140.112.8.116:443 -> 100.81.179.1:62449}}, " - + "status{408(IPS_CONFIRMED|IPS_SRC_NAT|IPS_SRC_NAT_DONE|IPS_DST_NAT_DONE)}, " - + "timeout_sec{120}}"; - assertEquals(expected, event.toString()); - } - - public static final String CT_V4DELETE_TCP_HEX = - // CHECKSTYLE:OFF IndentationCheck - // struct nlmsghdr - "84000000" + // length = 132 - "0201" + // type = NFNL_SUBSYS_CTNETLINK (1) << 8 | IPCTNL_MSG_CT_DELETE (2) - "0000" + // flags = 0 - "00000000" + // seqno = 0 - "00000000" + // pid = 0 - // struct nfgenmsg - "02" + // nfgen_family = AF_INET - "00" + // version = NFNETLINK_V0 - "1234" + // res_id = 0x1234 (big endian) - // struct nlattr - "3400" + // nla_len = 52 - "0180" + // nla_type = nested CTA_TUPLE_ORIG - // struct nlattr - "1400" + // nla_len = 20 - "0180" + // nla_type = nested CTA_TUPLE_IP - "0800 0100 C0A8500C" + // nla_type=CTA_IP_V4_SRC, ip=192.168.80.12 - "0800 0200 8C700874" + // nla_type=CTA_IP_V4_DST, ip=140.112.8.116 - // struct nlattr - "1C00" + // nla_len = 28 - "0280" + // nla_type = nested CTA_TUPLE_PROTO - "0500 0100 06 000000" + // nla_type=CTA_PROTO_NUM, proto=IPPROTO_TCP (6) - "0600 0200 F3F1 0000" + // nla_type=CTA_PROTO_SRC_PORT, port=62449 (big endian) - "0600 0300 01BB 0000" + // nla_type=CTA_PROTO_DST_PORT, port=433 (big endian) - // struct nlattr - "3400" + // nla_len = 52 - "0280" + // nla_type = nested CTA_TUPLE_REPLY - // struct nlattr - "1400" + // nla_len = 20 - "0180" + // nla_type = nested CTA_TUPLE_IP - "0800 0100 8C700874" + // nla_type=CTA_IP_V4_SRC, ip=140.112.8.116 - "0800 0200 6451B301" + // nla_type=CTA_IP_V4_DST, ip=100.81.179.1 - // struct nlattr - "1C00" + // nla_len = 28 - "0280" + // nla_type = nested CTA_TUPLE_PROTO - "0500 0100 06 000000" + // nla_type=CTA_PROTO_NUM, proto=IPPROTO_TCP (6) - "0600 0200 01BB 0000" + // nla_type=CTA_PROTO_SRC_PORT, port=433 (big endian) - "0600 0300 F3F1 0000" + // nla_type=CTA_PROTO_DST_PORT, port=62449 (big endian) - // struct nlattr - "0800" + // nla_len = 8 - "0300" + // nla_type = CTA_STATUS - "0000039E"; // nla_value = 0b1110011110 (big endian) - // IPS_SEEN_REPLY (1 << 1) | IPS_ASSURED (1 << 2) | - // IPS_CONFIRMED (1 << 3) | IPS_SRC_NAT (1 << 4) | - // IPS_SRC_NAT_DONE (1 << 7) | IPS_DST_NAT_DONE (1 << 8) | - // IPS_DYING (1 << 9) - // CHECKSTYLE:ON IndentationCheck - public static final byte[] CT_V4DELETE_TCP_BYTES = - HexEncoding.decode(CT_V4DELETE_TCP_HEX.replaceAll(" ", "").toCharArray(), false); - - @Test - public void testConntrackEventDelete() throws Exception { - final ConntrackEvent expectedEvent = - makeTestConntrackEvent(IPCTNL_MSG_CT_DELETE, 0x39e /* status */, - 0 /* timeoutSec (absent) */); - mConntrackMonitor.sendMessage(CT_V4DELETE_TCP_BYTES); - verify(mConsumer, timeout(TIMEOUT_MS)).accept(eq(expectedEvent)); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/ip/InterfaceControllerTest.java b/common/tests/unit/src/com/android/net/module/util/ip/InterfaceControllerTest.java deleted file mode 100644 index dea667d8..00000000 --- a/common/tests/unit/src/com/android/net/module/util/ip/InterfaceControllerTest.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2019 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.net.module.util.ip; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import android.net.INetd; -import android.net.InetAddresses; -import android.net.InterfaceConfigurationParcel; -import android.net.LinkAddress; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.net.module.util.SharedLog; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class InterfaceControllerTest { - private static final String TEST_IFACE = "testif"; - private static final String TEST_IPV4_ADDR = "192.168.123.28"; - private static final int TEST_PREFIXLENGTH = 31; - - @Mock private INetd mNetd; - @Mock private SharedLog mLog; - @Captor private ArgumentCaptor<InterfaceConfigurationParcel> mConfigCaptor; - - private InterfaceController mController; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - mController = new InterfaceController(TEST_IFACE, mNetd, mLog); - - doNothing().when(mNetd).interfaceSetCfg(mConfigCaptor.capture()); - } - - @Test - public void testSetIPv4Address() throws Exception { - mController.setIPv4Address( - new LinkAddress(InetAddresses.parseNumericAddress(TEST_IPV4_ADDR), - TEST_PREFIXLENGTH)); - verify(mNetd, times(1)).interfaceSetCfg(any()); - final InterfaceConfigurationParcel parcel = mConfigCaptor.getValue(); - assertEquals(TEST_IFACE, parcel.ifName); - assertEquals(TEST_IPV4_ADDR, parcel.ipv4Addr); - assertEquals(TEST_PREFIXLENGTH, parcel.prefixLength); - assertEquals("", parcel.hwAddr); - assertArrayEquals(new String[0], parcel.flags); - } - - @Test - public void testClearIPv4Address() throws Exception { - mController.clearIPv4Address(); - verify(mNetd, times(1)).interfaceSetCfg(any()); - final InterfaceConfigurationParcel parcel = mConfigCaptor.getValue(); - assertEquals(TEST_IFACE, parcel.ifName); - assertEquals("0.0.0.0", parcel.ipv4Addr); - assertEquals(0, parcel.prefixLength); - assertEquals("", parcel.hwAddr); - assertArrayEquals(new String[0], parcel.flags); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/netlink/ConntrackMessageTest.java b/common/tests/unit/src/com/android/net/module/util/netlink/ConntrackMessageTest.java deleted file mode 100644 index f02b4cb6..00000000 --- a/common/tests/unit/src/com/android/net/module/util/netlink/ConntrackMessageTest.java +++ /dev/null @@ -1,433 +0,0 @@ -/* - * 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.net.module.util.netlink; - -import static com.android.net.module.util.netlink.NetlinkConstants.IPCTNL_MSG_CT_NEW; -import static com.android.net.module.util.netlink.NetlinkConstants.NFNL_SUBSYS_CTNETLINK; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; - -import android.system.OsConstants; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import libcore.util.HexEncoding; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.Inet4Address; -import java.net.InetAddress; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.Arrays; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class ConntrackMessageTest { - private static final boolean USING_LE = (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN); - - private short makeCtType(short msgType) { - return (short) (NFNL_SUBSYS_CTNETLINK << 8 | (byte) msgType); - } - - // Example 1: TCP (192.168.43.209, 44333) -> (23.211.13.26, 443) - public static final String CT_V4UPDATE_TCP_HEX = - // struct nlmsghdr - "50000000" + // length = 80 - "0001" + // type = (1 << 8) | 0 - "0501" + // flags - "01000000" + // seqno = 1 - "00000000" + // pid = 0 - // struct nfgenmsg - "02" + // nfgen_family = AF_INET - "00" + // version = NFNETLINK_V0 - "0000" + // res_id - // struct nlattr - "3400" + // nla_len = 52 - "0180" + // nla_type = nested CTA_TUPLE_ORIG - // struct nlattr - "1400" + // nla_len = 20 - "0180" + // nla_type = nested CTA_TUPLE_IP - "0800 0100 C0A82BD1" + // nla_type=CTA_IP_V4_SRC, ip=192.168.43.209 - "0800 0200 17D30D1A" + // nla_type=CTA_IP_V4_DST, ip=23.211.13.26 - // struct nlattr - "1C00" + // nla_len = 28 - "0280" + // nla_type = nested CTA_TUPLE_PROTO - "0500 0100 06 000000" + // nla_type=CTA_PROTO_NUM, proto=6 - "0600 0200 AD2D 0000" + // nla_type=CTA_PROTO_SRC_PORT, port=44333 (big endian) - "0600 0300 01BB 0000" + // nla_type=CTA_PROTO_DST_PORT, port=443 (big endian) - // struct nlattr - "0800" + // nla_len = 8 - "0700" + // nla_type = CTA_TIMEOUT - "00069780"; // nla_value = 432000 (big endian) - public static final byte[] CT_V4UPDATE_TCP_BYTES = - HexEncoding.decode(CT_V4UPDATE_TCP_HEX.replaceAll(" ", "").toCharArray(), false); - - private byte[] makeIPv4TimeoutUpdateRequestTcp() throws Exception { - return ConntrackMessage.newIPv4TimeoutUpdateRequest( - OsConstants.IPPROTO_TCP, - (Inet4Address) InetAddress.getByName("192.168.43.209"), 44333, - (Inet4Address) InetAddress.getByName("23.211.13.26"), 443, - 432000); - } - - // Example 2: UDP (100.96.167.146, 37069) -> (216.58.197.10, 443) - public static final String CT_V4UPDATE_UDP_HEX = - // struct nlmsghdr - "50000000" + // length = 80 - "0001" + // type = (1 << 8) | 0 - "0501" + // flags - "01000000" + // seqno = 1 - "00000000" + // pid = 0 - // struct nfgenmsg - "02" + // nfgen_family = AF_INET - "00" + // version = NFNETLINK_V0 - "0000" + // res_id - // struct nlattr - "3400" + // nla_len = 52 - "0180" + // nla_type = nested CTA_TUPLE_ORIG - // struct nlattr - "1400" + // nla_len = 20 - "0180" + // nla_type = nested CTA_TUPLE_IP - "0800 0100 6460A792" + // nla_type=CTA_IP_V4_SRC, ip=100.96.167.146 - "0800 0200 D83AC50A" + // nla_type=CTA_IP_V4_DST, ip=216.58.197.10 - // struct nlattr - "1C00" + // nla_len = 28 - "0280" + // nla_type = nested CTA_TUPLE_PROTO - "0500 0100 11 000000" + // nla_type=CTA_PROTO_NUM, proto=17 - "0600 0200 90CD 0000" + // nla_type=CTA_PROTO_SRC_PORT, port=37069 (big endian) - "0600 0300 01BB 0000" + // nla_type=CTA_PROTO_DST_PORT, port=443 (big endian) - // struct nlattr - "0800" + // nla_len = 8 - "0700" + // nla_type = CTA_TIMEOUT - "000000B4"; // nla_value = 180 (big endian) - public static final byte[] CT_V4UPDATE_UDP_BYTES = - HexEncoding.decode(CT_V4UPDATE_UDP_HEX.replaceAll(" ", "").toCharArray(), false); - - private byte[] makeIPv4TimeoutUpdateRequestUdp() throws Exception { - return ConntrackMessage.newIPv4TimeoutUpdateRequest( - OsConstants.IPPROTO_UDP, - (Inet4Address) InetAddress.getByName("100.96.167.146"), 37069, - (Inet4Address) InetAddress.getByName("216.58.197.10"), 443, - 180); - } - - @Test - public void testConntrackMakeIPv4TcpTimeoutUpdate() throws Exception { - assumeTrue(USING_LE); - - final byte[] tcp = makeIPv4TimeoutUpdateRequestTcp(); - assertArrayEquals(CT_V4UPDATE_TCP_BYTES, tcp); - } - - @Test - public void testConntrackParseIPv4TcpTimeoutUpdate() throws Exception { - assumeTrue(USING_LE); - - final byte[] tcp = makeIPv4TimeoutUpdateRequestTcp(); - final ByteBuffer byteBuffer = ByteBuffer.wrap(tcp); - byteBuffer.order(ByteOrder.nativeOrder()); - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, OsConstants.NETLINK_NETFILTER); - assertNotNull(msg); - assertTrue(msg instanceof ConntrackMessage); - final ConntrackMessage conntrackMessage = (ConntrackMessage) msg; - - final StructNlMsgHdr hdr = conntrackMessage.getHeader(); - assertNotNull(hdr); - assertEquals(80, hdr.nlmsg_len); - assertEquals(makeCtType(IPCTNL_MSG_CT_NEW), hdr.nlmsg_type); - assertEquals((short) (StructNlMsgHdr.NLM_F_REPLACE | StructNlMsgHdr.NLM_F_REQUEST - | StructNlMsgHdr.NLM_F_ACK), hdr.nlmsg_flags); - assertEquals(1, hdr.nlmsg_seq); - assertEquals(0, hdr.nlmsg_pid); - - final StructNfGenMsg nfmsgHdr = conntrackMessage.nfGenMsg; - assertNotNull(nfmsgHdr); - assertEquals((byte) OsConstants.AF_INET, nfmsgHdr.nfgen_family); - assertEquals((byte) StructNfGenMsg.NFNETLINK_V0, nfmsgHdr.version); - assertEquals((short) 0, nfmsgHdr.res_id); - - assertEquals(InetAddress.parseNumericAddress("192.168.43.209"), - conntrackMessage.tupleOrig.srcIp); - assertEquals(InetAddress.parseNumericAddress("23.211.13.26"), - conntrackMessage.tupleOrig.dstIp); - assertEquals((byte) OsConstants.IPPROTO_TCP, conntrackMessage.tupleOrig.protoNum); - assertEquals((short) 44333, conntrackMessage.tupleOrig.srcPort); - assertEquals((short) 443, conntrackMessage.tupleOrig.dstPort); - - assertNull(conntrackMessage.tupleReply); - - assertEquals(0 /* absent */, conntrackMessage.status); - assertEquals(432000, conntrackMessage.timeoutSec); - } - - @Test - public void testConntrackMakeIPv4UdpTimeoutUpdate() throws Exception { - assumeTrue(USING_LE); - - final byte[] udp = makeIPv4TimeoutUpdateRequestUdp(); - assertArrayEquals(CT_V4UPDATE_UDP_BYTES, udp); - } - - @Test - public void testConntrackParseIPv4UdpTimeoutUpdate() throws Exception { - assumeTrue(USING_LE); - - final byte[] udp = makeIPv4TimeoutUpdateRequestUdp(); - final ByteBuffer byteBuffer = ByteBuffer.wrap(udp); - byteBuffer.order(ByteOrder.nativeOrder()); - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, OsConstants.NETLINK_NETFILTER); - assertNotNull(msg); - assertTrue(msg instanceof ConntrackMessage); - final ConntrackMessage conntrackMessage = (ConntrackMessage) msg; - - final StructNlMsgHdr hdr = conntrackMessage.getHeader(); - assertNotNull(hdr); - assertEquals(80, hdr.nlmsg_len); - assertEquals(makeCtType(IPCTNL_MSG_CT_NEW), hdr.nlmsg_type); - assertEquals((short) (StructNlMsgHdr.NLM_F_REPLACE | StructNlMsgHdr.NLM_F_REQUEST - | StructNlMsgHdr.NLM_F_ACK), hdr.nlmsg_flags); - assertEquals(1, hdr.nlmsg_seq); - assertEquals(0, hdr.nlmsg_pid); - - final StructNfGenMsg nfmsgHdr = conntrackMessage.nfGenMsg; - assertNotNull(nfmsgHdr); - assertEquals((byte) OsConstants.AF_INET, nfmsgHdr.nfgen_family); - assertEquals((byte) StructNfGenMsg.NFNETLINK_V0, nfmsgHdr.version); - assertEquals((short) 0, nfmsgHdr.res_id); - - assertEquals(InetAddress.parseNumericAddress("100.96.167.146"), - conntrackMessage.tupleOrig.srcIp); - assertEquals(InetAddress.parseNumericAddress("216.58.197.10"), - conntrackMessage.tupleOrig.dstIp); - assertEquals((byte) OsConstants.IPPROTO_UDP, conntrackMessage.tupleOrig.protoNum); - assertEquals((short) 37069, conntrackMessage.tupleOrig.srcPort); - assertEquals((short) 443, conntrackMessage.tupleOrig.dstPort); - - assertNull(conntrackMessage.tupleReply); - - assertEquals(0 /* absent */, conntrackMessage.status); - assertEquals(180, conntrackMessage.timeoutSec); - } - - public static final String CT_V4NEW_TCP_HEX = - // CHECKSTYLE:OFF IndentationCheck - // struct nlmsghdr - "8C000000" + // length = 140 - "0001" + // type = NFNL_SUBSYS_CTNETLINK (1) << 8 | IPCTNL_MSG_CT_NEW (0) - "0006" + // flags = NLM_F_CREATE (1 << 10) | NLM_F_EXCL (1 << 9) - "00000000" + // seqno = 0 - "00000000" + // pid = 0 - // struct nfgenmsg - "02" + // nfgen_family = AF_INET - "00" + // version = NFNETLINK_V0 - "1234" + // res_id = 0x1234 (big endian) - // struct nlattr - "3400" + // nla_len = 52 - "0180" + // nla_type = nested CTA_TUPLE_ORIG - // struct nlattr - "1400" + // nla_len = 20 - "0180" + // nla_type = nested CTA_TUPLE_IP - "0800 0100 C0A8500C" + // nla_type=CTA_IP_V4_SRC, ip=192.168.80.12 - "0800 0200 8C700874" + // nla_type=CTA_IP_V4_DST, ip=140.112.8.116 - // struct nlattr - "1C00" + // nla_len = 28 - "0280" + // nla_type = nested CTA_TUPLE_PROTO - "0500 0100 06 000000" + // nla_type=CTA_PROTO_NUM, proto=IPPROTO_TCP (6) - "0600 0200 F3F1 0000" + // nla_type=CTA_PROTO_SRC_PORT, port=62449 (big endian) - "0600 0300 01BB 0000" + // nla_type=CTA_PROTO_DST_PORT, port=443 (big endian) - // struct nlattr - "3400" + // nla_len = 52 - "0280" + // nla_type = nested CTA_TUPLE_REPLY - // struct nlattr - "1400" + // nla_len = 20 - "0180" + // nla_type = nested CTA_TUPLE_IP - "0800 0100 8C700874" + // nla_type=CTA_IP_V4_SRC, ip=140.112.8.116 - "0800 0200 6451B301" + // nla_type=CTA_IP_V4_DST, ip=100.81.179.1 - // struct nlattr - "1C00" + // nla_len = 28 - "0280" + // nla_type = nested CTA_TUPLE_PROTO - "0500 0100 06 000000" + // nla_type=CTA_PROTO_NUM, proto=IPPROTO_TCP (6) - "0600 0200 01BB 0000" + // nla_type=CTA_PROTO_SRC_PORT, port=443 (big endian) - "0600 0300 F3F1 0000" + // nla_type=CTA_PROTO_DST_PORT, port=62449 (big endian) - // struct nlattr - "0800" + // nla_len = 8 - "0300" + // nla_type = CTA_STATUS - "00000198" + // nla_value = 0b110011000 (big endian) - // IPS_CONFIRMED (1 << 3) | IPS_SRC_NAT (1 << 4) | - // IPS_SRC_NAT_DONE (1 << 7) | IPS_DST_NAT_DONE (1 << 8) - // struct nlattr - "0800" + // nla_len = 8 - "0700" + // nla_type = CTA_TIMEOUT - "00000078"; // nla_value = 120 (big endian) - // CHECKSTYLE:ON IndentationCheck - public static final byte[] CT_V4NEW_TCP_BYTES = - HexEncoding.decode(CT_V4NEW_TCP_HEX.replaceAll(" ", "").toCharArray(), false); - - @Test - public void testParseCtNew() { - assumeTrue(USING_LE); - - final ByteBuffer byteBuffer = ByteBuffer.wrap(CT_V4NEW_TCP_BYTES); - byteBuffer.order(ByteOrder.nativeOrder()); - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, OsConstants.NETLINK_NETFILTER); - assertNotNull(msg); - assertTrue(msg instanceof ConntrackMessage); - final ConntrackMessage conntrackMessage = (ConntrackMessage) msg; - - final StructNlMsgHdr hdr = conntrackMessage.getHeader(); - assertNotNull(hdr); - assertEquals(140, hdr.nlmsg_len); - assertEquals(makeCtType(IPCTNL_MSG_CT_NEW), hdr.nlmsg_type); - assertEquals((short) (StructNlMsgHdr.NLM_F_CREATE | StructNlMsgHdr.NLM_F_EXCL), - hdr.nlmsg_flags); - assertEquals(0, hdr.nlmsg_seq); - assertEquals(0, hdr.nlmsg_pid); - - final StructNfGenMsg nfmsgHdr = conntrackMessage.nfGenMsg; - assertNotNull(nfmsgHdr); - assertEquals((byte) OsConstants.AF_INET, nfmsgHdr.nfgen_family); - assertEquals((byte) StructNfGenMsg.NFNETLINK_V0, nfmsgHdr.version); - assertEquals((short) 0x1234, nfmsgHdr.res_id); - - assertEquals(InetAddress.parseNumericAddress("192.168.80.12"), - conntrackMessage.tupleOrig.srcIp); - assertEquals(InetAddress.parseNumericAddress("140.112.8.116"), - conntrackMessage.tupleOrig.dstIp); - assertEquals((byte) OsConstants.IPPROTO_TCP, conntrackMessage.tupleOrig.protoNum); - assertEquals((short) 62449, conntrackMessage.tupleOrig.srcPort); - assertEquals((short) 443, conntrackMessage.tupleOrig.dstPort); - - assertEquals(InetAddress.parseNumericAddress("140.112.8.116"), - conntrackMessage.tupleReply.srcIp); - assertEquals(InetAddress.parseNumericAddress("100.81.179.1"), - conntrackMessage.tupleReply.dstIp); - assertEquals((byte) OsConstants.IPPROTO_TCP, conntrackMessage.tupleReply.protoNum); - assertEquals((short) 443, conntrackMessage.tupleReply.srcPort); - assertEquals((short) 62449, conntrackMessage.tupleReply.dstPort); - - assertEquals(0x198, conntrackMessage.status); - assertEquals(120, conntrackMessage.timeoutSec); - } - - @Test - public void testParseTruncation() { - assumeTrue(USING_LE); - - // Expect no crash while parsing the truncated message which has been truncated to every - // length between 0 and its full length - 1. - for (int len = 0; len < CT_V4NEW_TCP_BYTES.length; len++) { - final byte[] truncated = Arrays.copyOfRange(CT_V4NEW_TCP_BYTES, 0, len); - - final ByteBuffer byteBuffer = ByteBuffer.wrap(truncated); - byteBuffer.order(ByteOrder.nativeOrder()); - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, - OsConstants.NETLINK_NETFILTER); - } - } - - @Test - public void testParseTruncationWithInvalidByte() { - assumeTrue(USING_LE); - - // Expect no crash while parsing the message which is truncated by invalid bytes. The - // message has been truncated to every length between 0 and its full length - 1. - for (byte invalid : new byte[]{(byte) 0x00, (byte) 0xff}) { - for (int len = 0; len < CT_V4NEW_TCP_BYTES.length; len++) { - final byte[] truncated = new byte[CT_V4NEW_TCP_BYTES.length]; - Arrays.fill(truncated, (byte) invalid); - System.arraycopy(CT_V4NEW_TCP_BYTES, 0, truncated, 0, len); - - final ByteBuffer byteBuffer = ByteBuffer.wrap(truncated); - byteBuffer.order(ByteOrder.nativeOrder()); - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, - OsConstants.NETLINK_NETFILTER); - } - } - } - - // Malformed conntrack messages. - public static final String CT_MALFORMED_HEX = - // CHECKSTYLE:OFF IndentationCheck - // <-- nlmsghr -->|<-nfgenmsg->|<-- CTA_TUPLE_ORIG -->| - // CTA_TUPLE_ORIG has no nla_value. - "18000000 0001 0006 00000000 00000000 02 00 0000 0400 0180" - // nested CTA_TUPLE_IP has no nla_value. - + "1C000000 0001 0006 00000000 00000000 02 00 0000 0800 0180 0400 0180" - // nested CTA_IP_V4_SRC has no nla_value. - + "20000000 0001 0006 00000000 00000000 02 00 0000 0C00 0180 0800 0180 0400 0100" - // nested CTA_TUPLE_PROTO has no nla_value. - // <-- nlmsghr -->|<-nfgenmsg->|<-- CTA_TUPLE_ORIG - + "30000000 0001 0006 00000000 00000000 02 00 0000 1C00 0180 1400 0180 0800 0100" - // -->| - + "C0A8500C 0800 0200 8C700874 0400 0280"; - // CHECKSTYLE:ON IndentationCheck - public static final byte[] CT_MALFORMED_BYTES = - HexEncoding.decode(CT_MALFORMED_HEX.replaceAll(" ", "").toCharArray(), false); - - @Test - public void testParseMalformation() { - assumeTrue(USING_LE); - - final ByteBuffer byteBuffer = ByteBuffer.wrap(CT_MALFORMED_BYTES); - byteBuffer.order(ByteOrder.nativeOrder()); - - // Expect no crash while parsing the malformed message. - int messageCount = 0; - while (byteBuffer.remaining() > 0) { - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, - OsConstants.NETLINK_NETFILTER); - messageCount++; - } - assertEquals(4, messageCount); - } - - @Test - public void testToString() { - assumeTrue(USING_LE); - - final ByteBuffer byteBuffer = ByteBuffer.wrap(CT_V4NEW_TCP_BYTES); - byteBuffer.order(ByteOrder.nativeOrder()); - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, OsConstants.NETLINK_NETFILTER); - assertNotNull(msg); - assertTrue(msg instanceof ConntrackMessage); - final ConntrackMessage conntrackMessage = (ConntrackMessage) msg; - - // Bug: "nlmsg_flags{1536(NLM_F_MATCH))" is not correct because StructNlMsgHdr - // #stringForNlMsgFlags can't convert all flags (ex: NLM_F_CREATE) and can't distinguish - // the flags which have the same value (ex: NLM_F_MATCH <0x200> and NLM_F_EXCL <0x200>). - // The flags output string should be "NLM_F_CREATE|NLM_F_EXCL" in this case. - // TODO: correct the flag converted string once #stringForNlMsgFlags does. - final String expected = "" - + "ConntrackMessage{" - + "nlmsghdr{StructNlMsgHdr{ nlmsg_len{140}, nlmsg_type{256(IPCTNL_MSG_CT_NEW)}, " - + "nlmsg_flags{1536(NLM_F_MATCH)}, nlmsg_seq{0}, nlmsg_pid{0} }}, " - + "nfgenmsg{NfGenMsg{ nfgen_family{AF_INET}, version{0}, res_id{4660} }}, " - + "tuple_orig{Tuple{IPPROTO_TCP: 192.168.80.12:62449 -> 140.112.8.116:443}}, " - + "tuple_reply{Tuple{IPPROTO_TCP: 140.112.8.116:443 -> 100.81.179.1:62449}}, " - + "status{408(IPS_CONFIRMED|IPS_SRC_NAT|IPS_SRC_NAT_DONE|IPS_DST_NAT_DONE)}, " - + "timeout_sec{120}}"; - assertEquals(expected, conntrackMessage.toString()); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/netlink/InetDiagSocketTest.java b/common/tests/unit/src/com/android/net/module/util/netlink/InetDiagSocketTest.java deleted file mode 100644 index 65e99f82..00000000 --- a/common/tests/unit/src/com/android/net/module/util/netlink/InetDiagSocketTest.java +++ /dev/null @@ -1,692 +0,0 @@ -/* - * 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.net.module.util.netlink; - -import static android.os.Process.ROOT_UID; -import static android.os.Process.SHELL_UID; -import static android.system.OsConstants.AF_INET; -import static android.system.OsConstants.AF_INET6; -import static android.system.OsConstants.IPPROTO_TCP; -import static android.system.OsConstants.IPPROTO_UDP; -import static android.system.OsConstants.NETLINK_INET_DIAG; - -import static com.android.net.module.util.netlink.NetlinkConstants.SOCK_DESTROY; -import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_ACK; -import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_DUMP; -import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_REQUEST; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import android.net.InetAddresses; -import android.util.ArraySet; -import android.util.Range; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import libcore.util.HexEncoding; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.UnknownHostException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.List; -import java.util.Set; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class InetDiagSocketTest { - // ::FFFF:192.0.2.1 - private static final byte[] SRC_V4_MAPPED_V6_ADDRESS_BYTES = { - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xff, (byte) 0xff, - (byte) 0xc0, (byte) 0x00, (byte) 0x02, (byte) 0x01, - }; - // ::FFFF:192.0.2.2 - private static final byte[] DST_V4_MAPPED_V6_ADDRESS_BYTES = { - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xff, (byte) 0xff, - (byte) 0xc0, (byte) 0x00, (byte) 0x02, (byte) 0x02, - }; - - // Hexadecimal representation of InetDiagReqV2 request. - private static final String INET_DIAG_REQ_V2_UDP_INET4_HEX = - // struct nlmsghdr - "48000000" + // length = 72 - "1400" + // type = SOCK_DIAG_BY_FAMILY - "0103" + // flags = NLM_F_REQUEST | NLM_F_DUMP - "00000000" + // seqno - "00000000" + // pid (0 == kernel) - // struct inet_diag_req_v2 - "02" + // family = AF_INET - "11" + // protcol = IPPROTO_UDP - "00" + // idiag_ext - "00" + // pad - "ffffffff" + // idiag_states - // inet_diag_sockid - "a5de" + // idiag_sport = 42462 - "b971" + // idiag_dport = 47473 - "0a006402000000000000000000000000" + // idiag_src = 10.0.100.2 - "08080808000000000000000000000000" + // idiag_dst = 8.8.8.8 - "00000000" + // idiag_if - "ffffffffffffffff"; // idiag_cookie = INET_DIAG_NOCOOKIE - private static final byte[] INET_DIAG_REQ_V2_UDP_INET4_BYTES = - HexEncoding.decode(INET_DIAG_REQ_V2_UDP_INET4_HEX.toCharArray(), false); - - @Test - public void testInetDiagReqV2UdpInet4() throws Exception { - InetSocketAddress local = new InetSocketAddress(InetAddress.getByName("10.0.100.2"), - 42462); - InetSocketAddress remote = new InetSocketAddress(InetAddress.getByName("8.8.8.8"), - 47473); - final byte[] msg = InetDiagMessage.inetDiagReqV2(IPPROTO_UDP, local, remote, AF_INET, - (short) (NLM_F_REQUEST | NLM_F_DUMP)); - assertArrayEquals(INET_DIAG_REQ_V2_UDP_INET4_BYTES, msg); - } - - // Hexadecimal representation of InetDiagReqV2 request. - private static final String INET_DIAG_REQ_V2_TCP_INET6_HEX = - // struct nlmsghdr - "48000000" + // length = 72 - "1400" + // type = SOCK_DIAG_BY_FAMILY - "0100" + // flags = NLM_F_REQUEST - "00000000" + // seqno - "00000000" + // pid (0 == kernel) - // struct inet_diag_req_v2 - "0a" + // family = AF_INET6 - "06" + // protcol = IPPROTO_TCP - "00" + // idiag_ext - "00" + // pad - "ffffffff" + // idiag_states - // inet_diag_sockid - "a5de" + // idiag_sport = 42462 - "b971" + // idiag_dport = 47473 - "fe8000000000000086c9b2fffe6aed4b" + // idiag_src = fe80::86c9:b2ff:fe6a:ed4b - "08080808000000000000000000000000" + // idiag_dst = 8.8.8.8 - "00000000" + // idiag_if - "ffffffffffffffff"; // idiag_cookie = INET_DIAG_NOCOOKIE - private static final byte[] INET_DIAG_REQ_V2_TCP_INET6_BYTES = - HexEncoding.decode(INET_DIAG_REQ_V2_TCP_INET6_HEX.toCharArray(), false); - - @Test - public void testInetDiagReqV2TcpInet6() throws Exception { - InetSocketAddress local = new InetSocketAddress( - InetAddress.getByName("fe80::86c9:b2ff:fe6a:ed4b"), 42462); - InetSocketAddress remote = new InetSocketAddress(InetAddress.getByName("8.8.8.8"), - 47473); - byte[] msg = InetDiagMessage.inetDiagReqV2(IPPROTO_TCP, local, remote, AF_INET6, - NLM_F_REQUEST); - - assertArrayEquals(INET_DIAG_REQ_V2_TCP_INET6_BYTES, msg); - } - - // Hexadecimal representation of InetDiagReqV2 request with extension, INET_DIAG_INFO. - private static final String INET_DIAG_REQ_V2_TCP_INET_INET_DIAG_HEX = - // struct nlmsghdr - "48000000" + // length = 72 - "1400" + // type = SOCK_DIAG_BY_FAMILY - "0100" + // flags = NLM_F_REQUEST - "00000000" + // seqno - "00000000" + // pid (0 == kernel) - // struct inet_diag_req_v2 - "02" + // family = AF_INET - "06" + // protcol = IPPROTO_TCP - "02" + // idiag_ext = INET_DIAG_INFO - "00" + // pad - "ffffffff" + // idiag_states - // inet_diag_sockid - "3039" + // idiag_sport = 12345 - "d431" + // idiag_dport = 54321 - "01020304000000000000000000000000" + // idiag_src = 1.2.3.4 - "08080404000000000000000000000000" + // idiag_dst = 8.8.4.4 - "00000000" + // idiag_if - "ffffffffffffffff"; // idiag_cookie = INET_DIAG_NOCOOKIE - - private static final byte[] INET_DIAG_REQ_V2_TCP_INET_INET_DIAG_BYTES = - HexEncoding.decode(INET_DIAG_REQ_V2_TCP_INET_INET_DIAG_HEX.toCharArray(), false); - private static final int TCP_ALL_STATES = 0xffffffff; - @Test - public void testInetDiagReqV2TcpInetWithExt() throws Exception { - InetSocketAddress local = new InetSocketAddress( - InetAddress.getByName("1.2.3.4"), 12345); - InetSocketAddress remote = new InetSocketAddress(InetAddress.getByName("8.8.4.4"), - 54321); - byte[] msg = InetDiagMessage.inetDiagReqV2(IPPROTO_TCP, local, remote, AF_INET, - NLM_F_REQUEST, 0 /* pad */, 2 /* idiagExt */, TCP_ALL_STATES); - - assertArrayEquals(INET_DIAG_REQ_V2_TCP_INET_INET_DIAG_BYTES, msg); - - local = new InetSocketAddress( - InetAddress.getByName("fe80::86c9:b2ff:fe6a:ed4b"), 42462); - remote = new InetSocketAddress(InetAddress.getByName("8.8.8.8"), - 47473); - msg = InetDiagMessage.inetDiagReqV2(IPPROTO_TCP, local, remote, AF_INET6, - NLM_F_REQUEST, 0 /* pad */, 0 /* idiagExt */, TCP_ALL_STATES); - - assertArrayEquals(INET_DIAG_REQ_V2_TCP_INET6_BYTES, msg); - } - - // Hexadecimal representation of InetDiagReqV2 request with no socket specified. - private static final String INET_DIAG_REQ_V2_TCP_INET6_NO_ID_SPECIFIED_HEX = - // struct nlmsghdr - "48000000" + // length = 72 - "1400" + // type = SOCK_DIAG_BY_FAMILY - "0100" + // flags = NLM_F_REQUEST - "00000000" + // seqno - "00000000" + // pid (0 == kernel) - // struct inet_diag_req_v2 - "0a" + // family = AF_INET6 - "06" + // protcol = IPPROTO_TCP - "00" + // idiag_ext - "00" + // pad - "ffffffff" + // idiag_states - // inet_diag_sockid - "0000" + // idiag_sport - "0000" + // idiag_dport - "00000000000000000000000000000000" + // idiag_src - "00000000000000000000000000000000" + // idiag_dst - "00000000" + // idiag_if - "0000000000000000"; // idiag_cookie - - private static final byte[] INET_DIAG_REQ_V2_TCP_INET6_NO_ID_SPECIFIED_BYTES = - HexEncoding.decode(INET_DIAG_REQ_V2_TCP_INET6_NO_ID_SPECIFIED_HEX.toCharArray(), false); - - @Test - public void testInetDiagReqV2TcpInet6NoIdSpecified() throws Exception { - InetSocketAddress local = new InetSocketAddress( - InetAddress.getByName("fe80::fe6a:ed4b"), 12345); - InetSocketAddress remote = new InetSocketAddress(InetAddress.getByName("8.8.4.4"), - 54321); - // Verify no socket specified if either local or remote socket address is null. - byte[] msgExt = InetDiagMessage.inetDiagReqV2(IPPROTO_TCP, null, null, AF_INET6, - NLM_F_REQUEST, 0 /* pad */, 0 /* idiagExt */, TCP_ALL_STATES); - byte[] msg; - try { - msg = InetDiagMessage.inetDiagReqV2(IPPROTO_TCP, null, remote, AF_INET6, - NLM_F_REQUEST); - fail("Both remote and local should be null, expected UnknownHostException"); - } catch (IllegalArgumentException e) { - } - - try { - msg = InetDiagMessage.inetDiagReqV2(IPPROTO_TCP, local, null, AF_INET6, - NLM_F_REQUEST, 0 /* pad */, 0 /* idiagExt */, TCP_ALL_STATES); - fail("Both remote and local should be null, expected UnknownHostException"); - } catch (IllegalArgumentException e) { - } - - msg = InetDiagMessage.inetDiagReqV2(IPPROTO_TCP, null, null, AF_INET6, - NLM_F_REQUEST, 0 /* pad */, 0 /* idiagExt */, TCP_ALL_STATES); - assertArrayEquals(INET_DIAG_REQ_V2_TCP_INET6_NO_ID_SPECIFIED_BYTES, msg); - assertArrayEquals(INET_DIAG_REQ_V2_TCP_INET6_NO_ID_SPECIFIED_BYTES, msgExt); - } - - // Hexadecimal representation of InetDiagReqV2 request with v4-mapped v6 address - private static final String INET_DIAG_REQ_V2_TCP_INET6_V4_MAPPED_HEX = - // struct nlmsghdr - "48000000" + // length = 72 - "1400" + // type = SOCK_DIAG_BY_FAMILY - "0100" + // flags = NLM_F_REQUEST - "00000000" + // seqno - "00000000" + // pid (0 == kernel) - // struct inet_diag_req_v2 - "0a" + // family = AF_INET6 - "06" + // protcol = IPPROTO_TCP - "00" + // idiag_ext - "00" + // pad - "ffffffff" + // idiag_states - // inet_diag_sockid - "a817" + // idiag_sport = 43031 - "960f" + // idiag_dport = 38415 - "00000000000000000000ffffc0000201" + // idiag_src = ::FFFF:192.0.2.1 - "00000000000000000000ffffc0000202" + // idiag_dst = ::FFFF:192.0.2.2 - "00000000" + // idiag_if - "ffffffffffffffff"; // idiag_cookie = INET_DIAG_NOCOOKIE - - private static final byte[] INET_DIAG_REQ_V2_TCP_INET6_V4_MAPPED_BYTES = - HexEncoding.decode(INET_DIAG_REQ_V2_TCP_INET6_V4_MAPPED_HEX.toCharArray(), false); - - @Test - public void testInetDiagReqV2TcpInet6V4Mapped() throws Exception { - final Inet6Address srcAddr = Inet6Address.getByAddress( - null /* host */, SRC_V4_MAPPED_V6_ADDRESS_BYTES, -1 /* scope_id */); - final Inet6Address dstAddr = Inet6Address.getByAddress( - null /* host */, DST_V4_MAPPED_V6_ADDRESS_BYTES, -1 /* scope_id */); - final byte[] msg = InetDiagMessage.inetDiagReqV2( - IPPROTO_TCP, - new InetSocketAddress(srcAddr, 43031), - new InetSocketAddress(dstAddr, 38415), - AF_INET6, - NLM_F_REQUEST); - assertArrayEquals(INET_DIAG_REQ_V2_TCP_INET6_V4_MAPPED_BYTES, msg); - } - - // Hexadecimal representation of InetDiagReqV2 request with SOCK_DESTROY - private static final String INET_DIAG_REQ_V2_TCP_INET6_DESTROY_HEX = - // struct nlmsghdr - "48000000" + // length = 72 - "1500" + // type = SOCK_DESTROY - "0500" + // flags = NLM_F_REQUEST | NLM_F_ACK - "00000000" + // seqno - "00000000" + // pid (0 == kernel) - // struct inet_diag_req_v2 - "0a" + // family = AF_INET6 - "06" + // protcol = IPPROTO_TCP - "00" + // idiag_ext - "00" + // pad - "ffffffff" + // idiag_states = TCP_ALL_STATES - // inet_diag_sockid - "a817" + // idiag_sport = 43031 - "960f" + // idiag_dport = 38415 - "20010db8000000000000000000000001" + // idiag_src = 2001:db8::1 - "20010db8000000000000000000000002" + // idiag_dst = 2001:db8::2 - "07000000" + // idiag_if = 7 - "5800000000000000"; // idiag_cookie = 88 - - private static final byte[] INET_DIAG_REQ_V2_TCP_INET6_DESTROY_BYTES = - HexEncoding.decode(INET_DIAG_REQ_V2_TCP_INET6_DESTROY_HEX.toCharArray(), false); - - @Test - public void testInetDiagReqV2TcpInet6Destroy() throws Exception { - final StructInetDiagSockId sockId = new StructInetDiagSockId( - new InetSocketAddress(InetAddresses.parseNumericAddress("2001:db8::1"), 43031), - new InetSocketAddress(InetAddresses.parseNumericAddress("2001:db8::2"), 38415), - 7 /* ifIndex */, - 88 /* cookie */); - final byte[] msg = InetDiagMessage.inetDiagReqV2(IPPROTO_TCP, sockId, AF_INET6, - SOCK_DESTROY, (short) (NLM_F_REQUEST | NLM_F_ACK), 0 /* pad */, 0 /* idiagExt */, - TCP_ALL_STATES); - - assertArrayEquals(INET_DIAG_REQ_V2_TCP_INET6_DESTROY_BYTES, msg); - } - - private void assertNlMsgHdr(StructNlMsgHdr hdr, short type, short flags, int seq, int pid) { - assertNotNull(hdr); - assertEquals(type, hdr.nlmsg_type); - assertEquals(flags, hdr.nlmsg_flags); - assertEquals(seq, hdr.nlmsg_seq); - assertEquals(pid, hdr.nlmsg_pid); - } - - private void assertInetDiagSockId(StructInetDiagSockId sockId, - InetSocketAddress locSocketAddress, InetSocketAddress remSocketAddress, - int ifIndex, long cookie) { - assertEquals(locSocketAddress, sockId.locSocketAddress); - assertEquals(remSocketAddress, sockId.remSocketAddress); - assertEquals(ifIndex, sockId.ifIndex); - assertEquals(cookie, sockId.cookie); - } - - // Hexadecimal representation of InetDiagMessage - private static final String INET_DIAG_MSG_HEX1 = - // struct nlmsghdr - "58000000" + // length = 88 - "1400" + // type = SOCK_DIAG_BY_FAMILY - "0200" + // flags = NLM_F_MULTI - "00000000" + // seqno - "f5220000" + // pid - // struct inet_diag_msg - "0a" + // family = AF_INET6 - "01" + // idiag_state = 1 - "02" + // idiag_timer = 2 - "ff" + // idiag_retrans = 255 - // inet_diag_sockid - "a817" + // idiag_sport = 43031 - "960f" + // idiag_dport = 38415 - "20010db8000000000000000000000001" + // idiag_src = 2001:db8::1 - "20010db8000000000000000000000002" + // idiag_dst = 2001:db8::2 - "07000000" + // idiag_if = 7 - "5800000000000000" + // idiag_cookie = 88 - "04000000" + // idiag_expires = 4 - "05000000" + // idiag_rqueue = 5 - "06000000" + // idiag_wqueue = 6 - "a3270000" + // idiag_uid = 10147 - "a57e19f0"; // idiag_inode = 4028202661 - - private void assertInetDiagMsg1(final NetlinkMessage msg) { - assertNotNull(msg); - - assertTrue(msg instanceof InetDiagMessage); - final InetDiagMessage inetDiagMsg = (InetDiagMessage) msg; - - assertNlMsgHdr(inetDiagMsg.getHeader(), - NetlinkConstants.SOCK_DIAG_BY_FAMILY, - StructNlMsgHdr.NLM_F_MULTI, - 0 /* seq */, - 8949 /* pid */); - - assertEquals(AF_INET6, inetDiagMsg.inetDiagMsg.idiag_family); - assertEquals(1, inetDiagMsg.inetDiagMsg.idiag_state); - assertEquals(2, inetDiagMsg.inetDiagMsg.idiag_timer); - assertEquals(255, inetDiagMsg.inetDiagMsg.idiag_retrans); - assertInetDiagSockId(inetDiagMsg.inetDiagMsg.id, - new InetSocketAddress(InetAddresses.parseNumericAddress("2001:db8::1"), 43031), - new InetSocketAddress(InetAddresses.parseNumericAddress("2001:db8::2"), 38415), - 7 /* ifIndex */, - 88 /* cookie */); - assertEquals(4, inetDiagMsg.inetDiagMsg.idiag_expires); - assertEquals(5, inetDiagMsg.inetDiagMsg.idiag_rqueue); - assertEquals(6, inetDiagMsg.inetDiagMsg.idiag_wqueue); - assertEquals(10147, inetDiagMsg.inetDiagMsg.idiag_uid); - assertEquals(4028202661L, inetDiagMsg.inetDiagMsg.idiag_inode); - } - - // Hexadecimal representation of InetDiagMessage - private static final String INET_DIAG_MSG_HEX2 = - // struct nlmsghdr - "58000000" + // length = 88 - "1400" + // type = SOCK_DIAG_BY_FAMILY - "0200" + // flags = NLM_F_MULTI - "00000000" + // seqno - "f5220000" + // pid - // struct inet_diag_msg - "0a" + // family = AF_INET6 - "02" + // idiag_state = 2 - "10" + // idiag_timer = 16 - "20" + // idiag_retrans = 32 - // inet_diag_sockid - "a845" + // idiag_sport = 43077 - "01bb" + // idiag_dport = 443 - "20010db8000000000000000000000003" + // idiag_src = 2001:db8::3 - "20010db8000000000000000000000004" + // idiag_dst = 2001:db8::4 - "08000000" + // idiag_if = 8 - "6300000000000000" + // idiag_cookie = 99 - "30000000" + // idiag_expires = 48 - "40000000" + // idiag_rqueue = 64 - "50000000" + // idiag_wqueue = 80 - "39300000" + // idiag_uid = 12345 - "851a0000"; // idiag_inode = 6789 - - private void assertInetDiagMsg2(final NetlinkMessage msg) { - assertNotNull(msg); - - assertTrue(msg instanceof InetDiagMessage); - final InetDiagMessage inetDiagMsg = (InetDiagMessage) msg; - - assertNlMsgHdr(inetDiagMsg.getHeader(), - NetlinkConstants.SOCK_DIAG_BY_FAMILY, - StructNlMsgHdr.NLM_F_MULTI, - 0 /* seq */, - 8949 /* pid */); - - assertEquals(AF_INET6, inetDiagMsg.inetDiagMsg.idiag_family); - assertEquals(2, inetDiagMsg.inetDiagMsg.idiag_state); - assertEquals(16, inetDiagMsg.inetDiagMsg.idiag_timer); - assertEquals(32, inetDiagMsg.inetDiagMsg.idiag_retrans); - assertInetDiagSockId(inetDiagMsg.inetDiagMsg.id, - new InetSocketAddress(InetAddresses.parseNumericAddress("2001:db8::3"), 43077), - new InetSocketAddress(InetAddresses.parseNumericAddress("2001:db8::4"), 443), - 8 /* ifIndex */, - 99 /* cookie */); - assertEquals(48, inetDiagMsg.inetDiagMsg.idiag_expires); - assertEquals(64, inetDiagMsg.inetDiagMsg.idiag_rqueue); - assertEquals(80, inetDiagMsg.inetDiagMsg.idiag_wqueue); - assertEquals(12345, inetDiagMsg.inetDiagMsg.idiag_uid); - assertEquals(6789, inetDiagMsg.inetDiagMsg.idiag_inode); - } - - private static final byte[] INET_DIAG_MSG_BYTES = - HexEncoding.decode(INET_DIAG_MSG_HEX1.toCharArray(), false); - - @Test - public void testParseInetDiagResponse() throws Exception { - final ByteBuffer byteBuffer = ByteBuffer.wrap(INET_DIAG_MSG_BYTES); - byteBuffer.order(ByteOrder.nativeOrder()); - assertInetDiagMsg1(NetlinkMessage.parse(byteBuffer, NETLINK_INET_DIAG)); - } - - - private static final byte[] INET_DIAG_MSG_BYTES_MULTIPLE = - HexEncoding.decode((INET_DIAG_MSG_HEX1 + INET_DIAG_MSG_HEX2).toCharArray(), false); - - @Test - public void testParseInetDiagResponseMultiple() { - final ByteBuffer byteBuffer = ByteBuffer.wrap(INET_DIAG_MSG_BYTES_MULTIPLE); - byteBuffer.order(ByteOrder.nativeOrder()); - assertInetDiagMsg1(NetlinkMessage.parse(byteBuffer, NETLINK_INET_DIAG)); - assertInetDiagMsg2(NetlinkMessage.parse(byteBuffer, NETLINK_INET_DIAG)); - } - - private static final String INET_DIAG_SOCK_ID_V4_MAPPED_V6_HEX = - "a845" + // idiag_sport = 43077 - "01bb" + // idiag_dport = 443 - "00000000000000000000ffffc0000201" + // idiag_src = ::FFFF:192.0.2.1 - "00000000000000000000ffffc0000202" + // idiag_dst = ::FFFF:192.0.2.2 - "08000000" + // idiag_if = 8 - "6300000000000000"; // idiag_cookie = 99 - - private static final byte[] INET_DIAG_SOCK_ID_V4_MAPPED_V6_BYTES = - HexEncoding.decode(INET_DIAG_SOCK_ID_V4_MAPPED_V6_HEX.toCharArray(), false); - - @Test - public void testParseAndPackInetDiagSockIdV4MappedV6() { - final ByteBuffer parseByteBuffer = ByteBuffer.wrap(INET_DIAG_SOCK_ID_V4_MAPPED_V6_BYTES); - parseByteBuffer.order(ByteOrder.nativeOrder()); - final StructInetDiagSockId diagSockId = - StructInetDiagSockId.parse(parseByteBuffer, (short) AF_INET6); - assertNotNull(diagSockId); - - final ByteBuffer packByteBuffer = - ByteBuffer.allocate(INET_DIAG_SOCK_ID_V4_MAPPED_V6_BYTES.length); - diagSockId.pack(packByteBuffer); - - // Move position to the head since ByteBuffer#equals compares the values from the current - // position. - parseByteBuffer.position(0); - packByteBuffer.position(0); - assertEquals(parseByteBuffer, packByteBuffer); - } - - // Hexadecimal representation of InetDiagMessage with v4-mapped v6 address - private static final String INET_DIAG_MSG_V4_MAPPED_V6_HEX = - // struct nlmsghdr - "58000000" + // length = 88 - "1400" + // type = SOCK_DIAG_BY_FAMILY - "0200" + // flags = NLM_F_MULTI - "00000000" + // seqno - "f5220000" + // pid - // struct inet_diag_msg - "0a" + // family = AF_INET6 - "01" + // idiag_state = 1 - "02" + // idiag_timer = 2 - "03" + // idiag_retrans = 3 - // inet_diag_sockid - "a817" + // idiag_sport = 43031 - "960f" + // idiag_dport = 38415 - "00000000000000000000ffffc0000201" + // idiag_src = ::FFFF:192.0.2.1 - "00000000000000000000ffffc0000202" + // idiag_dst = ::FFFF:192.0.2.2 - "07000000" + // idiag_if = 7 - "5800000000000000" + // idiag_cookie = 88 - "04000000" + // idiag_expires = 4 - "05000000" + // idiag_rqueue = 5 - "06000000" + // idiag_wqueue = 6 - "a3270000" + // idiag_uid = 10147 - "A57E1900"; // idiag_inode = 1670821 - - private static final byte[] INET_DIAG_MSG_V4_MAPPED_V6_BYTES = - HexEncoding.decode(INET_DIAG_MSG_V4_MAPPED_V6_HEX.toCharArray(), false); - - @Test - public void testParseInetDiagResponseV4MappedV6() throws Exception { - final ByteBuffer byteBuffer = ByteBuffer.wrap(INET_DIAG_MSG_V4_MAPPED_V6_BYTES); - byteBuffer.order(ByteOrder.nativeOrder()); - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_INET_DIAG); - - assertNotNull(msg); - assertTrue(msg instanceof InetDiagMessage); - final InetDiagMessage inetDiagMsg = (InetDiagMessage) msg; - final Inet6Address srcAddr = Inet6Address.getByAddress( - null /* host */, SRC_V4_MAPPED_V6_ADDRESS_BYTES, -1 /* scope_id */); - final Inet6Address dstAddr = Inet6Address.getByAddress( - null /* host */, DST_V4_MAPPED_V6_ADDRESS_BYTES, -1 /* scope_id */); - assertInetDiagSockId(inetDiagMsg.inetDiagMsg.id, - new InetSocketAddress(srcAddr, 43031), - new InetSocketAddress(dstAddr, 38415), - 7 /* ifIndex */, - 88 /* cookie */); - } - - private void doTestIsLoopback(InetAddress srcAddr, InetAddress dstAddr, boolean expected) { - final InetDiagMessage inetDiagMsg = new InetDiagMessage(new StructNlMsgHdr()); - inetDiagMsg.inetDiagMsg.id = new StructInetDiagSockId( - new InetSocketAddress(srcAddr, 43031), - new InetSocketAddress(dstAddr, 38415) - ); - - assertEquals(expected, InetDiagMessage.isLoopback(inetDiagMsg)); - } - - @Test - public void testIsLoopback() { - doTestIsLoopback( - InetAddresses.parseNumericAddress("127.0.0.1"), - InetAddresses.parseNumericAddress("192.0.2.1"), - true - ); - doTestIsLoopback( - InetAddresses.parseNumericAddress("192.0.2.1"), - InetAddresses.parseNumericAddress("127.7.7.7"), - true - ); - doTestIsLoopback( - InetAddresses.parseNumericAddress("::1"), - InetAddresses.parseNumericAddress("::1"), - true - ); - doTestIsLoopback( - InetAddresses.parseNumericAddress("::1"), - InetAddresses.parseNumericAddress("2001:db8::1"), - true - ); - } - - @Test - public void testIsLoopbackSameSrcDstAddress() { - doTestIsLoopback( - InetAddresses.parseNumericAddress("192.0.2.1"), - InetAddresses.parseNumericAddress("192.0.2.1"), - true - ); - doTestIsLoopback( - InetAddresses.parseNumericAddress("2001:db8::1"), - InetAddresses.parseNumericAddress("2001:db8::1"), - true - ); - } - - @Test - public void testIsLoopbackNonLoopbackSocket() { - doTestIsLoopback( - InetAddresses.parseNumericAddress("192.0.2.1"), - InetAddresses.parseNumericAddress("192.0.2.2"), - false - ); - doTestIsLoopback( - InetAddresses.parseNumericAddress("2001:db8::1"), - InetAddresses.parseNumericAddress("2001:db8::2"), - false - ); - } - - @Test - public void testIsLoopbackV4MappedV6() throws UnknownHostException { - // ::FFFF:127.1.2.3 - final byte[] addrLoopbackByte = { - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xff, (byte) 0xff, - (byte) 0x7f, (byte) 0x01, (byte) 0x02, (byte) 0x03, - }; - // ::FFFF:192.0.2.1 - final byte[] addrNonLoopbackByte1 = { - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xff, (byte) 0xff, - (byte) 0xc0, (byte) 0x00, (byte) 0x02, (byte) 0x01, - }; - // ::FFFF:192.0.2.2 - final byte[] addrNonLoopbackByte2 = { - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xff, (byte) 0xff, - (byte) 0xc0, (byte) 0x00, (byte) 0x02, (byte) 0x02, - }; - - final Inet6Address addrLoopback = Inet6Address.getByAddress(null, addrLoopbackByte, -1); - final Inet6Address addrNonLoopback1 = - Inet6Address.getByAddress(null, addrNonLoopbackByte1, -1); - final Inet6Address addrNonLoopback2 = - Inet6Address.getByAddress(null, addrNonLoopbackByte2, -1); - - doTestIsLoopback(addrLoopback, addrNonLoopback1, true); - doTestIsLoopback(addrNonLoopback1, addrNonLoopback2, false); - doTestIsLoopback(addrNonLoopback1, addrNonLoopback1, true); - } - - private void doTestContainsUid(final int uid, final Set<Range<Integer>> ranges, - final boolean expected) { - final InetDiagMessage inetDiagMsg = new InetDiagMessage(new StructNlMsgHdr()); - inetDiagMsg.inetDiagMsg.idiag_uid = uid; - assertEquals(expected, InetDiagMessage.containsUid(inetDiagMsg, ranges)); - } - - @Test - public void testContainsUid() { - doTestContainsUid(77 /* uid */, - new ArraySet<>(List.of(new Range<>(0, 100))), - true /* expected */); - doTestContainsUid(77 /* uid */, - new ArraySet<>(List.of(new Range<>(77, 77), new Range<>(100, 200))), - true /* expected */); - - doTestContainsUid(77 /* uid */, - new ArraySet<>(List.of(new Range<>(100, 200))), - false /* expected */); - doTestContainsUid(77 /* uid */, - new ArraySet<>(List.of(new Range<>(0, 76), new Range<>(78, 100))), - false /* expected */); - } - - private void doTestIsAdbSocket(final int uid, final boolean expected) { - final InetDiagMessage inetDiagMsg = new InetDiagMessage(new StructNlMsgHdr()); - inetDiagMsg.inetDiagMsg.idiag_uid = uid; - inetDiagMsg.inetDiagMsg.id = new StructInetDiagSockId( - new InetSocketAddress(InetAddresses.parseNumericAddress("2001:db8::1"), 38417), - new InetSocketAddress(InetAddresses.parseNumericAddress("2001:db8::2"), 38415) - ); - assertEquals(expected, InetDiagMessage.isAdbSocket(inetDiagMsg)); - } - - @Test - public void testIsAdbSocket() { - final int appUid = 10108; - doTestIsAdbSocket(SHELL_UID, true /* expected */); - doTestIsAdbSocket(ROOT_UID, false /* expected */); - doTestIsAdbSocket(appUid, false /* expected */); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/netlink/NduseroptMessageTest.java b/common/tests/unit/src/com/android/net/module/util/netlink/NduseroptMessageTest.java deleted file mode 100644 index 4fc5ec2e..00000000 --- a/common/tests/unit/src/com/android/net/module/util/netlink/NduseroptMessageTest.java +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (C) 2020 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.net.module.util.netlink; - -import static android.net.InetAddresses.parseNumericAddress; -import static android.system.OsConstants.AF_INET6; -import static android.system.OsConstants.NETLINK_ROUTE; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import android.net.InetAddresses; -import android.net.IpPrefix; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import libcore.util.HexEncoding; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.Inet6Address; -import java.net.InetAddress; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class NduseroptMessageTest { - - private static final byte ICMP_TYPE_RA = (byte) 134; - - private static final int IFINDEX1 = 15715755; - private static final int IFINDEX2 = 1431655765; - - // IPv6, 0 bytes of options, interface index 15715755, type 134 (RA), code 0, padding. - private static final String HDR_EMPTY = "0a00" + "0000" + "abcdef00" + "8600000000000000"; - - // IPv6, 16 bytes of options, interface index 1431655765, type 134 (RA), code 0, padding. - private static final String HDR_16BYTE = "0a00" + "1000" + "55555555" + "8600000000000000"; - - // IPv6, 32 bytes of options, interface index 1431655765, type 134 (RA), code 0, padding. - private static final String HDR_32BYTE = "0a00" + "2000" + "55555555" + "8600000000000000"; - - // PREF64 option, 2001:db8:3:4:5:6::/96, lifetime=10064 - private static final String OPT_PREF64 = "2602" + "2750" + "20010db80003000400050006"; - - // Length 20, NDUSEROPT_SRCADDR, fe80:2:3:4:5:6:7:8 - private static final String NLA_SRCADDR = "1400" + "0100" + "fe800002000300040005000600070008"; - - private static final InetAddress SADDR1 = parseNumericAddress("fe80:2:3:4:5:6:7:8%" + IFINDEX1); - private static final InetAddress SADDR2 = parseNumericAddress("fe80:2:3:4:5:6:7:8%" + IFINDEX2); - - private static final String MSG_EMPTY = HDR_EMPTY + NLA_SRCADDR; - private static final String MSG_PREF64 = HDR_16BYTE + OPT_PREF64 + NLA_SRCADDR; - - @Test - public void testParsing() { - NduseroptMessage msg = parseNduseroptMessage(toBuffer(MSG_EMPTY)); - assertMatches(AF_INET6, 0, IFINDEX1, ICMP_TYPE_RA, (byte) 0, SADDR1, msg); - assertNull(msg.option); - - msg = parseNduseroptMessage(toBuffer(MSG_PREF64)); - assertMatches(AF_INET6, 16, IFINDEX2, ICMP_TYPE_RA, (byte) 0, SADDR2, msg); - assertPref64Option("2001:db8:3:4:5:6::/96", msg.option); - } - - @Test - public void testParseWithinNetlinkMessage() throws Exception { - // A NduseroptMessage inside a netlink message. Ensure that it parses the same way both by - // parsing the netlink message via NetlinkMessage.parse() and by parsing the option itself - // with NduseroptMessage.parse(). - final String hexBytes = - "44000000440000000000000000000000" // len=68, RTM_NEWNDUSEROPT - + "0A0010001E0000008600000000000000" // IPv6, opt_bytes=16, ifindex=30, RA - + "260202580064FF9B0000000000000000" // pref64, prefix=64:ff9b::/96, 600 - + "14000100FE800000000000000250B6FFFEB7C499"; // srcaddr=fe80::250:b6ff:feb7:c499 - - ByteBuffer buf = toBuffer(hexBytes); - assertEquals(68, buf.limit()); - buf.order(ByteOrder.nativeOrder()); - - NetlinkMessage nlMsg = NetlinkMessage.parse(buf, NETLINK_ROUTE); - assertNotNull(nlMsg); - assertTrue(nlMsg instanceof NduseroptMessage); - - NduseroptMessage msg = (NduseroptMessage) nlMsg; - InetAddress srcaddr = InetAddress.getByName("fe80::250:b6ff:feb7:c499%30"); - assertMatches(AF_INET6, 16, 30, ICMP_TYPE_RA, (byte) 0, srcaddr, msg); - assertPref64Option("64:ff9b::/96", msg.option); - - final String hexBytesWithoutHeader = hexBytes.substring(StructNlMsgHdr.STRUCT_SIZE * 2); - ByteBuffer bufWithoutHeader = toBuffer(hexBytesWithoutHeader); - assertEquals(52, bufWithoutHeader.limit()); - msg = parseNduseroptMessage(bufWithoutHeader); - assertMatches(AF_INET6, 16, 30, ICMP_TYPE_RA, (byte) 0, srcaddr, msg); - assertPref64Option("64:ff9b::/96", msg.option); - } - - @Test - public void testParseRdnssOptionWithinNetlinkMessage() throws Exception { - final String hexBytes = - "4C000000440000000000000000000000" - + "0A0018001E0000008600000000000000" - + "1903000000001770FD123456789000000000000000000001" // RDNSS option - + "14000100FE800000000000000250B6FFFEB7C499"; - - ByteBuffer buf = toBuffer(hexBytes); - assertEquals(76, buf.limit()); - buf.order(ByteOrder.nativeOrder()); - - NetlinkMessage nlMsg = NetlinkMessage.parse(buf, NETLINK_ROUTE); - assertNotNull(nlMsg); - assertTrue(nlMsg instanceof NduseroptMessage); - - NduseroptMessage msg = (NduseroptMessage) nlMsg; - InetAddress srcaddr = InetAddress.getByName("fe80::250:b6ff:feb7:c499%30"); - assertMatches(AF_INET6, 24, 30, ICMP_TYPE_RA, (byte) 0, srcaddr, msg); - assertRdnssOption(msg.option, 6000 /* lifetime */, - (Inet6Address) InetAddresses.parseNumericAddress("fd12:3456:7890::1")); - } - - @Test - public void testParseTruncatedRdnssOptionWithinNetlinkMessage() throws Exception { - final String truncatedHexBytes = - "38000000440000000000000000000000" - + "0A0018001E0000008600000000000000" - + "1903000000001770FD123456789000000000000000000001"; // RDNSS option - - ByteBuffer buf = toBuffer(truncatedHexBytes); - buf.order(ByteOrder.nativeOrder()); - NetlinkMessage nlMsg = NetlinkMessage.parse(buf, NETLINK_ROUTE); - assertNull(nlMsg); - } - - @Test - public void testParseUnknownOptionWithinNetlinkMessage() throws Exception { - final String hexBytes = - "4C000000440000000000000000000000" - + "0A0018001E0000008600000000000000" - + "310300000000177006676F6F676C652E03636F6D00000000" // DNSSL option: "google.com" - + "14000100FE800000000000000250B6FFFEB7C499"; - - ByteBuffer buf = toBuffer(hexBytes); - assertEquals(76, buf.limit()); - buf.order(ByteOrder.nativeOrder()); - - NetlinkMessage nlMsg = NetlinkMessage.parse(buf, NETLINK_ROUTE); - assertNotNull(nlMsg); - assertTrue(nlMsg instanceof NduseroptMessage); - - NduseroptMessage msg = (NduseroptMessage) nlMsg; - InetAddress srcaddr = InetAddress.getByName("fe80::250:b6ff:feb7:c499%30"); - assertMatches(AF_INET6, 24, 30, ICMP_TYPE_RA, (byte) 0, srcaddr, msg); - assertEquals(NdOption.UNKNOWN, msg.option); - } - - @Test - public void testUnknownOption() { - ByteBuffer buf = toBuffer(MSG_PREF64); - // Replace the PREF64 option type (38) with an unknown option number. - final int optionStart = NduseroptMessage.STRUCT_SIZE; - assertEquals(38, buf.get(optionStart)); - buf.put(optionStart, (byte) 42); - - NduseroptMessage msg = parseNduseroptMessage(buf); - assertMatches(AF_INET6, 16, IFINDEX2, ICMP_TYPE_RA, (byte) 0, SADDR2, msg); - assertEquals(NdOption.UNKNOWN, msg.option); - - buf.flip(); - assertEquals(42, buf.get(optionStart)); - buf.put(optionStart, (byte) 38); - - msg = parseNduseroptMessage(buf); - assertMatches(AF_INET6, 16, IFINDEX2, ICMP_TYPE_RA, (byte) 0, SADDR2, msg); - assertPref64Option("2001:db8:3:4:5:6::/96", msg.option); - } - - @Test - public void testZeroLengthOption() { - // Make sure an unknown option with a 0-byte length is ignored and parsing continues with - // the address, which comes after it. - final String hexString = HDR_16BYTE + "00000000000000000000000000000000" + NLA_SRCADDR; - ByteBuffer buf = toBuffer(hexString); - assertEquals(52, buf.limit()); - NduseroptMessage msg = parseNduseroptMessage(buf); - assertMatches(AF_INET6, 16, IFINDEX2, ICMP_TYPE_RA, (byte) 0, SADDR2, msg); - assertNull(msg.option); - } - - @Test - public void testTooLongOption() { - // Make sure that if an option's length is too long, it's ignored and parsing continues with - // the address, which comes after it. - final String hexString = HDR_16BYTE + "26030000000000000000000000000000" + NLA_SRCADDR; - ByteBuffer buf = toBuffer(hexString); - assertEquals(52, buf.limit()); - NduseroptMessage msg = parseNduseroptMessage(buf); - assertMatches(AF_INET6, 16, IFINDEX2, ICMP_TYPE_RA, (byte) 0, SADDR2, msg); - assertNull(msg.option); - } - - @Test - public void testOptionsTooLong() { - // Header claims 32 bytes of options. Buffer ends before options end. - String hexString = HDR_32BYTE + OPT_PREF64; - ByteBuffer buf = toBuffer(hexString); - assertEquals(32, buf.limit()); - assertNull(NduseroptMessage.parse(toBuffer(hexString), NETLINK_ROUTE)); - - // Header claims 32 bytes of options. Buffer ends at end of options with no source address. - hexString = HDR_32BYTE + OPT_PREF64 + OPT_PREF64; - buf = toBuffer(hexString); - assertEquals(48, buf.limit()); - assertNull(NduseroptMessage.parse(toBuffer(hexString), NETLINK_ROUTE)); - } - - @Test - public void testTruncation() { - final int optLen = MSG_PREF64.length() / 2; // 1 byte = 2 hex chars - for (int len = 0; len < optLen; len++) { - ByteBuffer buf = toBuffer(MSG_PREF64.substring(0, len * 2)); - NduseroptMessage msg = parseNduseroptMessage(buf); - if (len < optLen) { - assertNull(msg); - } else { - assertNotNull(msg); - assertPref64Option("2001:db8:3:4:5:6::/96", msg.option); - } - } - } - - @Test - public void testToString() { - NduseroptMessage msg = parseNduseroptMessage(toBuffer(MSG_PREF64)); - assertNotNull(msg); - assertEquals("Nduseroptmsg(10, 16, 1431655765, 134, 0, fe80:2:3:4:5:6:7:8%1431655765)", - msg.toString()); - } - - // Convenience method to parse a NduseroptMessage that's not part of a netlink message. - private NduseroptMessage parseNduseroptMessage(ByteBuffer buf) { - return NduseroptMessage.parse(null, buf); - } - - private ByteBuffer toBuffer(String hexString) { - return ByteBuffer.wrap(HexEncoding.decode(hexString)); - } - - private void assertMatches(int family, int optsLen, int ifindex, byte icmpType, - byte icmpCode, InetAddress srcaddr, NduseroptMessage msg) { - assertNotNull(msg); - assertEquals(family, msg.family); - assertEquals(ifindex, msg.ifindex); - assertEquals(optsLen, msg.opts_len); - assertEquals(icmpType, msg.icmp_type); - assertEquals(icmpCode, msg.icmp_code); - assertEquals(srcaddr, msg.srcaddr); - } - - private void assertPref64Option(String prefix, NdOption opt) { - assertNotNull(opt); - assertTrue(opt instanceof StructNdOptPref64); - StructNdOptPref64 pref64Opt = (StructNdOptPref64) opt; - assertEquals(new IpPrefix(prefix), pref64Opt.prefix); - } - - private void assertRdnssOption(NdOption opt, long lifetime, Inet6Address... servers) { - assertNotNull(opt); - assertTrue(opt instanceof StructNdOptRdnss); - StructNdOptRdnss rdnss = (StructNdOptRdnss) opt; - assertEquals(StructNdOptRdnss.TYPE, rdnss.type); - assertEquals((byte) (servers.length * 2 + 1), rdnss.header.length); - assertEquals(lifetime, rdnss.header.lifetime); - assertArrayEquals(servers, rdnss.servers); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/netlink/NetlinkConstantsTest.java b/common/tests/unit/src/com/android/net/module/util/netlink/NetlinkConstantsTest.java deleted file mode 100644 index 143e4d4a..00000000 --- a/common/tests/unit/src/com/android/net/module/util/netlink/NetlinkConstantsTest.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2020 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.net.module.util.netlink; - -import static android.system.OsConstants.NETLINK_INET_DIAG; -import static android.system.OsConstants.NETLINK_NETFILTER; -import static android.system.OsConstants.NETLINK_ROUTE; - -import static com.android.net.module.util.netlink.NetlinkConstants.IPCTNL_MSG_CT_DELETE; -import static com.android.net.module.util.netlink.NetlinkConstants.IPCTNL_MSG_CT_GET; -import static com.android.net.module.util.netlink.NetlinkConstants.IPCTNL_MSG_CT_GET_CTRZERO; -import static com.android.net.module.util.netlink.NetlinkConstants.IPCTNL_MSG_CT_GET_DYING; -import static com.android.net.module.util.netlink.NetlinkConstants.IPCTNL_MSG_CT_GET_STATS; -import static com.android.net.module.util.netlink.NetlinkConstants.IPCTNL_MSG_CT_GET_STATS_CPU; -import static com.android.net.module.util.netlink.NetlinkConstants.IPCTNL_MSG_CT_GET_UNCONFIRMED; -import static com.android.net.module.util.netlink.NetlinkConstants.IPCTNL_MSG_CT_NEW; -import static com.android.net.module.util.netlink.NetlinkConstants.NFNL_SUBSYS_CTNETLINK; -import static com.android.net.module.util.netlink.NetlinkConstants.NLMSG_DONE; -import static com.android.net.module.util.netlink.NetlinkConstants.NLMSG_ERROR; -import static com.android.net.module.util.netlink.NetlinkConstants.NLMSG_NOOP; -import static com.android.net.module.util.netlink.NetlinkConstants.NLMSG_OVERRUN; -import static com.android.net.module.util.netlink.NetlinkConstants.RTM_DELADDR; -import static com.android.net.module.util.netlink.NetlinkConstants.RTM_DELLINK; -import static com.android.net.module.util.netlink.NetlinkConstants.RTM_DELNEIGH; -import static com.android.net.module.util.netlink.NetlinkConstants.RTM_DELROUTE; -import static com.android.net.module.util.netlink.NetlinkConstants.RTM_DELRULE; -import static com.android.net.module.util.netlink.NetlinkConstants.RTM_GETADDR; -import static com.android.net.module.util.netlink.NetlinkConstants.RTM_GETLINK; -import static com.android.net.module.util.netlink.NetlinkConstants.RTM_GETNEIGH; -import static com.android.net.module.util.netlink.NetlinkConstants.RTM_GETROUTE; -import static com.android.net.module.util.netlink.NetlinkConstants.RTM_GETRULE; -import static com.android.net.module.util.netlink.NetlinkConstants.RTM_NEWADDR; -import static com.android.net.module.util.netlink.NetlinkConstants.RTM_NEWLINK; -import static com.android.net.module.util.netlink.NetlinkConstants.RTM_NEWNDUSEROPT; -import static com.android.net.module.util.netlink.NetlinkConstants.RTM_NEWNEIGH; -import static com.android.net.module.util.netlink.NetlinkConstants.RTM_NEWROUTE; -import static com.android.net.module.util.netlink.NetlinkConstants.RTM_NEWRULE; -import static com.android.net.module.util.netlink.NetlinkConstants.RTM_SETLINK; -import static com.android.net.module.util.netlink.NetlinkConstants.SOCK_DIAG_BY_FAMILY; -import static com.android.net.module.util.netlink.NetlinkConstants.stringForNlMsgType; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class NetlinkConstantsTest { - private static final short UNKNOWN_FAMILY = 1234; - - private short makeCtType(short msgType) { - return (short) (NFNL_SUBSYS_CTNETLINK << 8 | (byte) msgType); - } - - @Test - public void testStringForNlMsgType() { - assertEquals("RTM_NEWLINK", stringForNlMsgType(RTM_NEWLINK, NETLINK_ROUTE)); - assertEquals("RTM_DELLINK", stringForNlMsgType(RTM_DELLINK, NETLINK_ROUTE)); - assertEquals("RTM_GETLINK", stringForNlMsgType(RTM_GETLINK, NETLINK_ROUTE)); - assertEquals("RTM_SETLINK", stringForNlMsgType(RTM_SETLINK, NETLINK_ROUTE)); - assertEquals("RTM_NEWADDR", stringForNlMsgType(RTM_NEWADDR, NETLINK_ROUTE)); - assertEquals("RTM_DELADDR", stringForNlMsgType(RTM_DELADDR, NETLINK_ROUTE)); - assertEquals("RTM_GETADDR", stringForNlMsgType(RTM_GETADDR, NETLINK_ROUTE)); - assertEquals("RTM_NEWROUTE", stringForNlMsgType(RTM_NEWROUTE, NETLINK_ROUTE)); - assertEquals("RTM_DELROUTE", stringForNlMsgType(RTM_DELROUTE, NETLINK_ROUTE)); - assertEquals("RTM_GETROUTE", stringForNlMsgType(RTM_GETROUTE, NETLINK_ROUTE)); - assertEquals("RTM_NEWNEIGH", stringForNlMsgType(RTM_NEWNEIGH, NETLINK_ROUTE)); - assertEquals("RTM_DELNEIGH", stringForNlMsgType(RTM_DELNEIGH, NETLINK_ROUTE)); - assertEquals("RTM_GETNEIGH", stringForNlMsgType(RTM_GETNEIGH, NETLINK_ROUTE)); - assertEquals("RTM_NEWRULE", stringForNlMsgType(RTM_NEWRULE, NETLINK_ROUTE)); - assertEquals("RTM_DELRULE", stringForNlMsgType(RTM_DELRULE, NETLINK_ROUTE)); - assertEquals("RTM_GETRULE", stringForNlMsgType(RTM_GETRULE, NETLINK_ROUTE)); - assertEquals("RTM_NEWNDUSEROPT", stringForNlMsgType(RTM_NEWNDUSEROPT, NETLINK_ROUTE)); - - assertEquals("SOCK_DIAG_BY_FAMILY", - stringForNlMsgType(SOCK_DIAG_BY_FAMILY, NETLINK_INET_DIAG)); - - assertEquals("IPCTNL_MSG_CT_NEW", - stringForNlMsgType(makeCtType(IPCTNL_MSG_CT_NEW), NETLINK_NETFILTER)); - assertEquals("IPCTNL_MSG_CT_GET", - stringForNlMsgType(makeCtType(IPCTNL_MSG_CT_GET), NETLINK_NETFILTER)); - assertEquals("IPCTNL_MSG_CT_DELETE", - stringForNlMsgType(makeCtType(IPCTNL_MSG_CT_DELETE), NETLINK_NETFILTER)); - assertEquals("IPCTNL_MSG_CT_GET_CTRZERO", - stringForNlMsgType(makeCtType(IPCTNL_MSG_CT_GET_CTRZERO), NETLINK_NETFILTER)); - assertEquals("IPCTNL_MSG_CT_GET_STATS_CPU", - stringForNlMsgType(makeCtType(IPCTNL_MSG_CT_GET_STATS_CPU), NETLINK_NETFILTER)); - assertEquals("IPCTNL_MSG_CT_GET_STATS", - stringForNlMsgType(makeCtType(IPCTNL_MSG_CT_GET_STATS), NETLINK_NETFILTER)); - assertEquals("IPCTNL_MSG_CT_GET_DYING", - stringForNlMsgType(makeCtType(IPCTNL_MSG_CT_GET_DYING), NETLINK_NETFILTER)); - assertEquals("IPCTNL_MSG_CT_GET_UNCONFIRMED", - stringForNlMsgType(makeCtType(IPCTNL_MSG_CT_GET_UNCONFIRMED), NETLINK_NETFILTER)); - } - - @Test - public void testStringForNlMsgType_ControlMessage() { - for (int family : new int[]{NETLINK_ROUTE, NETLINK_INET_DIAG, NETLINK_NETFILTER}) { - assertEquals("NLMSG_NOOP", stringForNlMsgType(NLMSG_NOOP, family)); - assertEquals("NLMSG_ERROR", stringForNlMsgType(NLMSG_ERROR, family)); - assertEquals("NLMSG_DONE", stringForNlMsgType(NLMSG_DONE, family)); - assertEquals("NLMSG_OVERRUN", stringForNlMsgType(NLMSG_OVERRUN, family)); - } - } - - @Test - public void testStringForNlMsgType_UnknownFamily() { - assertTrue(stringForNlMsgType(RTM_NEWLINK, UNKNOWN_FAMILY).startsWith("unknown")); - assertTrue(stringForNlMsgType(SOCK_DIAG_BY_FAMILY, UNKNOWN_FAMILY).startsWith("unknown")); - assertTrue(stringForNlMsgType(makeCtType(IPCTNL_MSG_CT_NEW), UNKNOWN_FAMILY) - .startsWith("unknown")); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/netlink/NetlinkErrorMessageTest.java b/common/tests/unit/src/com/android/net/module/util/netlink/NetlinkErrorMessageTest.java deleted file mode 100644 index ab7d9cf5..00000000 --- a/common/tests/unit/src/com/android/net/module/util/netlink/NetlinkErrorMessageTest.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2015 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.net.module.util.netlink; - -import static android.system.OsConstants.NETLINK_ROUTE; - -import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_ACK; -import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_REPLACE; -import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_REQUEST; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import libcore.util.HexEncoding; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class NetlinkErrorMessageTest { - private static final String TAG = "NetlinkErrorMessageTest"; - - // Hexadecimal representation of packet capture. - public static final String NLM_ERROR_OK_HEX = - // struct nlmsghdr - "24000000" + // length = 36 - "0200" + // type = 2 (NLMSG_ERROR) - "0000" + // flags - "26350000" + // seqno - "64100000" + // pid = userspace process - // error integer - "00000000" + // "errno" (0 == OK) - // struct nlmsghdr - "30000000" + // length (48) of original request - "1C00" + // type = 28 (RTM_NEWNEIGH) - "0501" + // flags (NLM_F_REQUEST | NLM_F_ACK | NLM_F_REPLACE) - "26350000" + // seqno - "00000000"; // pid = kernel - public static final byte[] NLM_ERROR_OK = - HexEncoding.decode(NLM_ERROR_OK_HEX.toCharArray(), false); - - @Test - public void testParseNlmErrorOk() { - final ByteBuffer byteBuffer = ByteBuffer.wrap(NLM_ERROR_OK); - byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE); - assertNotNull(msg); - assertTrue(msg instanceof NetlinkErrorMessage); - final NetlinkErrorMessage errorMsg = (NetlinkErrorMessage) msg; - - final StructNlMsgHdr hdr = errorMsg.getHeader(); - assertNotNull(hdr); - assertEquals(36, hdr.nlmsg_len); - assertEquals(NetlinkConstants.NLMSG_ERROR, hdr.nlmsg_type); - assertEquals(0, hdr.nlmsg_flags); - assertEquals(13606, hdr.nlmsg_seq); - assertEquals(4196, hdr.nlmsg_pid); - - final StructNlMsgErr err = errorMsg.getNlMsgError(); - assertNotNull(err); - assertEquals(0, err.error); - assertNotNull(err.msg); - assertEquals(48, err.msg.nlmsg_len); - assertEquals(NetlinkConstants.RTM_NEWNEIGH, err.msg.nlmsg_type); - assertEquals((NLM_F_REQUEST | NLM_F_ACK | NLM_F_REPLACE), err.msg.nlmsg_flags); - assertEquals(13606, err.msg.nlmsg_seq); - assertEquals(0, err.msg.nlmsg_pid); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/netlink/NetlinkUtilsTest.java b/common/tests/unit/src/com/android/net/module/util/netlink/NetlinkUtilsTest.java deleted file mode 100644 index 3a72dd1b..00000000 --- a/common/tests/unit/src/com/android/net/module/util/netlink/NetlinkUtilsTest.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (C) 2015 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.net.module.util.netlink; - -import static android.system.OsConstants.AF_INET; -import static android.system.OsConstants.AF_INET6; -import static android.system.OsConstants.AF_UNSPEC; -import static android.system.OsConstants.EACCES; -import static android.system.OsConstants.NETLINK_ROUTE; - -import static com.android.net.module.util.netlink.NetlinkUtils.DEFAULT_RECV_BUFSIZE; -import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_DUMP; -import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_REQUEST; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.junit.Assume.assumeFalse; - -import android.content.Context; -import android.system.ErrnoException; -import android.system.NetlinkSocketAddress; -import android.system.Os; - -import androidx.test.filters.SmallTest; -import androidx.test.platform.app.InstrumentationRegistry; -import androidx.test.runner.AndroidJUnit4; - -import com.android.modules.utils.build.SdkLevel; -import com.android.net.module.util.Struct; - -import libcore.io.IoUtils; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.io.FileDescriptor; -import java.net.InetAddress; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.file.Files; -import java.nio.file.Paths; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class NetlinkUtilsTest { - private static final String TAG = "NetlinkUtilsTest"; - private static final int TEST_SEQNO = 5; - private static final int TEST_TIMEOUT_MS = 500; - - @Test - public void testGetNeighborsQuery() throws Exception { - final FileDescriptor fd = NetlinkUtils.netlinkSocketForProto(NETLINK_ROUTE); - assertNotNull(fd); - - NetlinkUtils.connectSocketToNetlink(fd); - - final NetlinkSocketAddress localAddr = (NetlinkSocketAddress) Os.getsockname(fd); - assertNotNull(localAddr); - assertEquals(0, localAddr.getGroupsMask()); - assertTrue(0 != localAddr.getPortId()); - - final byte[] req = RtNetlinkNeighborMessage.newGetNeighborsRequest(TEST_SEQNO); - assertNotNull(req); - - final Context ctx = InstrumentationRegistry.getInstrumentation().getContext(); - final int targetSdk = - ctx.getPackageManager() - .getApplicationInfo(ctx.getPackageName(), 0) - .targetSdkVersion; - - // Apps targeting an SDK version > S are not allowed to send RTM_GETNEIGH{TBL} messages - if (SdkLevel.isAtLeastT() && targetSdk > 31) { - var ctxt = new String(Files.readAllBytes(Paths.get("/proc/thread-self/attr/current"))); - assumeFalse("must not be platform app", ctxt.startsWith("u:r:platform_app:s0:")); - try { - NetlinkUtils.sendMessage(fd, req, 0, req.length, TEST_TIMEOUT_MS); - fail("RTM_GETNEIGH is not allowed for apps targeting SDK > 31 on T+ platforms," - + " target SDK version: " + targetSdk); - } catch (ErrnoException e) { - // Expected - assertEquals(e.errno, EACCES); - return; - } - } - - // Check that apps targeting lower API levels / running on older platforms succeed - assertEquals(req.length, - NetlinkUtils.sendMessage(fd, req, 0, req.length, TEST_TIMEOUT_MS)); - - int neighMessageCount = 0; - int doneMessageCount = 0; - - while (doneMessageCount == 0) { - ByteBuffer response = - NetlinkUtils.recvMessage(fd, DEFAULT_RECV_BUFSIZE, TEST_TIMEOUT_MS); - assertNotNull(response); - assertTrue(StructNlMsgHdr.STRUCT_SIZE <= response.limit()); - assertEquals(0, response.position()); - assertEquals(ByteOrder.nativeOrder(), response.order()); - - // Verify the messages at least appears minimally reasonable. - while (response.remaining() > 0) { - final NetlinkMessage msg = NetlinkMessage.parse(response, NETLINK_ROUTE); - assertNotNull(msg); - final StructNlMsgHdr hdr = msg.getHeader(); - assertNotNull(hdr); - - if (hdr.nlmsg_type == NetlinkConstants.NLMSG_DONE) { - doneMessageCount++; - continue; - } - - assertEquals(NetlinkConstants.RTM_NEWNEIGH, hdr.nlmsg_type); - assertTrue(msg instanceof RtNetlinkNeighborMessage); - assertTrue((hdr.nlmsg_flags & StructNlMsgHdr.NLM_F_MULTI) != 0); - assertEquals(TEST_SEQNO, hdr.nlmsg_seq); - assertEquals(localAddr.getPortId(), hdr.nlmsg_pid); - - neighMessageCount++; - } - } - - assertEquals(1, doneMessageCount); - // TODO: make sure this test passes sanely in airplane mode. - assertTrue(neighMessageCount > 0); - - IoUtils.closeQuietly(fd); - } - - @Test - public void testBasicWorkingGetAddrQuery() throws Exception { - final FileDescriptor fd = NetlinkUtils.netlinkSocketForProto(NETLINK_ROUTE); - assertNotNull(fd); - - NetlinkUtils.connectSocketToNetlink(fd); - - final NetlinkSocketAddress localAddr = (NetlinkSocketAddress) Os.getsockname(fd); - assertNotNull(localAddr); - assertEquals(0, localAddr.getGroupsMask()); - assertTrue(0 != localAddr.getPortId()); - - final int testSeqno = 8; - final byte[] req = newGetAddrRequest(testSeqno); - assertNotNull(req); - - final long timeout = 500; - assertEquals(req.length, NetlinkUtils.sendMessage(fd, req, 0, req.length, timeout)); - - int addrMessageCount = 0; - - while (true) { - ByteBuffer response = NetlinkUtils.recvMessage(fd, DEFAULT_RECV_BUFSIZE, timeout); - assertNotNull(response); - assertTrue(StructNlMsgHdr.STRUCT_SIZE <= response.limit()); - assertEquals(0, response.position()); - assertEquals(ByteOrder.nativeOrder(), response.order()); - - final NetlinkMessage msg = NetlinkMessage.parse(response, NETLINK_ROUTE); - assertNotNull(msg); - final StructNlMsgHdr nlmsghdr = msg.getHeader(); - assertNotNull(nlmsghdr); - - if (nlmsghdr.nlmsg_type == NetlinkConstants.NLMSG_DONE) { - break; - } - - assertEquals(NetlinkConstants.RTM_NEWADDR, nlmsghdr.nlmsg_type); - assertTrue((nlmsghdr.nlmsg_flags & StructNlMsgHdr.NLM_F_MULTI) != 0); - assertEquals(testSeqno, nlmsghdr.nlmsg_seq); - assertEquals(localAddr.getPortId(), nlmsghdr.nlmsg_pid); - assertTrue(msg instanceof RtNetlinkAddressMessage); - addrMessageCount++; - - // From the query response we can see the RTM_NEWADDR messages representing for IPv4 - // and IPv6 loopback address: 127.0.0.1 and ::1. - final StructIfaddrMsg ifaMsg = ((RtNetlinkAddressMessage) msg).getIfaddrHeader(); - final InetAddress ipAddress = ((RtNetlinkAddressMessage) msg).getIpAddress(); - assertTrue( - "Non-IP address family: " + ifaMsg.family, - ifaMsg.family == AF_INET || ifaMsg.family == AF_INET6); - assertTrue(ipAddress.isLoopbackAddress()); - } - - assertTrue(addrMessageCount > 0); - - IoUtils.closeQuietly(fd); - } - - /** A convenience method to create an RTM_GETADDR request message. */ - private static byte[] newGetAddrRequest(int seqNo) { - final int length = StructNlMsgHdr.STRUCT_SIZE + Struct.getSize(StructIfaddrMsg.class); - final byte[] bytes = new byte[length]; - final ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); - byteBuffer.order(ByteOrder.nativeOrder()); - - final StructNlMsgHdr nlmsghdr = new StructNlMsgHdr(); - nlmsghdr.nlmsg_len = length; - nlmsghdr.nlmsg_type = NetlinkConstants.RTM_GETADDR; - nlmsghdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; - nlmsghdr.nlmsg_seq = seqNo; - nlmsghdr.pack(byteBuffer); - - final StructIfaddrMsg addrMsg = new StructIfaddrMsg((byte) AF_UNSPEC /* family */, - (short) 0 /* prefixLen */, (short) 0 /* flags */, (short) 0 /* scope */, - 0 /* index */); - addrMsg.pack(byteBuffer); - - return bytes; - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/netlink/RtNetlinkAddressMessageTest.java b/common/tests/unit/src/com/android/net/module/util/netlink/RtNetlinkAddressMessageTest.java deleted file mode 100644 index 01126d2f..00000000 --- a/common/tests/unit/src/com/android/net/module/util/netlink/RtNetlinkAddressMessageTest.java +++ /dev/null @@ -1,289 +0,0 @@ -/* - * 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.net.module.util.netlink; - -import static android.system.OsConstants.IFA_F_PERMANENT; -import static android.system.OsConstants.NETLINK_ROUTE; -import static android.system.OsConstants.RT_SCOPE_LINK; -import static android.system.OsConstants.RT_SCOPE_UNIVERSE; - -import static com.android.testutils.MiscAsserts.assertThrows; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import android.net.InetAddresses; -import android.system.OsConstants; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.net.module.util.HexDump; - -import libcore.util.HexEncoding; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.Inet6Address; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class RtNetlinkAddressMessageTest { - private static final Inet6Address TEST_LINK_LOCAL = - (Inet6Address) InetAddresses.parseNumericAddress("FE80::2C41:5CFF:FE09:6665"); - private static final Inet6Address TEST_GLOBAL_ADDRESS = - (Inet6Address) InetAddresses.parseNumericAddress("2001:DB8:1::100"); - - // An example of the full RTM_NEWADDR message. - private static final String RTM_NEWADDR_HEX = - "48000000140000000000000000000000" // struct nlmsghr - + "0A4080FD1E000000" // struct ifaddrmsg - + "14000100FE800000000000002C415CFFFE096665" // IFA_ADDRESS - + "14000600100E0000201C00002A70000045700000" // IFA_CACHEINFO - + "0800080080000000"; // IFA_FLAGS - - private ByteBuffer toByteBuffer(final String hexString) { - return ByteBuffer.wrap(HexDump.hexStringToByteArray(hexString)); - } - - @Test - public void testParseRtmNewAddress() { - final ByteBuffer byteBuffer = toByteBuffer(RTM_NEWADDR_HEX); - byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE); - assertNotNull(msg); - assertTrue(msg instanceof RtNetlinkAddressMessage); - final RtNetlinkAddressMessage addrMsg = (RtNetlinkAddressMessage) msg; - - final StructNlMsgHdr hdr = addrMsg.getHeader(); - assertNotNull(hdr); - assertEquals(72, hdr.nlmsg_len); - assertEquals(NetlinkConstants.RTM_NEWADDR, hdr.nlmsg_type); - assertEquals(0, hdr.nlmsg_flags); - assertEquals(0, hdr.nlmsg_seq); - assertEquals(0, hdr.nlmsg_pid); - - final StructIfaddrMsg ifaddrMsgHdr = addrMsg.getIfaddrHeader(); - assertNotNull(ifaddrMsgHdr); - assertEquals((byte) OsConstants.AF_INET6, ifaddrMsgHdr.family); - assertEquals(64, ifaddrMsgHdr.prefixLen); - assertEquals(0x80, ifaddrMsgHdr.flags); - assertEquals(0xFD, ifaddrMsgHdr.scope); - assertEquals(30, ifaddrMsgHdr.index); - - assertEquals((Inet6Address) addrMsg.getIpAddress(), TEST_LINK_LOCAL); - assertEquals(3600L, addrMsg.getIfacacheInfo().preferred); - assertEquals(7200L, addrMsg.getIfacacheInfo().valid); - assertEquals(28714, addrMsg.getIfacacheInfo().cstamp); - assertEquals(28741, addrMsg.getIfacacheInfo().tstamp); - assertEquals(0x80, addrMsg.getFlags()); - } - - private static final String RTM_NEWADDR_PACK_HEX = - "48000000140000000000000000000000" // struct nlmsghr - + "0A4080FD1E000000" // struct ifaddrmsg - + "14000100FE800000000000002C415CFFFE096665" // IFA_ADDRESS - + "14000600FFFFFFFFFFFFFFFF2A7000002A700000" // IFA_CACHEINFO - + "0800080081000000"; // IFA_FLAGS(override ifa_flags) - - @Test - public void testPackRtmNewAddr() { - final ByteBuffer byteBuffer = toByteBuffer(RTM_NEWADDR_PACK_HEX); - byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE); - assertNotNull(msg); - assertTrue(msg instanceof RtNetlinkAddressMessage); - final RtNetlinkAddressMessage addrMsg = (RtNetlinkAddressMessage) msg; - - final ByteBuffer packBuffer = ByteBuffer.allocate(72); - packBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. - addrMsg.pack(packBuffer); - assertEquals(RTM_NEWADDR_PACK_HEX, HexDump.toHexString(packBuffer.array())); - } - - private static final String RTM_NEWADDR_TRUNCATED_HEX = - "44000000140000000000000000000000" // struct nlmsghr - + "0A4080FD1E000000" // struct ifaddrmsg - + "10000100FE800000000000002C415CFF" // IFA_ADDRESS(truncated) - + "14000600FFFFFFFFFFFFFFFF2A7000002A700000" // IFA_CACHEINFO - + "0800080080000000"; // IFA_FLAGS - - @Test - public void testTruncatedRtmNewAddr() { - final ByteBuffer byteBuffer = toByteBuffer(RTM_NEWADDR_TRUNCATED_HEX); - byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE); - // Parsing RTM_NEWADDR with truncated IFA_ADDRESS attribute returns null. - assertNull(msg); - } - - @Test - public void testCreateRtmNewAddressMessage() { - // Hexadecimal representation of our created packet. - final String expectedNewAddressHex = - // struct nlmsghdr - "48000000" + // length = 72 - "1400" + // type = 20 (RTM_NEWADDR) - "0501" + // flags = NLM_F_ACK | NLM_F_REQUEST | NLM_F_REPLACE - "01000000" + // seqno = 1 - "00000000" + // pid = 0 (send to kernel) - // struct IfaddrMsg - "0A" + // family = inet6 - "40" + // prefix len = 64 - "00" + // flags = 0 - "FD" + // scope = RT_SCOPE_LINK - "17000000" + // ifindex = 23 - // struct nlattr: IFA_ADDRESS - "1400" + // len - "0100" + // type - "FE800000000000002C415CFFFE096665" + // IP address = fe80::2C41:5cff:fe09:6665 - // struct nlattr: IFA_CACHEINFO - "1400" + // len - "0600" + // type - "FFFFFFFF" + // preferred = infinite - "FFFFFFFF" + // valid = infinite - "00000000" + // cstamp - "00000000" + // tstamp - // struct nlattr: IFA_FLAGS - "0800" + // len - "0800" + // type - "80000000"; // flags = IFA_F_PERMANENT - final byte[] expectedNewAddress = - HexEncoding.decode(expectedNewAddressHex.toCharArray(), false); - - final byte[] bytes = RtNetlinkAddressMessage.newRtmNewAddressMessage(1 /* seqno */, - TEST_LINK_LOCAL, (short) 64 /* prefix len */, IFA_F_PERMANENT /* flags */, - (byte) RT_SCOPE_LINK /* scope */, 23 /* ifindex */, - (long) 0xFFFFFFFF /* preferred */, (long) 0xFFFFFFFF /* valid */); - assertArrayEquals(expectedNewAddress, bytes); - } - - @Test - public void testCreateRtmDelAddressMessage() { - // Hexadecimal representation of our created packet. - final String expectedDelAddressHex = - // struct nlmsghdr - "2C000000" + // length = 44 - "1500" + // type = 21 (RTM_DELADDR) - "0500" + // flags = NLM_F_ACK | NLM_F_REQUEST - "01000000" + // seqno = 1 - "00000000" + // pid = 0 (send to kernel) - // struct IfaddrMsg - "0A" + // family = inet6 - "40" + // prefix len = 64 - "00" + // flags = 0 - "00" + // scope = RT_SCOPE_UNIVERSE - "3B000000" + // ifindex = 59 - // struct nlattr: IFA_ADDRESS - "1400" + // len - "0100" + // type - "20010DB8000100000000000000000100"; // IP address = 2001:db8:1::100 - final byte[] expectedDelAddress = - HexEncoding.decode(expectedDelAddressHex.toCharArray(), false); - - final byte[] bytes = RtNetlinkAddressMessage.newRtmDelAddressMessage(1 /* seqno */, - TEST_GLOBAL_ADDRESS, (short) 64 /* prefix len */, 59 /* ifindex */); - assertArrayEquals(expectedDelAddress, bytes); - } - - @Test - public void testCreateRtmNewAddressMessage_nullIpAddress() { - assertThrows(NullPointerException.class, - () -> RtNetlinkAddressMessage.newRtmNewAddressMessage(1 /* seqno */, - null /* IP address */, (short) 0 /* prefix len */, - IFA_F_PERMANENT /* flags */, (byte) RT_SCOPE_LINK /* scope */, - 23 /* ifindex */, (long) 0xFFFFFFFF /* preferred */, - (long) 0xFFFFFFFF /* valid */)); - } - - @Test - public void testCreateRtmDelAddressMessage_nullIpAddress() { - assertThrows(NullPointerException.class, - () -> RtNetlinkAddressMessage.newRtmDelAddressMessage(1 /* seqno */, - null /* IP address */, (short) 0 /* prefix len */, 59 /* ifindex */)); - } - - @Test - public void testCreateRtmNewAddressMessage_u32Flags() { - // Hexadecimal representation of our created packet. - final String expectedNewAddressHex = - // struct nlmsghdr - "48000000" + // length = 72 - "1400" + // type = 20 (RTM_NEWADDR) - "0501" + // flags = NLM_F_ACK | NLM_F_REQUEST | NLM_F_REPLACE - "01000000" + // seqno = 1 - "00000000" + // pid = 0 (send to kernel) - // struct IfaddrMsg - "0A" + // family = inet6 - "80" + // prefix len = 128 - "00" + // flags = 0 - "00" + // scope = RT_SCOPE_UNIVERSE - "17000000" + // ifindex = 23 - // struct nlattr: IFA_ADDRESS - "1400" + // len - "0100" + // type - "20010DB8000100000000000000000100" + // IP address = 2001:db8:1::100 - // struct nlattr: IFA_CACHEINFO - "1400" + // len - "0600" + // type - "FFFFFFFF" + // preferred = infinite - "FFFFFFFF" + // valid = infinite - "00000000" + // cstamp - "00000000" + // tstamp - // struct nlattr: IFA_FLAGS - "0800" + // len - "0800" + // type - "00030000"; // flags = IFA_F_MANAGETEMPADDR | IFA_F_NOPREFIXROUTE - final byte[] expectedNewAddress = - HexEncoding.decode(expectedNewAddressHex.toCharArray(), false); - - final byte[] bytes = RtNetlinkAddressMessage.newRtmNewAddressMessage(1 /* seqno */, - TEST_GLOBAL_ADDRESS, (short) 128 /* prefix len */, - (int) 0x300 /* flags: IFA_F_MANAGETEMPADDR | IFA_F_NOPREFIXROUTE */, - (byte) RT_SCOPE_UNIVERSE /* scope */, 23 /* ifindex */, - (long) 0xFFFFFFFF /* preferred */, (long) 0xFFFFFFFF /* valid */); - assertArrayEquals(expectedNewAddress, bytes); - } - - @Test - public void testToString() { - final ByteBuffer byteBuffer = toByteBuffer(RTM_NEWADDR_HEX); - byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE); - assertNotNull(msg); - assertTrue(msg instanceof RtNetlinkAddressMessage); - final RtNetlinkAddressMessage addrMsg = (RtNetlinkAddressMessage) msg; - final String expected = "RtNetlinkAddressMessage{ " - + "nlmsghdr{" - + "StructNlMsgHdr{ nlmsg_len{72}, nlmsg_type{20(RTM_NEWADDR)}, nlmsg_flags{0()}, " - + "nlmsg_seq{0}, nlmsg_pid{0} }}, " - + "Ifaddrmsg{" - + "family: 10, prefixLen: 64, flags: 128, scope: 253, index: 30}, " - + "IP Address{fe80::2c41:5cff:fe09:6665}, " - + "IfacacheInfo{" - + "preferred: 3600, valid: 7200, cstamp: 28714, tstamp: 28741}, " - + "Address Flags{00000080} " - + "}"; - assertEquals(expected, addrMsg.toString()); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/netlink/RtNetlinkLinkMessageTest.java b/common/tests/unit/src/com/android/net/module/util/netlink/RtNetlinkLinkMessageTest.java deleted file mode 100644 index 9db63db1..00000000 --- a/common/tests/unit/src/com/android/net/module/util/netlink/RtNetlinkLinkMessageTest.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * 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.net.module.util.netlink; - -import static android.system.OsConstants.NETLINK_ROUTE; - -import static com.android.net.module.util.NetworkStackConstants.ETHER_MTU; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import android.net.MacAddress; -import android.system.OsConstants; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.net.module.util.HexDump; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class RtNetlinkLinkMessageTest { - - // An example of the full RTM_NEWLINK message. - private static final String RTM_NEWLINK_HEX = - "64000000100000000000000000000000" // struct nlmsghr - + "000001001E0000000210000000000000" // struct ifinfo - + "0A000300776C616E30000000" // IFLA_IFNAME(wlan0) - + "08000D00B80B0000" // IFLA_PROTINFO - + "0500100002000000" // IFLA_OPERSTATE - + "0500110001000000" // IFLA_LINKMODE - + "08000400DC050000" // IFLA_MTU - + "0A00010092C3E3C9374E0000" // IFLA_ADDRESS - + "0A000200FFFFFFFFFFFF0000"; // IFLA_BROADCAST - - private ByteBuffer toByteBuffer(final String hexString) { - return ByteBuffer.wrap(HexDump.hexStringToByteArray(hexString)); - } - - @Test - public void testParseRtmNewLink() { - final ByteBuffer byteBuffer = toByteBuffer(RTM_NEWLINK_HEX); - byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE); - assertNotNull(msg); - assertTrue(msg instanceof RtNetlinkLinkMessage); - final RtNetlinkLinkMessage linkMsg = (RtNetlinkLinkMessage) msg; - - final StructNlMsgHdr hdr = linkMsg.getHeader(); - assertNotNull(hdr); - assertEquals(100, hdr.nlmsg_len); - assertEquals(NetlinkConstants.RTM_NEWLINK, hdr.nlmsg_type); - assertEquals(0, hdr.nlmsg_flags); - assertEquals(0, hdr.nlmsg_seq); - assertEquals(0, hdr.nlmsg_pid); - - final StructIfinfoMsg ifinfomsgHdr = linkMsg.getIfinfoHeader(); - assertNotNull(ifinfomsgHdr); - assertEquals((byte) OsConstants.AF_UNSPEC, ifinfomsgHdr.family); - assertEquals(OsConstants.ARPHRD_ETHER, ifinfomsgHdr.type); - assertEquals(30, ifinfomsgHdr.index); - assertEquals(0, ifinfomsgHdr.change); - - assertEquals(ETHER_MTU, linkMsg.getMtu()); - assertEquals(MacAddress.fromString("92:C3:E3:C9:37:4E"), linkMsg.getHardwareAddress()); - assertTrue(linkMsg.getInterfaceName().equals("wlan0")); - } - - /** - * Example: - * # adb shell ip tunnel add ăƒˆăƒ³0 mode sit local any remote 8.8.8.8 - * # adb shell ip link show | grep ăƒˆăƒ³ - * 33: ăƒˆăƒ³0@NONE: <POINTOPOINT,NOARP> mtu 1480 qdisc noop state DOWN mode DEFAULT group - * default qlen 1000 - * - * IFLA_IFNAME attribute: \x0c\x00\x03\x00\xe3\x83\x88\xe3\x83\xb3\x30\x00 - * length: 0x000c - * type: 0x0003 - * value: \xe3\x83\x88\xe3\x83\xb3\x30\x00 - * ăƒˆ (\xe3\x83\x88) - * ăƒ³ (\xe3\x83\xb3) - * 0 (\x30) - * null terminated (\x00) - */ - private static final String RTM_NEWLINK_UTF8_HEX = - "34000000100000000000000000000000" // struct nlmsghr - + "000001001E0000000210000000000000" // struct ifinfo - + "08000400DC050000" // IFLA_MTU - + "0A00010092C3E3C9374E0000" // IFLA_ADDRESS - + "0C000300E38388E383B33000"; // IFLA_IFNAME(ăƒˆăƒ³0) - - @Test - public void testParseRtmNewLink_utf8Ifname() { - final ByteBuffer byteBuffer = toByteBuffer(RTM_NEWLINK_UTF8_HEX); - byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE); - assertNotNull(msg); - assertTrue(msg instanceof RtNetlinkLinkMessage); - final RtNetlinkLinkMessage linkMsg = (RtNetlinkLinkMessage) msg; - - assertTrue(linkMsg.getInterfaceName().equals("ăƒˆăƒ³0")); - } - - private static final String RTM_NEWLINK_PACK_HEX = - "34000000100000000000000000000000" // struct nlmsghr - + "000001001E0000000210000000000000" // struct ifinfo - + "08000400DC050000" // IFLA_MTU - + "0A00010092C3E3C9374E0000" // IFLA_ADDRESS - + "0A000300776C616E30000000"; // IFLA_IFNAME(wlan0) - - @Test - public void testPackRtmNewLink() { - final ByteBuffer byteBuffer = toByteBuffer(RTM_NEWLINK_PACK_HEX); - byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE); - assertNotNull(msg); - assertTrue(msg instanceof RtNetlinkLinkMessage); - final RtNetlinkLinkMessage linkMsg = (RtNetlinkLinkMessage) msg; - - final ByteBuffer packBuffer = ByteBuffer.allocate(64); - packBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. - linkMsg.pack(packBuffer); - assertEquals(RTM_NEWLINK_PACK_HEX, HexDump.toHexString(packBuffer.array())); - } - - private static final String RTM_NEWLINK_TRUNCATED_HEX = - "54000000100000000000000000000000" // struct nlmsghr - + "000001001E0000000210000000000000" // struct ifinfo - + "08000D00B80B0000" // IFLA_PROTINFO - + "0500100002000000" // IFLA_OPERSTATE - + "0800010092C3E3C9" // IFLA_ADDRESS(truncated) - + "0500110001000000" // IFLA_LINKMODE - + "0A000300776C616E30000000" // IFLA_IFNAME(wlan0) - + "08000400DC050000"; // IFLA_MTU - - @Test - public void testTruncatedRtmNewLink() { - final ByteBuffer byteBuffer = toByteBuffer(RTM_NEWLINK_TRUNCATED_HEX); - byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE); - assertNotNull(msg); - assertTrue(msg instanceof RtNetlinkLinkMessage); - final RtNetlinkLinkMessage linkMsg = (RtNetlinkLinkMessage) msg; - - // Truncated IFLA_ADDRESS attribute doesn't affect parsing other attrs. - assertNull(linkMsg.getHardwareAddress()); - assertEquals(ETHER_MTU, linkMsg.getMtu()); - assertTrue(linkMsg.getInterfaceName().equals("wlan0")); - } - - @Test - public void testToString() { - final ByteBuffer byteBuffer = toByteBuffer(RTM_NEWLINK_HEX); - byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE); - assertNotNull(msg); - assertTrue(msg instanceof RtNetlinkLinkMessage); - final RtNetlinkLinkMessage linkMsg = (RtNetlinkLinkMessage) msg; - final String expected = "RtNetlinkLinkMessage{ " - + "nlmsghdr{" - + "StructNlMsgHdr{ nlmsg_len{100}, nlmsg_type{16(RTM_NEWLINK)}, nlmsg_flags{0()}, " - + "nlmsg_seq{0}, nlmsg_pid{0} }}, " - + "Ifinfomsg{" - + "family: 0, type: 1, index: 30, flags: 4098, change: 0}, " - + "Hardware Address{92:c3:e3:c9:37:4e}, " + "MTU{1500}, " - + "Ifname{wlan0} " - + "}"; - assertEquals(expected, linkMsg.toString()); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/netlink/RtNetlinkNeighborMessageTest.java b/common/tests/unit/src/com/android/net/module/util/netlink/RtNetlinkNeighborMessageTest.java deleted file mode 100644 index 4d8900cd..00000000 --- a/common/tests/unit/src/com/android/net/module/util/netlink/RtNetlinkNeighborMessageTest.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (C) 2019 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.net.module.util.netlink; - -import static android.system.OsConstants.NETLINK_ROUTE; - -import static com.android.net.module.util.netlink.StructNdMsg.NUD_STALE; -import static com.android.testutils.NetlinkTestUtils.makeDelNeighMessage; -import static com.android.testutils.NetlinkTestUtils.makeNewNeighMessage; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import android.net.InetAddresses; -import android.system.OsConstants; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import libcore.util.HexEncoding; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.Inet4Address; -import java.net.InetAddress; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.Arrays; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class RtNetlinkNeighborMessageTest { - private static final String TAG = "RtNetlinkNeighborMessageTest"; - - public static final byte[] RTM_DELNEIGH = makeDelNeighMessage( - InetAddresses.parseNumericAddress("192.168.159.254"), NUD_STALE); - - public static final byte[] RTM_NEWNEIGH = makeNewNeighMessage( - InetAddresses.parseNumericAddress("fe80::86c9:b2ff:fe6a:ed4b"), NUD_STALE); - - // An example of the full response from an RTM_GETNEIGH query. - private static final String RTM_GETNEIGH_RESPONSE_HEX = - // <-- struct nlmsghr -->|<-- struct ndmsg -->|<-- struct nlattr: NDA_DST -->|<-- NDA_LLADDR -->|<-- NDA_PROBES -->|<-- NDA_CACHEINFO -->| - "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff020000000000000000000000000001 0a00 0200 333300000001 0000 0800 0400 00000000 1400 0300 a2280000 32110000 32110000 01000000" + - "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff0200000000000000000001ff000001 0a00 0200 3333ff000001 0000 0800 0400 00000000 1400 0300 0d280000 9d100000 9d100000 00000000" + - "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 0400 80 01 1400 0100 20010db800040ca00000000000000001 0a00 0200 84c9b26aed4b 0000 0800 0400 04000000 1400 0300 90100000 90100000 90080000 01000000" + - "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff0200000000000000000001ff47da19 0a00 0200 3333ff47da19 0000 0800 0400 00000000 1400 0300 a1280000 31110000 31110000 01000000" + - "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 14000000 4000 00 05 1400 0100 ff020000000000000000000000000016 0a00 0200 333300000016 0000 0800 0400 00000000 1400 0300 912a0000 21130000 21130000 00000000" + - "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 14000000 4000 00 05 1400 0100 ff0200000000000000000001ffeace3b 0a00 0200 3333ffeace3b 0000 0800 0400 00000000 1400 0300 922a0000 22130000 22130000 00000000" + - "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff0200000000000000000001ff5c2a83 0a00 0200 3333ff5c2a83 0000 0800 0400 00000000 1400 0300 391c0000 c9040000 c9040000 01000000" + - "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 01000000 4000 00 02 1400 0100 00000000000000000000000000000000 0a00 0200 000000000000 0000 0800 0400 00000000 1400 0300 cd180200 5d010200 5d010200 08000000" + - "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff020000000000000000000000000002 0a00 0200 333300000002 0000 0800 0400 00000000 1400 0300 352a0000 c5120000 c5120000 00000000" + - "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff020000000000000000000000000016 0a00 0200 333300000016 0000 0800 0400 00000000 1400 0300 982a0000 28130000 28130000 00000000" + - "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 0800 80 01 1400 0100 fe8000000000000086c9b2fffe6aed4b 0a00 0200 84c9b26aed4b 0000 0800 0400 00000000 1400 0300 23000000 24000000 57000000 13000000" + - "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff0200000000000000000001ffeace3b 0a00 0200 3333ffeace3b 0000 0800 0400 00000000 1400 0300 992a0000 29130000 29130000 01000000" + - "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 14000000 4000 00 05 1400 0100 ff020000000000000000000000000002 0a00 0200 333300000002 0000 0800 0400 00000000 1400 0300 2e2a0000 be120000 be120000 00000000" + - "44000000 1c00 0200 00000000 3e2b0000 02 00 0000 18000000 4000 00 03 0800 0100 00000000 0400 0200 0800 0400 00000000 1400 0300 75280000 05110000 05110000 22000000"; - public static final byte[] RTM_GETNEIGH_RESPONSE = - HexEncoding.decode(RTM_GETNEIGH_RESPONSE_HEX.replaceAll(" ", "").toCharArray(), false); - - @Test - public void testParseRtmDelNeigh() { - final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_DELNEIGH); - byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE); - assertNotNull(msg); - assertTrue(msg instanceof RtNetlinkNeighborMessage); - final RtNetlinkNeighborMessage neighMsg = (RtNetlinkNeighborMessage) msg; - - final StructNlMsgHdr hdr = neighMsg.getHeader(); - assertNotNull(hdr); - assertEquals(76, hdr.nlmsg_len); - assertEquals(NetlinkConstants.RTM_DELNEIGH, hdr.nlmsg_type); - assertEquals(0, hdr.nlmsg_flags); - assertEquals(0, hdr.nlmsg_seq); - assertEquals(0, hdr.nlmsg_pid); - - final StructNdMsg ndmsgHdr = neighMsg.getNdHeader(); - assertNotNull(ndmsgHdr); - assertEquals((byte) OsConstants.AF_INET, ndmsgHdr.ndm_family); - assertEquals(21, ndmsgHdr.ndm_ifindex); - assertEquals(NUD_STALE, ndmsgHdr.ndm_state); - final InetAddress destination = neighMsg.getDestination(); - assertNotNull(destination); - assertEquals(InetAddress.parseNumericAddress("192.168.159.254"), destination); - } - - @Test - public void testParseRtmNewNeigh() { - final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_NEWNEIGH); - byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE); - assertNotNull(msg); - assertTrue(msg instanceof RtNetlinkNeighborMessage); - final RtNetlinkNeighborMessage neighMsg = (RtNetlinkNeighborMessage) msg; - - final StructNlMsgHdr hdr = neighMsg.getHeader(); - assertNotNull(hdr); - assertEquals(88, hdr.nlmsg_len); - assertEquals(NetlinkConstants.RTM_NEWNEIGH, hdr.nlmsg_type); - assertEquals(0, hdr.nlmsg_flags); - assertEquals(0, hdr.nlmsg_seq); - assertEquals(0, hdr.nlmsg_pid); - - final StructNdMsg ndmsgHdr = neighMsg.getNdHeader(); - assertNotNull(ndmsgHdr); - assertEquals((byte) OsConstants.AF_INET6, ndmsgHdr.ndm_family); - assertEquals(21, ndmsgHdr.ndm_ifindex); - assertEquals(NUD_STALE, ndmsgHdr.ndm_state); - final InetAddress destination = neighMsg.getDestination(); - assertNotNull(destination); - assertEquals(InetAddress.parseNumericAddress("fe80::86c9:b2ff:fe6a:ed4b"), destination); - } - - @Test - public void testParseRtmGetNeighResponse() { - final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_GETNEIGH_RESPONSE); - byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. - - int messageCount = 0; - while (byteBuffer.remaining() > 0) { - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE); - assertNotNull(msg); - assertTrue(msg instanceof RtNetlinkNeighborMessage); - final RtNetlinkNeighborMessage neighMsg = (RtNetlinkNeighborMessage) msg; - - final StructNlMsgHdr hdr = neighMsg.getHeader(); - assertNotNull(hdr); - assertEquals(NetlinkConstants.RTM_NEWNEIGH, hdr.nlmsg_type); - assertEquals(StructNlMsgHdr.NLM_F_MULTI, hdr.nlmsg_flags); - assertEquals(0, hdr.nlmsg_seq); - assertEquals(11070, hdr.nlmsg_pid); - - final int probes = neighMsg.getProbes(); - assertTrue("Unexpected number of probes. Got " + probes + ", max=5", - probes < 5); - final int ndm_refcnt = neighMsg.getCacheInfo().ndm_refcnt; - assertTrue("nda_cacheinfo has unexpectedly high ndm_refcnt: " + ndm_refcnt, - ndm_refcnt < 0x100); - - messageCount++; - } - // TODO: add more detailed spot checks. - assertEquals(14, messageCount); - } - - @Test - public void testCreateRtmNewNeighMessage() { - final int seqNo = 2635; - final int ifIndex = 14; - final byte[] llAddr = - new byte[] { (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6 }; - - // Hexadecimal representation of our created packet. - final String expectedNewNeighHex = - // struct nlmsghdr - "30000000" + // length = 48 - "1c00" + // type = 28 (RTM_NEWNEIGH) - "0501" + // flags (NLM_F_REQUEST | NLM_F_ACK | NLM_F_REPLACE) - "4b0a0000" + // seqno - "00000000" + // pid (0 == kernel) - // struct ndmsg - "02" + // family - "00" + // pad1 - "0000" + // pad2 - "0e000000" + // interface index (14) - "0800" + // NUD state (0x08 == NUD_DELAY) - "00" + // flags - "00" + // type - // struct nlattr: NDA_DST - "0800" + // length = 8 - "0100" + // type (1 == NDA_DST, for neighbor messages) - "7f000001" + // IPv4 address (== 127.0.0.1) - // struct nlattr: NDA_LLADDR - "0a00" + // length = 10 - "0200" + // type (2 == NDA_LLADDR, for neighbor messages) - "010203040506" + // MAC Address (== 01:02:03:04:05:06) - "0000"; // padding, for 4 byte alignment - final byte[] expectedNewNeigh = - HexEncoding.decode(expectedNewNeighHex.toCharArray(), false); - - final byte[] bytes = RtNetlinkNeighborMessage.newNewNeighborMessage( - seqNo, Inet4Address.LOOPBACK, StructNdMsg.NUD_DELAY, ifIndex, llAddr); - if (!Arrays.equals(expectedNewNeigh, bytes)) { - assertEquals(expectedNewNeigh.length, bytes.length); - for (int i = 0; i < Math.min(expectedNewNeigh.length, bytes.length); i++) { - assertEquals(expectedNewNeigh[i], bytes[i]); - } - } - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/netlink/RtNetlinkRouteMessageTest.java b/common/tests/unit/src/com/android/net/module/util/netlink/RtNetlinkRouteMessageTest.java deleted file mode 100644 index 9881653a..00000000 --- a/common/tests/unit/src/com/android/net/module/util/netlink/RtNetlinkRouteMessageTest.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * 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.net.module.util.netlink; - -import static android.system.OsConstants.NETLINK_ROUTE; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import android.net.InetAddresses; -import android.net.IpPrefix; -import android.system.OsConstants; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.net.module.util.HexDump; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.Inet6Address; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class RtNetlinkRouteMessageTest { - private static final IpPrefix TEST_IPV6_GLOBAL_PREFIX = new IpPrefix("2001:db8:1::/64"); - private static final Inet6Address TEST_IPV6_LINK_LOCAL_GATEWAY = - (Inet6Address) InetAddresses.parseNumericAddress("fe80::1"); - - // An example of the full RTM_NEWROUTE message. - private static final String RTM_NEWROUTE_HEX = - "88000000180000060000000000000000" // struct nlmsghr - + "0A400000FC02000100000000" // struct rtmsg - + "08000F00C7060000" // RTA_TABLE - + "1400010020010DB8000100000000000000000000" // RTA_DST - + "08000400DF020000" // RTA_OIF - + "0800060000010000" // RTA_PRIORITY - + "24000C0000000000000000005EEA000000000000" // RTA_CACHEINFO - + "00000000000000000000000000000000" - + "14000500FE800000000000000000000000000001" // RTA_GATEWAY - + "0500140000000000"; // RTA_PREF - - private ByteBuffer toByteBuffer(final String hexString) { - return ByteBuffer.wrap(HexDump.hexStringToByteArray(hexString)); - } - - private void assertRtmRouteMessage(final RtNetlinkRouteMessage routeMsg) { - final StructNlMsgHdr hdr = routeMsg.getHeader(); - assertNotNull(hdr); - assertEquals(136, hdr.nlmsg_len); - assertEquals(NetlinkConstants.RTM_NEWROUTE, hdr.nlmsg_type); - assertEquals(0x600, hdr.nlmsg_flags); - assertEquals(0, hdr.nlmsg_seq); - assertEquals(0, hdr.nlmsg_pid); - - final StructRtMsg rtmsg = routeMsg.getRtMsgHeader(); - assertNotNull(rtmsg); - assertEquals((byte) OsConstants.AF_INET6, rtmsg.family); - assertEquals(64, rtmsg.dstLen); - assertEquals(0, rtmsg.srcLen); - assertEquals(0, rtmsg.tos); - assertEquals(0xFC, rtmsg.table); - assertEquals(NetlinkConstants.RTPROT_KERNEL, rtmsg.protocol); - assertEquals(NetlinkConstants.RT_SCOPE_UNIVERSE, rtmsg.scope); - assertEquals(NetlinkConstants.RTN_UNICAST, rtmsg.type); - assertEquals(0, rtmsg.flags); - - assertEquals(routeMsg.getDestination(), TEST_IPV6_GLOBAL_PREFIX); - assertEquals(735, routeMsg.getInterfaceIndex()); - assertEquals((Inet6Address) routeMsg.getGateway(), TEST_IPV6_LINK_LOCAL_GATEWAY); - - assertNotNull(routeMsg.getRtaCacheInfo()); - } - - @Test - public void testParseRtmRouteMessage() { - final ByteBuffer byteBuffer = toByteBuffer(RTM_NEWROUTE_HEX); - byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. - - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE); - assertNotNull(msg); - assertTrue(msg instanceof RtNetlinkRouteMessage); - final RtNetlinkRouteMessage routeMsg = (RtNetlinkRouteMessage) msg; - assertRtmRouteMessage(routeMsg); - } - - private static final String RTM_NEWROUTE_PACK_HEX = - "4C000000180000060000000000000000" // struct nlmsghr - + "0A400000FC02000100000000" // struct rtmsg - + "1400010020010DB8000100000000000000000000" // RTA_DST - + "14000500FE800000000000000000000000000001" // RTA_GATEWAY - + "08000400DF020000" // RTA_OIF - + "24000C0000000000000000005EEA000000000000" // RTA_CACHEINFO - + "00000000000000000000000000000000"; - - @Test - public void testPackRtmNewRoute() { - final ByteBuffer byteBuffer = toByteBuffer(RTM_NEWROUTE_PACK_HEX); - byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE); - assertNotNull(msg); - assertTrue(msg instanceof RtNetlinkRouteMessage); - final RtNetlinkRouteMessage routeMsg = (RtNetlinkRouteMessage) msg; - - final ByteBuffer packBuffer = ByteBuffer.allocate(112); - packBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. - routeMsg.pack(packBuffer); - assertEquals(RTM_NEWROUTE_PACK_HEX, HexDump.toHexString(packBuffer.array())); - } - - private static final String RTM_NEWROUTE_TRUNCATED_HEX = - "48000000180000060000000000000000" // struct nlmsghr - + "0A400000FC02000100000000" // struct rtmsg - + "1400010020010DB8000100000000000000000000" // RTA_DST - + "10000500FE8000000000000000000000" // RTA_GATEWAY(truncated) - + "08000400DF020000"; // RTA_OIF - - @Test - public void testTruncatedRtmNewRoute() { - final ByteBuffer byteBuffer = toByteBuffer(RTM_NEWROUTE_TRUNCATED_HEX); - byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE); - // Parsing RTM_NEWROUTE with truncated RTA_GATEWAY attribute returns null. - assertNull(msg); - } - - private static final String RTM_NEWROUTE_IPV4_MAPPED_IPV6_GATEWAY_HEX = - "4C000000180000060000000000000000" // struct nlmsghr - + "0A400000FC02000100000000" // struct rtmsg - + "1400010020010DB8000100000000000000000000" // RTA_DST(2001:db8:1::/64) - + "1400050000000000000000000000FFFF0A010203" // RTA_GATEWAY(::ffff:10.1.2.3) - + "08000400DF020000"; // RTA_OIF - - @Test - public void testParseRtmRouteMessage_IPv4MappedIPv6Gateway() { - final ByteBuffer byteBuffer = toByteBuffer(RTM_NEWROUTE_IPV4_MAPPED_IPV6_GATEWAY_HEX); - byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE); - // Parsing RTM_NEWROUTE with IPv4-mapped IPv6 gateway address, which doesn't match - // rtm_family after address parsing. - assertNull(msg); - } - - private static final String RTM_NEWROUTE_IPV4_MAPPED_IPV6_DST_HEX = - "4C000000180000060000000000000000" // struct nlmsghr - + "0A780000FC02000100000000" // struct rtmsg - + "1400010000000000000000000000FFFF0A000000" // RTA_DST(::ffff:10.0.0.0/120) - + "14000500FE800000000000000000000000000001" // RTA_GATEWAY(fe80::1) - + "08000400DF020000"; // RTA_OIF - - @Test - public void testParseRtmRouteMessage_IPv4MappedIPv6Destination() { - final ByteBuffer byteBuffer = toByteBuffer(RTM_NEWROUTE_IPV4_MAPPED_IPV6_DST_HEX); - byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE); - // Parsing RTM_NEWROUTE with IPv4-mapped IPv6 destination prefix, which doesn't match - // rtm_family after address parsing. - assertNull(msg); - } - - // An example of the full RTM_NEWADDR message. - private static final String RTM_NEWADDR_HEX = - "48000000140000000000000000000000" // struct nlmsghr - + "0A4080FD1E000000" // struct ifaddrmsg - + "14000100FE800000000000002C415CFFFE096665" // IFA_ADDRESS - + "14000600100E0000201C00002A70000045700000" // IFA_CACHEINFO - + "0800080080000000"; // IFA_FLAGS - - @Test - public void testParseMultipleRtmMessagesInOneByteBuffer() { - final ByteBuffer byteBuffer = toByteBuffer(RTM_NEWROUTE_HEX + RTM_NEWADDR_HEX); - byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. - - // Try to parse the RTM_NEWROUTE message. - NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE); - assertNotNull(msg); - assertTrue(msg instanceof RtNetlinkRouteMessage); - final RtNetlinkRouteMessage routeMsg = (RtNetlinkRouteMessage) msg; - assertRtmRouteMessage(routeMsg); - - // Try to parse the RTM_NEWADDR message. - msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE); - assertNotNull(msg); - assertTrue(msg instanceof RtNetlinkAddressMessage); - } - - @Test - public void testToString() { - final ByteBuffer byteBuffer = toByteBuffer(RTM_NEWROUTE_HEX); - byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. - final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE); - assertNotNull(msg); - assertTrue(msg instanceof RtNetlinkRouteMessage); - final RtNetlinkRouteMessage routeMsg = (RtNetlinkRouteMessage) msg; - final String expected = "RtNetlinkRouteMessage{ " - + "nlmsghdr{" - + "StructNlMsgHdr{ nlmsg_len{136}, nlmsg_type{24(RTM_NEWROUTE)}, " - + "nlmsg_flags{1536(NLM_F_MATCH)}, nlmsg_seq{0}, nlmsg_pid{0} }}, " - + "Rtmsg{" - + "family: 10, dstLen: 64, srcLen: 0, tos: 0, table: 252, protocol: 2, " - + "scope: 0, type: 1, flags: 0}, " - + "destination{2001:db8:1::}, " - + "gateway{fe80::1}, " - + "ifindex{735}, " - + "rta_cacheinfo{clntref: 0, lastuse: 0, expires: 59998, error: 0, used: 0, " - + "id: 0, ts: 0, tsage: 0} " - + "}"; - assertEquals(expected, routeMsg.toString()); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/netlink/StructInetDiagSockIdTest.java b/common/tests/unit/src/com/android/net/module/util/netlink/StructInetDiagSockIdTest.java deleted file mode 100644 index ce190f2c..00000000 --- a/common/tests/unit/src/com/android/net/module/util/netlink/StructInetDiagSockIdTest.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * 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.net.module.util.netlink; - -import static android.system.OsConstants.AF_INET; -import static android.system.OsConstants.AF_INET6; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; - -import android.net.InetAddresses; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetSocketAddress; -import java.nio.ByteBuffer; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class StructInetDiagSockIdTest { - private static final Inet4Address IPV4_SRC_ADDR = - (Inet4Address) InetAddresses.parseNumericAddress("192.0.2.1"); - private static final Inet4Address IPV4_DST_ADDR = - (Inet4Address) InetAddresses.parseNumericAddress("198.51.100.1"); - private static final Inet6Address IPV6_SRC_ADDR = - (Inet6Address) InetAddresses.parseNumericAddress("2001:db8::1"); - private static final Inet6Address IPV6_DST_ADDR = - (Inet6Address) InetAddresses.parseNumericAddress("2001:db8::2"); - private static final int SRC_PORT = 65297; - private static final int DST_PORT = 443; - private static final int IF_INDEX = 7; - private static final long COOKIE = 561; - - private static final byte[] INET_DIAG_SOCKET_ID_IPV4 = - new byte[] { - // src port, dst port - (byte) 0xff, (byte) 0x11, (byte) 0x01, (byte) 0xbb, - // src address - (byte) 0xc0, (byte) 0x00, (byte) 0x02, (byte) 0x01, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - // dst address - (byte) 0xc6, (byte) 0x33, (byte) 0x64, (byte) 0x01, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - // if index - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - // cookie - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff - }; - - private static final byte[] INET_DIAG_SOCKET_ID_IPV4_IF_COOKIE = - new byte[] { - // src port, dst port - (byte) 0xff, (byte) 0x11, (byte) 0x01, (byte) 0xbb, - // src address - (byte) 0xc0, (byte) 0x00, (byte) 0x02, (byte) 0x01, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - // dst address - (byte) 0xc6, (byte) 0x33, (byte) 0x64, (byte) 0x01, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - // if index - (byte) 0x07, (byte) 0x00, (byte) 0x00, (byte) 0x00, - // cookie - (byte) 0x31, (byte) 0x02, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - }; - - private static final byte[] INET_DIAG_SOCKET_ID_IPV6 = - new byte[] { - // src port, dst port - (byte) 0xff, (byte) 0x11, (byte) 0x01, (byte) 0xbb, - // src address - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, - // dst address - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, - // if index - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - // cookie - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff - }; - - private static final byte[] INET_DIAG_SOCKET_ID_IPV6_IF_COOKIE = - new byte[] { - // src port, dst port - (byte) 0xff, (byte) 0x11, (byte) 0x01, (byte) 0xbb, - // src address - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, - // dst address - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, - // if index - (byte) 0x07, (byte) 0x00, (byte) 0x00, (byte) 0x00, - // cookie - (byte) 0x31, (byte) 0x02, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - }; - - @Test - public void testPackStructInetDiagSockIdWithIpv4() { - final InetSocketAddress srcAddr = new InetSocketAddress(IPV4_SRC_ADDR, SRC_PORT); - final InetSocketAddress dstAddr = new InetSocketAddress(IPV4_DST_ADDR, DST_PORT); - final StructInetDiagSockId sockId = new StructInetDiagSockId(srcAddr, dstAddr); - final ByteBuffer buffer = ByteBuffer.allocate(StructInetDiagSockId.STRUCT_SIZE); - sockId.pack(buffer); - assertArrayEquals(INET_DIAG_SOCKET_ID_IPV4, buffer.array()); - } - - @Test - public void testPackStructInetDiagSockIdWithIpv6() { - final InetSocketAddress srcAddr = new InetSocketAddress(IPV6_SRC_ADDR, SRC_PORT); - final InetSocketAddress dstAddr = new InetSocketAddress(IPV6_DST_ADDR, DST_PORT); - final StructInetDiagSockId sockId = new StructInetDiagSockId(srcAddr, dstAddr); - final ByteBuffer buffer = ByteBuffer.allocate(StructInetDiagSockId.STRUCT_SIZE); - sockId.pack(buffer); - assertArrayEquals(INET_DIAG_SOCKET_ID_IPV6, buffer.array()); - } - - @Test - public void testPackStructInetDiagSockIdWithIpv4IfIndexCookie() { - final InetSocketAddress srcAddr = new InetSocketAddress(IPV4_SRC_ADDR, SRC_PORT); - final InetSocketAddress dstAddr = new InetSocketAddress(IPV4_DST_ADDR, DST_PORT); - final StructInetDiagSockId sockId = - new StructInetDiagSockId(srcAddr, dstAddr, IF_INDEX, COOKIE); - final ByteBuffer buffer = ByteBuffer.allocate(StructInetDiagSockId.STRUCT_SIZE); - sockId.pack(buffer); - assertArrayEquals(INET_DIAG_SOCKET_ID_IPV4_IF_COOKIE, buffer.array()); - } - - @Test - public void testPackStructInetDiagSockIdWithIpv6IfIndexCookie() { - final InetSocketAddress srcAddr = new InetSocketAddress(IPV6_SRC_ADDR, SRC_PORT); - final InetSocketAddress dstAddr = new InetSocketAddress(IPV6_DST_ADDR, DST_PORT); - final StructInetDiagSockId sockId = - new StructInetDiagSockId(srcAddr, dstAddr, IF_INDEX, COOKIE); - final ByteBuffer buffer = ByteBuffer.allocate(StructInetDiagSockId.STRUCT_SIZE); - sockId.pack(buffer); - assertArrayEquals(INET_DIAG_SOCKET_ID_IPV6_IF_COOKIE, buffer.array()); - } - - @Test - public void testParseStructInetDiagSockIdWithIpv4() { - final ByteBuffer buffer = ByteBuffer.wrap(INET_DIAG_SOCKET_ID_IPV4_IF_COOKIE); - final StructInetDiagSockId sockId = StructInetDiagSockId.parse(buffer, (byte) AF_INET); - - assertEquals(SRC_PORT, sockId.locSocketAddress.getPort()); - assertEquals(IPV4_SRC_ADDR, sockId.locSocketAddress.getAddress()); - assertEquals(DST_PORT, sockId.remSocketAddress.getPort()); - assertEquals(IPV4_DST_ADDR, sockId.remSocketAddress.getAddress()); - assertEquals(IF_INDEX, sockId.ifIndex); - assertEquals(COOKIE, sockId.cookie); - } - - @Test - public void testParseStructInetDiagSockIdWithIpv6() { - final ByteBuffer buffer = ByteBuffer.wrap(INET_DIAG_SOCKET_ID_IPV6_IF_COOKIE); - final StructInetDiagSockId sockId = StructInetDiagSockId.parse(buffer, (byte) AF_INET6); - - assertEquals(SRC_PORT, sockId.locSocketAddress.getPort()); - assertEquals(IPV6_SRC_ADDR, sockId.locSocketAddress.getAddress()); - assertEquals(DST_PORT, sockId.remSocketAddress.getPort()); - assertEquals(IPV6_DST_ADDR, sockId.remSocketAddress.getAddress()); - assertEquals(IF_INDEX, sockId.ifIndex); - assertEquals(COOKIE, sockId.cookie); - } - - @Test - public void testToStringStructInetDiagSockIdWithIpv4() { - final InetSocketAddress srcAddr = new InetSocketAddress(IPV4_SRC_ADDR, SRC_PORT); - final InetSocketAddress dstAddr = new InetSocketAddress(IPV4_DST_ADDR, DST_PORT); - final StructInetDiagSockId sockId = new StructInetDiagSockId(srcAddr, dstAddr); - assertEquals("StructInetDiagSockId{ idiag_sport{65297}, idiag_dport{443}," - + " idiag_src{192.0.2.1}, idiag_dst{198.51.100.1}, idiag_if{0}," - + " idiag_cookie{INET_DIAG_NOCOOKIE}}", sockId.toString()); - } - - @Test - public void testToStringStructInetDiagSockIdWithIpv6() { - final InetSocketAddress srcAddr = new InetSocketAddress(IPV6_SRC_ADDR, SRC_PORT); - final InetSocketAddress dstAddr = new InetSocketAddress(IPV6_DST_ADDR, DST_PORT); - final StructInetDiagSockId sockId = new StructInetDiagSockId(srcAddr, dstAddr); - assertEquals("StructInetDiagSockId{ idiag_sport{65297}, idiag_dport{443}," - + " idiag_src{2001:db8::1}, idiag_dst{2001:db8::2}, idiag_if{0}," - + " idiag_cookie{INET_DIAG_NOCOOKIE}}", sockId.toString()); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/netlink/StructNdOptPref64Test.java b/common/tests/unit/src/com/android/net/module/util/netlink/StructNdOptPref64Test.java deleted file mode 100644 index beed8383..00000000 --- a/common/tests/unit/src/com/android/net/module/util/netlink/StructNdOptPref64Test.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (C) 2019 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.net.module.util.netlink; - -import static com.android.net.module.util.netlink.StructNdOptPref64.getScaledLifetimePlc; -import static com.android.net.module.util.netlink.StructNdOptPref64.plcToPrefixLength; -import static com.android.net.module.util.netlink.StructNdOptPref64.prefixLengthToPlc; -import static com.android.testutils.MiscAsserts.assertThrows; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; - -import android.annotation.SuppressLint; -import android.net.IpPrefix; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import libcore.util.HexEncoding; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.InetAddress; -import java.nio.ByteBuffer; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class StructNdOptPref64Test { - - private static final String PREFIX1 = "64:ff9b::"; - private static final String PREFIX2 = "2001:db8:1:2:3:64::"; - - private static byte[] prefixBytes(String addrString) throws Exception { - InetAddress addr = InetAddress.getByName(addrString); - byte[] prefixBytes = new byte[12]; - System.arraycopy(addr.getAddress(), 0, prefixBytes, 0, 12); - return prefixBytes; - } - - @SuppressLint("NewApi") - private static IpPrefix prefix(String addrString, int prefixLength) throws Exception { - return new IpPrefix(InetAddress.getByName(addrString), prefixLength); - } - - private void assertPref64OptMatches(int lifetime, IpPrefix prefix, StructNdOptPref64 opt) { - assertEquals(StructNdOptPref64.TYPE, opt.type); - assertEquals(2, opt.length); - assertEquals(lifetime, opt.lifetime); - assertEquals(prefix, opt.prefix); - } - - private void assertToByteBufferMatches(StructNdOptPref64 opt, String expected) { - String actual = HexEncoding.encodeToString(opt.toByteBuffer().array()); - assertEquals(expected, actual); - } - - private ByteBuffer makeNdOptPref64(int lifetime, byte[] prefix, int prefixLengthCode) { - if (prefix.length != 12) throw new IllegalArgumentException("Prefix must be 12 bytes"); - - ByteBuffer buf = ByteBuffer.allocate(16) - .put((byte) StructNdOptPref64.TYPE) - .put((byte) StructNdOptPref64.LENGTH) - .putShort(getScaledLifetimePlc(lifetime, prefixLengthCode)) - .put(prefix, 0, 12); - - buf.flip(); - return buf; - } - - @Test - public void testParseCannedOption() throws Exception { - String hexBytes = "2602" // type=38, len=2 (16 bytes) - + "0088" // lifetime=136, PLC=0 (/96) - + "20010DB80003000400050006"; // 2001:db8:3:4:5:6/96 - byte[] rawBytes = HexEncoding.decode(hexBytes); - StructNdOptPref64 opt = StructNdOptPref64.parse(ByteBuffer.wrap(rawBytes)); - assertPref64OptMatches(136, prefix("2001:DB8:3:4:5:6::", 96), opt); - assertToByteBufferMatches(opt, hexBytes); - - hexBytes = "2602" // type=38, len=2 (16 bytes) - + "2752" // lifetime=10064, PLC=2 (/56) - + "0064FF9B0000000000000000"; // 64:ff9b::/56 - rawBytes = HexEncoding.decode(hexBytes); - opt = StructNdOptPref64.parse(ByteBuffer.wrap(rawBytes)); - assertPref64OptMatches(10064, prefix("64:FF9B::", 56), opt); - assertToByteBufferMatches(opt, hexBytes); - } - - @Test - public void testParsing() throws Exception { - // Valid. - ByteBuffer buf = makeNdOptPref64(600, prefixBytes(PREFIX1), 0); - StructNdOptPref64 opt = StructNdOptPref64.parse(buf); - assertPref64OptMatches(600, prefix(PREFIX1, 96), opt); - - // Valid, zero lifetime, /64. - buf = makeNdOptPref64(0, prefixBytes(PREFIX1), 1); - opt = StructNdOptPref64.parse(buf); - assertPref64OptMatches(0, prefix(PREFIX1, 64), opt); - - // Valid, low lifetime, /56. - buf = makeNdOptPref64(8, prefixBytes(PREFIX2), 2); - opt = StructNdOptPref64.parse(buf); - assertPref64OptMatches(8, prefix(PREFIX2, 56), opt); - assertEquals(new IpPrefix("2001:db8:1::/56"), opt.prefix); // Prefix is truncated. - - // Valid, maximum lifetime, /32. - buf = makeNdOptPref64(65528, prefixBytes(PREFIX2), 5); - opt = StructNdOptPref64.parse(buf); - assertPref64OptMatches(65528, prefix(PREFIX2, 32), opt); - assertEquals(new IpPrefix("2001:db8::/32"), opt.prefix); // Prefix is truncated. - - // Lifetime not divisible by 8. - buf = makeNdOptPref64(300, prefixBytes(PREFIX2), 0); - opt = StructNdOptPref64.parse(buf); - assertPref64OptMatches(296, prefix(PREFIX2, 96), opt); - - // Invalid prefix length codes. - buf = makeNdOptPref64(600, prefixBytes(PREFIX1), 6); - assertNull(StructNdOptPref64.parse(buf)); - buf = makeNdOptPref64(600, prefixBytes(PREFIX1), 7); - assertNull(StructNdOptPref64.parse(buf)); - - // Truncated to varying lengths... - buf = makeNdOptPref64(600, prefixBytes(PREFIX1), 3); - final int len = buf.limit(); - for (int i = 0; i < buf.limit() - 1; i++) { - buf.flip(); - buf.limit(i); - assertNull("Option truncated to " + i + " bytes, should have returned null", - StructNdOptPref64.parse(buf)); - } - buf.flip(); - buf.limit(len); - // ... but otherwise OK. - opt = StructNdOptPref64.parse(buf); - assertPref64OptMatches(600, prefix(PREFIX1, 48), opt); - } - - @Test - public void testToString() throws Exception { - ByteBuffer buf = makeNdOptPref64(600, prefixBytes(PREFIX1), 4); - StructNdOptPref64 opt = StructNdOptPref64.parse(buf); - assertPref64OptMatches(600, prefix(PREFIX1, 40), opt); - assertEquals("NdOptPref64(64:ff9b::/40, 600)", opt.toString()); - } - - private void assertInvalidPlc(int plc) { - assertThrows(IllegalArgumentException.class, () -> plcToPrefixLength(plc)); - } - - @Test - public void testPrefixLengthToPlc() { - for (int i = 0; i < 6; i++) { - assertEquals(i, prefixLengthToPlc(plcToPrefixLength(i))); - } - assertInvalidPlc(-1); - assertInvalidPlc(6); - assertInvalidPlc(7); - assertEquals(0, prefixLengthToPlc(96)); - } - - - private void assertInvalidParameters(IpPrefix prefix, int lifetime) { - assertThrows(IllegalArgumentException.class, () -> new StructNdOptPref64(prefix, lifetime)); - } - - @Test - public void testToByteBuffer() throws Exception { - final IpPrefix prefix1 = prefix(PREFIX1, 56); - final IpPrefix prefix2 = prefix(PREFIX2, 96); - - StructNdOptPref64 opt = new StructNdOptPref64(prefix1, 600); - assertToByteBufferMatches(opt, "2602025A0064FF9B0000000000000000"); - assertEquals(new IpPrefix("64:ff9b::/56"), opt.prefix); - assertEquals(600, opt.lifetime); - - opt = new StructNdOptPref64(prefix2, 65519); - assertToByteBufferMatches(opt, "2602FFE820010DB80001000200030064"); - assertEquals(new IpPrefix("2001:db8:1:2:3:64::/96"), opt.prefix); - assertEquals(65512, opt.lifetime); - - assertInvalidParameters(prefix1, 65535); - assertInvalidParameters(prefix2, -1); - assertInvalidParameters(prefix("1.2.3.4", 32), 600); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/netlink/StructNdOptRdnssTest.java b/common/tests/unit/src/com/android/net/module/util/netlink/StructNdOptRdnssTest.java deleted file mode 100644 index 1dcb9b59..00000000 --- a/common/tests/unit/src/com/android/net/module/util/netlink/StructNdOptRdnssTest.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * 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.net.module.util.netlink; - -import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ND_OPTION_RDNSS; -import static com.android.testutils.MiscAsserts.assertThrows; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; - -import android.net.InetAddresses; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.net.module.util.structs.RdnssOption; - -import libcore.util.HexEncoding; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.Inet6Address; -import java.nio.ByteBuffer; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class StructNdOptRdnssTest { - private static final String DNS_SERVER1 = "2001:4860:4860::64"; - private static final String DNS_SERVER2 = "2001:4860:4860::6464"; - - private static final Inet6Address[] DNS_SERVER_ADDRESSES = new Inet6Address[] { - (Inet6Address) InetAddresses.parseNumericAddress(DNS_SERVER1), - (Inet6Address) InetAddresses.parseNumericAddress(DNS_SERVER2), - }; - - private static final String RDNSS_OPTION_BYTES = - "1905" // type=25, len=5 (40 bytes) - + "0000" // reserved - + "00000E10" // lifetime=3600 - + "20014860486000000000000000000064" // 2001:4860:4860::64 - + "20014860486000000000000000006464"; // 2001:4860:4860::6464 - - private static final String RDNSS_INFINITY_LIFETIME_OPTION_BYTES = - "1905" // type=25, len=3 (24 bytes) - + "0000" // reserved - + "FFFFFFFF" // lifetime=0xffffffff - + "20014860486000000000000000000064" // 2001:4860:4860::64 - + "20014860486000000000000000006464"; // 2001:4860:4860::6464 - - private void assertRdnssOptMatches(final StructNdOptRdnss opt, int length, long lifetime, - final Inet6Address[] servers) { - assertEquals(StructNdOptRdnss.TYPE, opt.type); - assertEquals(length, opt.length); - assertEquals(lifetime, opt.header.lifetime); - assertEquals(servers, opt.servers); - } - - private ByteBuffer makeRdnssOption(byte type, byte length, long lifetime, String... servers) - throws Exception { - final ByteBuffer buf = ByteBuffer.allocate(8 + servers.length * 16) - .put(type) - .put(length) - .putShort((short) 0) // Reserved - .putInt((int) (lifetime & 0xFFFFFFFFL)); - for (int i = 0; i < servers.length; i++) { - final byte[] rawBytes = - ((Inet6Address) InetAddresses.parseNumericAddress(servers[i])).getAddress(); - buf.put(rawBytes); - } - buf.flip(); - return buf; - } - - private void assertToByteBufferMatches(StructNdOptRdnss opt, String expected) { - String actual = HexEncoding.encodeToString(opt.toByteBuffer().array()); - assertEquals(expected, actual); - } - - private void doRdnssOptionParsing(final String optionHexString, int length, long lifetime, - final Inet6Address[] servers) { - final byte[] rawBytes = HexEncoding.decode(optionHexString); - final StructNdOptRdnss opt = StructNdOptRdnss.parse(ByteBuffer.wrap(rawBytes)); - assertRdnssOptMatches(opt, length, lifetime, servers); - assertToByteBufferMatches(opt, optionHexString); - } - - @Test - public void testParsing() throws Exception { - doRdnssOptionParsing(RDNSS_OPTION_BYTES, 5 /* length */, 3600 /* lifetime */, - DNS_SERVER_ADDRESSES); - } - - @Test - public void testParsing_infinityLifetime() throws Exception { - doRdnssOptionParsing(RDNSS_INFINITY_LIFETIME_OPTION_BYTES, 5 /* length */, - 0xffffffffL /* lifetime */, DNS_SERVER_ADDRESSES); - } - - @Test - public void testToByteBuffer() { - final StructNdOptRdnss rdnss = new StructNdOptRdnss(DNS_SERVER_ADDRESSES, 3600); - assertToByteBufferMatches(rdnss, RDNSS_OPTION_BYTES); - } - - @Test - public void testToByteBuffer_infinityLifetime() { - final StructNdOptRdnss rdnss = new StructNdOptRdnss(DNS_SERVER_ADDRESSES, 0xffffffffL); - assertToByteBufferMatches(rdnss, RDNSS_INFINITY_LIFETIME_OPTION_BYTES); - } - - @Test - public void testParsing_invalidType() throws Exception { - final ByteBuffer buf = makeRdnssOption((byte) 38, (byte) 5 /* length */, - 3600 /* lifetime */, DNS_SERVER1, DNS_SERVER2); - assertNull(StructNdOptRdnss.parse(buf)); - } - - @Test - public void testParsing_smallOptionLength() throws Exception { - final ByteBuffer buf = makeRdnssOption((byte) ICMPV6_ND_OPTION_RDNSS, - (byte) 2 /* length */, 3600 /* lifetime */, DNS_SERVER1, DNS_SERVER2); - assertNull(StructNdOptRdnss.parse(buf)); - } - - @Test - public void testParsing_oddOptionLength() throws Exception { - final ByteBuffer buf = makeRdnssOption((byte) ICMPV6_ND_OPTION_RDNSS, - (byte) 6 /* length */, 3600 /* lifetime */, DNS_SERVER1, DNS_SERVER2); - assertNull(StructNdOptRdnss.parse(buf)); - } - - @Test - public void testParsing_truncatedByteBuffer() throws Exception { - ByteBuffer buf = makeRdnssOption((byte) ICMPV6_ND_OPTION_RDNSS, - (byte) 5 /* length */, 3600 /* lifetime */, DNS_SERVER1, DNS_SERVER2); - final int len = buf.limit(); - for (int i = 0; i < buf.limit() - 1; i++) { - buf.flip(); - buf.limit(i); - assertNull("Option truncated to " + i + " bytes, should have returned null", - StructNdOptRdnss.parse(buf)); - } - buf.flip(); - buf.limit(len); - - final StructNdOptRdnss opt = StructNdOptRdnss.parse(buf); - assertRdnssOptMatches(opt, 5 /* length */, 3600 /* lifetime */, DNS_SERVER_ADDRESSES); - } - - @Test - public void testParsing_invalidByteBufferLength() throws Exception { - final ByteBuffer buf = makeRdnssOption((byte) ICMPV6_ND_OPTION_RDNSS, - (byte) 5 /* length */, 3600 /* lifetime */, DNS_SERVER1, DNS_SERVER2); - buf.limit(20); // less than MIN_OPT_LEN * 8 - assertNull(StructNdOptRdnss.parse(buf)); - } - - @Test - public void testConstructor_nullDnsServerAddressArray() { - assertThrows(NullPointerException.class, - () -> new StructNdOptRdnss(null /* servers */, 3600 /* lifetime */)); - } - - @Test - public void testConstructor_emptyDnsServerAddressArray() { - assertThrows(IllegalArgumentException.class, - () -> new StructNdOptRdnss(new Inet6Address[0] /* empty server array */, - 3600 /* lifetime*/)); - } - - @Test - public void testToString() { - final ByteBuffer buf = RdnssOption.build(3600 /* lifetime */, DNS_SERVER1, DNS_SERVER2); - final StructNdOptRdnss opt = StructNdOptRdnss.parse(buf); - final String expected = "NdOptRdnss(type: 25, length: 5, reserved: 0, lifetime: 3600," - + "servers:[2001:4860:4860::64,2001:4860:4860::6464])"; - assertRdnssOptMatches(opt, 5 /* length */, 3600 /* lifetime */, DNS_SERVER_ADDRESSES); - assertEquals(expected, opt.toString()); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/netlink/StructNlAttrTest.java b/common/tests/unit/src/com/android/net/module/util/netlink/StructNlAttrTest.java deleted file mode 100644 index af3fac2e..00000000 --- a/common/tests/unit/src/com/android/net/module/util/netlink/StructNlAttrTest.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * 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.net.module.util.netlink; - -import static com.android.net.module.util.netlink.RtNetlinkAddressMessage.IFA_FLAGS; -import static com.android.net.module.util.netlink.RtNetlinkLinkMessage.IFLA_ADDRESS; -import static com.android.net.module.util.netlink.RtNetlinkLinkMessage.IFLA_IFNAME; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; - -import android.net.MacAddress; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class StructNlAttrTest { - private static final MacAddress TEST_MAC_ADDRESS = MacAddress.fromString("00:11:22:33:44:55"); - private static final String TEST_INTERFACE_NAME = "wlan0"; - private static final int TEST_ADDR_FLAGS = 0x80; - - @Test - public void testGetValueAsMacAddress() { - final StructNlAttr attr1 = new StructNlAttr(IFLA_ADDRESS, TEST_MAC_ADDRESS); - final MacAddress address1 = attr1.getValueAsMacAddress(); - assertEquals(address1, TEST_MAC_ADDRESS); - - // Invalid mac address byte array. - final byte[] array = new byte[] { - (byte) 0x00, (byte) 0x11, (byte) 0x22, (byte) 0x33, - (byte) 0x44, (byte) 0x55, (byte) 0x66, - }; - final StructNlAttr attr2 = new StructNlAttr(IFLA_ADDRESS, array); - final MacAddress address2 = attr2.getValueAsMacAddress(); - assertNull(address2); - } - - @Test - public void testGetValueAsString() { - final StructNlAttr attr1 = new StructNlAttr(IFLA_IFNAME, TEST_INTERFACE_NAME); - final String str1 = attr1.getValueAsString(); - assertEquals(str1, TEST_INTERFACE_NAME); - - final byte[] array = new byte[] { - (byte) 0x77, (byte) 0x6c, (byte) 0x61, (byte) 0x6E, (byte) 0x30, (byte) 0x00, - }; - final StructNlAttr attr2 = new StructNlAttr(IFLA_IFNAME, array); - final String str2 = attr2.getValueAsString(); - assertEquals(str2, TEST_INTERFACE_NAME); - } - - @Test - public void testGetValueAsIntger() { - final StructNlAttr attr1 = new StructNlAttr(IFA_FLAGS, TEST_ADDR_FLAGS); - final Integer integer1 = attr1.getValueAsInteger(); - final int int1 = attr1.getValueAsInt(0x08 /* default value */); - assertEquals(integer1, new Integer(TEST_ADDR_FLAGS)); - assertEquals(int1, TEST_ADDR_FLAGS); - - // Malformed attribute. - final byte[] malformed_int = new byte[] { (byte) 0x0, (byte) 0x0, (byte) 0x80, }; - final StructNlAttr attr2 = new StructNlAttr(IFA_FLAGS, malformed_int); - final Integer integer2 = attr2.getValueAsInteger(); - final int int2 = attr2.getValueAsInt(0x08 /* default value */); - assertNull(integer2); - assertEquals(int2, 0x08 /* default value */); - - // Null attribute value. - final byte[] null_int = null; - final StructNlAttr attr3 = new StructNlAttr(IFA_FLAGS, null_int); - final Integer integer3 = attr3.getValueAsInteger(); - final int int3 = attr3.getValueAsInt(0x08 /* default value */); - assertNull(integer3); - assertEquals(int3, 0x08 /* default value */); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/netlink/StructNlMsgHdrTest.java b/common/tests/unit/src/com/android/net/module/util/netlink/StructNlMsgHdrTest.java deleted file mode 100644 index b7f68c62..00000000 --- a/common/tests/unit/src/com/android/net/module/util/netlink/StructNlMsgHdrTest.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2020 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.net.module.util.netlink; - -import static org.junit.Assert.fail; - -import android.system.OsConstants; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class StructNlMsgHdrTest { - - public static final short TEST_NLMSG_LEN = 16; - public static final short TEST_NLMSG_FLAGS = StructNlMsgHdr.NLM_F_REQUEST - | StructNlMsgHdr.NLM_F_MULTI | StructNlMsgHdr.NLM_F_ACK | StructNlMsgHdr.NLM_F_ECHO; - public static final short TEST_NLMSG_SEQ = 1234; - public static final short TEST_NLMSG_PID = 5678; - - // Checking the header string nlmsg_{len, ..} of the number can make sure that the checking - // number comes from the expected element. - // TODO: Verify more flags once StructNlMsgHdr can distinguish the flags which have the same - // value. For example, NLM_F_MATCH (0x200) and NLM_F_EXCL (0x200) can't be distinguished. - // See StructNlMsgHdrTest#stringForNlMsgFlags. - public static final String TEST_NLMSG_LEN_STR = "nlmsg_len{16}"; - public static final String TEST_NLMSG_FLAGS_STR = - "NLM_F_REQUEST|NLM_F_MULTI|NLM_F_ACK|NLM_F_ECHO"; - public static final String TEST_NLMSG_SEQ_STR = "nlmsg_seq{1234}"; - public static final String TEST_NLMSG_PID_STR = "nlmsg_pid{5678}"; - - private StructNlMsgHdr makeStructNlMsgHdr(short type) { - final StructNlMsgHdr struct = new StructNlMsgHdr(); - struct.nlmsg_len = TEST_NLMSG_LEN; - struct.nlmsg_type = type; - struct.nlmsg_flags = TEST_NLMSG_FLAGS; - struct.nlmsg_seq = TEST_NLMSG_SEQ; - struct.nlmsg_pid = TEST_NLMSG_PID; - return struct; - } - - private static void assertContains(String actualValue, String expectedSubstring) { - if (actualValue.contains(expectedSubstring)) return; - fail("\"" + actualValue + "\" does not contain \"" + expectedSubstring + "\""); - } - - @Test - public void testToString() { - StructNlMsgHdr struct = makeStructNlMsgHdr(NetlinkConstants.RTM_NEWADDR); - String s = struct.toString(); - assertContains(s, TEST_NLMSG_LEN_STR); - assertContains(s, TEST_NLMSG_FLAGS_STR); - assertContains(s, TEST_NLMSG_SEQ_STR); - assertContains(s, TEST_NLMSG_PID_STR); - assertContains(s, "nlmsg_type{20()}"); - - struct = makeStructNlMsgHdr(NetlinkConstants.SOCK_DIAG_BY_FAMILY); - s = struct.toString(); - assertContains(s, TEST_NLMSG_LEN_STR); - assertContains(s, TEST_NLMSG_FLAGS_STR); - assertContains(s, TEST_NLMSG_SEQ_STR); - assertContains(s, TEST_NLMSG_PID_STR); - assertContains(s, "nlmsg_type{20()}"); - } - - @Test - public void testToStringWithNetlinkFamily() { - StructNlMsgHdr struct = makeStructNlMsgHdr(NetlinkConstants.RTM_NEWADDR); - String s = struct.toString(OsConstants.NETLINK_ROUTE); - assertContains(s, TEST_NLMSG_LEN_STR); - assertContains(s, TEST_NLMSG_FLAGS_STR); - assertContains(s, TEST_NLMSG_SEQ_STR); - assertContains(s, TEST_NLMSG_PID_STR); - assertContains(s, "nlmsg_type{20(RTM_NEWADDR)}"); - - struct = makeStructNlMsgHdr(NetlinkConstants.SOCK_DIAG_BY_FAMILY); - s = struct.toString(OsConstants.NETLINK_INET_DIAG); - assertContains(s, TEST_NLMSG_LEN_STR); - assertContains(s, TEST_NLMSG_FLAGS_STR); - assertContains(s, TEST_NLMSG_SEQ_STR); - assertContains(s, TEST_NLMSG_PID_STR); - assertContains(s, "nlmsg_type{20(SOCK_DIAG_BY_FAMILY)}"); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/wear/NetPacketHelpersTest.java b/common/tests/unit/src/com/android/net/module/util/wear/NetPacketHelpersTest.java deleted file mode 100644 index 23e7b15e..00000000 --- a/common/tests/unit/src/com/android/net/module/util/wear/NetPacketHelpersTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2023 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.net.module.util.wear; - -import static org.junit.Assert.assertEquals; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import com.android.net.module.util.async.CircularByteBuffer; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class NetPacketHelpersTest { - @Test - public void decodeNetworkUnsignedInt16() { - final byte[] data = new byte[4]; - data[0] = (byte) 0xFF; - data[1] = (byte) 1; - data[2] = (byte) 2; - data[3] = (byte) 0xFF; - - assertEquals(0x0102, NetPacketHelpers.decodeNetworkUnsignedInt16(data, 1)); - - CircularByteBuffer buffer = new CircularByteBuffer(100); - buffer.writeBytes(data, 0, data.length); - - assertEquals(0x0102, NetPacketHelpers.decodeNetworkUnsignedInt16(buffer, 1)); - } - - @Test - public void encodeNetworkUnsignedInt16() { - final byte[] data = new byte[4]; - data[0] = (byte) 0xFF; - data[3] = (byte) 0xFF; - NetPacketHelpers.encodeNetworkUnsignedInt16(0x0102, data, 1); - - assertEquals((byte) 0xFF, data[0]); - assertEquals((byte) 1, data[1]); - assertEquals((byte) 2, data[2]); - assertEquals((byte) 0xFF, data[3]); - } -} diff --git a/common/tests/unit/src/com/android/net/module/util/wear/StreamingPacketFileTest.java b/common/tests/unit/src/com/android/net/module/util/wear/StreamingPacketFileTest.java deleted file mode 100644 index 1fcca704..00000000 --- a/common/tests/unit/src/com/android/net/module/util/wear/StreamingPacketFileTest.java +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright (C) 2023 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.net.module.util.wear; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.ignoreStubs; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import android.os.ParcelFileDescriptor; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.net.module.util.async.AsyncFile; -import com.android.net.module.util.async.BufferedFile; -import com.android.net.module.util.async.EventManager; -import com.android.net.module.util.async.FileHandle; -import com.android.net.module.util.async.ReadableByteBuffer; -import com.android.testutils.async.ReadableDataAnswer; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class StreamingPacketFileTest { - private static final int MAX_PACKET_SIZE = 100; - - @Mock EventManager mockEventManager; - @Mock PacketFile.Listener mockFileListener; - @Mock AsyncFile mockAsyncFile; - @Mock ParcelFileDescriptor mockParcelFileDescriptor; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - } - - @After - public void tearDown() throws Exception { - verifyNoMoreInteractions(ignoreStubs(mockFileListener, mockAsyncFile, mockEventManager)); - } - - @Test - public void continueReadingAndClose() throws Exception { - final int maxBufferedInboundPackets = 3; - final int maxBufferedOutboundPackets = 5; - - final StreamingPacketFile file = - createFile(maxBufferedInboundPackets, maxBufferedOutboundPackets); - final BufferedFile bufferedFile = file.getUnderlyingFileForTest(); - - assertEquals(maxBufferedInboundPackets * (MAX_PACKET_SIZE + 2), - bufferedFile.getInboundBufferFreeSizeForTest()); - assertEquals(maxBufferedOutboundPackets * (MAX_PACKET_SIZE + 2), - bufferedFile.getOutboundBufferFreeSize()); - assertEquals(bufferedFile.getOutboundBufferFreeSize() - 2, - file.getOutboundFreeSize()); - - file.continueReading(); - verify(mockAsyncFile).enableReadEvents(true); - - file.close(); - verify(mockAsyncFile).close(); - } - - @Test - public void enqueueOutboundPacket() throws Exception { - final int maxBufferedInboundPackets = 10; - final int maxBufferedOutboundPackets = 20; - - final StreamingPacketFile file = - createFile(maxBufferedInboundPackets, maxBufferedOutboundPackets); - final BufferedFile bufferedFile = file.getUnderlyingFileForTest(); - - final byte[] packet1 = new byte[11]; - final byte[] packet2 = new byte[12]; - packet1[0] = (byte) 1; - packet2[0] = (byte) 2; - - assertEquals(0, bufferedFile.getOutboundBufferSize()); - - when(mockAsyncFile.write(any(), anyInt(), anyInt())).thenReturn(0); - assertTrue(file.enqueueOutboundPacket(packet1, 0, packet1.length)); - verify(mockAsyncFile).enableWriteEvents(true); - - assertEquals(packet1.length + 2, bufferedFile.getOutboundBufferSize()); - - checkAndResetMocks(); - - final int totalLen = packet1.length + packet2.length + 4; - - final ArgumentCaptor<byte[]> arrayCaptor = ArgumentCaptor.forClass(byte[].class); - final ArgumentCaptor<Integer> posCaptor = ArgumentCaptor.forClass(Integer.class); - final ArgumentCaptor<Integer> lenCaptor = ArgumentCaptor.forClass(Integer.class); - when(mockAsyncFile.write( - arrayCaptor.capture(), posCaptor.capture(), lenCaptor.capture())).thenReturn(totalLen); - - assertTrue(file.enqueueOutboundPacket(packet2, 0, packet2.length)); - - assertEquals(0, bufferedFile.getInboundBuffer().size()); - assertEquals(0, bufferedFile.getOutboundBufferSize()); - - assertEquals(0, posCaptor.getValue().intValue()); - assertEquals(totalLen, lenCaptor.getValue().intValue()); - - final byte[] capturedData = arrayCaptor.getValue(); - assertEquals(packet1.length, NetPacketHelpers.decodeNetworkUnsignedInt16(capturedData, 0)); - assertEquals(packet2.length, - NetPacketHelpers.decodeNetworkUnsignedInt16(capturedData, packet1.length + 2)); - assertEquals(packet1[0], capturedData[2]); - assertEquals(packet2[0], capturedData[packet1.length + 4]); - } - - @Test - public void onInboundPacket() throws Exception { - final int maxBufferedInboundPackets = 10; - final int maxBufferedOutboundPackets = 20; - - final StreamingPacketFile file = - createFile(maxBufferedInboundPackets, maxBufferedOutboundPackets); - final BufferedFile bufferedFile = file.getUnderlyingFileForTest(); - final ReadableByteBuffer inboundBuffer = bufferedFile.getInboundBuffer(); - - final int len1 = 11; - final int len2 = 12; - final byte[] data = new byte[len1 + len2 + 4]; - NetPacketHelpers.encodeNetworkUnsignedInt16(len1, data, 0); - NetPacketHelpers.encodeNetworkUnsignedInt16(len2, data, 11 + 2); - data[2] = (byte) 1; - data[len1 + 4] = (byte) 2; - - final ReadableDataAnswer dataAnswer = new ReadableDataAnswer(data); - - final ArgumentCaptor<byte[]> arrayCaptor = ArgumentCaptor.forClass(byte[].class); - final ArgumentCaptor<Integer> posCaptor = ArgumentCaptor.forClass(Integer.class); - final ArgumentCaptor<Integer> lenCaptor = ArgumentCaptor.forClass(Integer.class); - - when(mockAsyncFile.read(any(), anyInt(), anyInt())).thenAnswer(dataAnswer); - when(mockFileListener.onPreambleData(any(), eq(0), eq(data.length))).thenReturn(0); - bufferedFile.onReadReady(mockAsyncFile); - verify(mockAsyncFile).enableReadEvents(true); - verify(mockFileListener).onInboundBuffered(data.length, data.length); - verify(mockFileListener).onInboundPacket( - arrayCaptor.capture(), posCaptor.capture(), lenCaptor.capture()); - verify(mockEventManager).execute(any()); - - byte[] capturedData = arrayCaptor.getValue(); - assertEquals(2, posCaptor.getValue().intValue()); - assertEquals(len1, lenCaptor.getValue().intValue()); - assertEquals((byte) 1, capturedData[2]); - - checkAndResetMocks(); - - when(mockAsyncFile.read(any(), anyInt(), anyInt())).thenAnswer(dataAnswer); - file.onBufferedFileInboundData(0); - verify(mockFileListener).onInboundPacket( - arrayCaptor.capture(), posCaptor.capture(), lenCaptor.capture()); - verify(mockEventManager).execute(any()); - - capturedData = arrayCaptor.getValue(); - assertEquals(2, posCaptor.getValue().intValue()); - assertEquals(len2, lenCaptor.getValue().intValue()); - assertEquals((byte) 2, capturedData[2]); - - assertEquals(0, bufferedFile.getOutboundBufferSize()); - assertEquals(0, inboundBuffer.size()); - } - - @Test - public void onReadReady_preambleData() throws Exception { - final int maxBufferedInboundPackets = 10; - final int maxBufferedOutboundPackets = 20; - - final StreamingPacketFile file = - createFile(maxBufferedInboundPackets, maxBufferedOutboundPackets); - final BufferedFile bufferedFile = file.getUnderlyingFileForTest(); - final ReadableByteBuffer inboundBuffer = bufferedFile.getInboundBuffer(); - - final int preambleLen = 23; - final int len1 = 11; - final byte[] data = new byte[preambleLen + 2 + len1]; - NetPacketHelpers.encodeNetworkUnsignedInt16(len1, data, preambleLen); - data[preambleLen + 2] = (byte) 1; - - final ReadableDataAnswer dataAnswer = new ReadableDataAnswer(data); - - when(mockAsyncFile.read(any(), anyInt(), anyInt())).thenAnswer(dataAnswer); - when(mockFileListener.onPreambleData(any(), eq(0), eq(data.length))).thenReturn(5); - when(mockFileListener.onPreambleData( - any(), eq(0), eq(data.length - 5))).thenReturn(preambleLen - 5); - when(mockFileListener.onPreambleData( - any(), eq(0), eq(data.length - preambleLen))).thenReturn(0); - - bufferedFile.onReadReady(mockAsyncFile); - - final ArgumentCaptor<byte[]> arrayCaptor = ArgumentCaptor.forClass(byte[].class); - final ArgumentCaptor<Integer> posCaptor = ArgumentCaptor.forClass(Integer.class); - final ArgumentCaptor<Integer> lenCaptor = ArgumentCaptor.forClass(Integer.class); - - verify(mockFileListener).onInboundBuffered(data.length, data.length); - verify(mockFileListener).onInboundPacket( - arrayCaptor.capture(), posCaptor.capture(), lenCaptor.capture()); - verify(mockEventManager).execute(any()); - verify(mockAsyncFile).enableReadEvents(true); - - final byte[] capturedData = arrayCaptor.getValue(); - assertEquals(2, posCaptor.getValue().intValue()); - assertEquals(len1, lenCaptor.getValue().intValue()); - assertEquals((byte) 1, capturedData[2]); - - assertEquals(0, bufferedFile.getOutboundBufferSize()); - assertEquals(0, inboundBuffer.size()); - } - - @Test - public void shutdownReading() throws Exception { - final int maxBufferedInboundPackets = 10; - final int maxBufferedOutboundPackets = 20; - - final StreamingPacketFile file = - createFile(maxBufferedInboundPackets, maxBufferedOutboundPackets); - final BufferedFile bufferedFile = file.getUnderlyingFileForTest(); - - final byte[] data = new byte[100]; - final ReadableDataAnswer dataAnswer = new ReadableDataAnswer(data); - when(mockAsyncFile.read(any(), anyInt(), anyInt())).thenAnswer(dataAnswer); - - doAnswer(new Answer() { - @Override public Object answer(InvocationOnMock invocation) { - file.shutdownReading(); - return Integer.valueOf(-1); - }}).when(mockFileListener).onPreambleData(any(), anyInt(), anyInt()); - - bufferedFile.onReadReady(mockAsyncFile); - - verify(mockFileListener).onInboundBuffered(data.length, data.length); - verify(mockAsyncFile).enableReadEvents(false); - - assertEquals(0, bufferedFile.getInboundBuffer().size()); - } - - private void checkAndResetMocks() { - verifyNoMoreInteractions(ignoreStubs(mockFileListener, mockAsyncFile, mockEventManager, - mockParcelFileDescriptor)); - reset(mockFileListener, mockAsyncFile, mockEventManager); - } - - private StreamingPacketFile createFile( - int maxBufferedInboundPackets, int maxBufferedOutboundPackets) throws Exception { - when(mockEventManager.registerFile(any(), any())).thenReturn(mockAsyncFile); - return new StreamingPacketFile( - mockEventManager, - FileHandle.fromFileDescriptor(mockParcelFileDescriptor), - mockFileListener, - MAX_PACKET_SIZE, - maxBufferedInboundPackets, - maxBufferedOutboundPackets); - } -} diff --git a/common/tests/unit/src/com/android/testutils/DeviceInfoUtilsTest.java b/common/tests/unit/src/com/android/testutils/DeviceInfoUtilsTest.java deleted file mode 100644 index e46dd599..00000000 --- a/common/tests/unit/src/com/android/testutils/DeviceInfoUtilsTest.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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.testutils; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertTrue; - -import androidx.test.filters.SmallTest; - -import org.junit.Test; - -@SmallTest -public final class DeviceInfoUtilsTest { - /** - * Verifies that version string compare logic returns expected result for various cases. - * Note that only major and minor number are compared. - */ - @Test - public void testMajorMinorVersionCompare() { - assertEquals(0, DeviceInfoUtils.compareMajorMinorVersion("4.8.1", "4.8")); - assertEquals(1, DeviceInfoUtils.compareMajorMinorVersion("4.9", "4.8.1")); - assertEquals(1, DeviceInfoUtils.compareMajorMinorVersion("5.0", "4.8")); - assertEquals(1, DeviceInfoUtils.compareMajorMinorVersion("5", "4.8")); - assertEquals(0, DeviceInfoUtils.compareMajorMinorVersion("5", "5.0")); - assertEquals(1, DeviceInfoUtils.compareMajorMinorVersion("5-beta1", "4.8")); - assertEquals(0, DeviceInfoUtils.compareMajorMinorVersion("4.8.0.0", "4.8")); - assertEquals(0, DeviceInfoUtils.compareMajorMinorVersion("4.8-RC1", "4.8")); - assertEquals(0, DeviceInfoUtils.compareMajorMinorVersion("4.8", "4.8")); - assertEquals(-1, DeviceInfoUtils.compareMajorMinorVersion("3.10", "4.8.0")); - assertEquals(-1, DeviceInfoUtils.compareMajorMinorVersion("4.7.10.10", "4.8")); - } - - @Test - public void testGetMajorMinorSubminorVersion() throws Exception { - final DeviceInfoUtils.KVersion expected = new DeviceInfoUtils.KVersion(4, 19, 220); - assertEquals(expected, DeviceInfoUtils.getMajorMinorSubminorVersion("4.19.220")); - assertEquals(expected, DeviceInfoUtils.getMajorMinorSubminorVersion("4.19.220.50")); - assertEquals(expected, DeviceInfoUtils.getMajorMinorSubminorVersion( - "4.19.220-g500ede0aed22-ab8272303")); - - final DeviceInfoUtils.KVersion expected2 = new DeviceInfoUtils.KVersion(5, 17, 0); - assertEquals(expected2, DeviceInfoUtils.getMajorMinorSubminorVersion("5.17")); - assertEquals(expected2, DeviceInfoUtils.getMajorMinorSubminorVersion("5.17.")); - assertEquals(expected2, DeviceInfoUtils.getMajorMinorSubminorVersion("5.17.beta")); - assertEquals(expected2, DeviceInfoUtils.getMajorMinorSubminorVersion( - "5.17-rc6-g52099515ca00-ab8032400")); - - final DeviceInfoUtils.KVersion invalid = new DeviceInfoUtils.KVersion(0, 0, 0); - assertEquals(invalid, DeviceInfoUtils.getMajorMinorSubminorVersion("")); - assertEquals(invalid, DeviceInfoUtils.getMajorMinorSubminorVersion("4")); - assertEquals(invalid, DeviceInfoUtils.getMajorMinorSubminorVersion("4.")); - assertEquals(invalid, DeviceInfoUtils.getMajorMinorSubminorVersion("4-beta")); - assertEquals(invalid, DeviceInfoUtils.getMajorMinorSubminorVersion("1.x.1")); - assertEquals(invalid, DeviceInfoUtils.getMajorMinorSubminorVersion("x.1.1")); - } - - @Test - public void testVersion() throws Exception { - final DeviceInfoUtils.KVersion v1 = new DeviceInfoUtils.KVersion(4, 8, 1); - final DeviceInfoUtils.KVersion v2 = new DeviceInfoUtils.KVersion(4, 8, 1); - final DeviceInfoUtils.KVersion v3 = new DeviceInfoUtils.KVersion(4, 8, 2); - final DeviceInfoUtils.KVersion v4 = new DeviceInfoUtils.KVersion(4, 9, 1); - final DeviceInfoUtils.KVersion v5 = new DeviceInfoUtils.KVersion(5, 8, 1); - - assertEquals(v1, v2); - assertNotEquals(v1, v3); - assertNotEquals(v1, v4); - assertNotEquals(v1, v5); - - assertEquals(0, v1.compareTo(v2)); - assertEquals(-1, v1.compareTo(v3)); - assertEquals(1, v3.compareTo(v1)); - assertEquals(-1, v1.compareTo(v4)); - assertEquals(1, v4.compareTo(v1)); - assertEquals(-1, v1.compareTo(v5)); - assertEquals(1, v5.compareTo(v1)); - - assertTrue(v2.isInRange(v1, v5)); - assertTrue(v3.isInRange(v1, v5)); - assertTrue(v4.isInRange(v1, v5)); - assertFalse(v5.isInRange(v1, v5)); - assertFalse(v1.isInRange(v3, v5)); - assertFalse(v5.isInRange(v2, v4)); - - assertTrue(v2.isAtLeast(v1)); - assertTrue(v3.isAtLeast(v1)); - assertTrue(v4.isAtLeast(v1)); - assertTrue(v5.isAtLeast(v1)); - assertFalse(v1.isAtLeast(v3)); - assertFalse(v1.isAtLeast(v4)); - assertFalse(v1.isAtLeast(v5)); - } - - @Test - public void testKernelVersionIsAtLeast() { - // Pick a lower kernel version 4.0 which was released at April 2015, the kernel - // version running on all test devices nowadays should be higher than it. - assertTrue(DeviceInfoUtils.isKernelVersionAtLeast("4.0")); - - // Invalid kernel version. - assertTrue(DeviceInfoUtils.isKernelVersionAtLeast("0.0.0")); - - // Pick a higher kernel version which isn't released yet, comparison should return false. - // Need to update the target version in the future to make sure the test still passes. - assertFalse(DeviceInfoUtils.isKernelVersionAtLeast("20.0.0")); - } -} diff --git a/common/tests/unit/src/com/android/testutils/HandlerUtilsTest.kt b/common/tests/unit/src/com/android/testutils/HandlerUtilsTest.kt deleted file mode 100644 index 0f6fa48b..00000000 --- a/common/tests/unit/src/com/android/testutils/HandlerUtilsTest.kt +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2019 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.testutils - -import android.os.Handler -import android.os.HandlerThread -import com.android.testutils.FunctionalUtils.ThrowingSupplier -import kotlin.test.assertEquals -import kotlin.test.assertFailsWith -import kotlin.test.assertNull -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.JUnit4 - -private const val ATTEMPTS = 50 // Causes testWaitForIdle to take about 150ms on aosp_crosshatch-eng -private const val TIMEOUT_MS = 200 - -@RunWith(JUnit4::class) -class HandlerUtilsTest { - @Test - fun testWaitForIdle() { - val handlerThread = HandlerThread("testHandler").apply { start() } - - // Tests that waitForIdle can be called many times without ill impact if the service is - // already idle. - repeat(ATTEMPTS) { - handlerThread.waitForIdle(TIMEOUT_MS) - } - - // Tests that calling waitForIdle waits for messages to be processed. Use both an - // inline runnable that's instantiated at each loop run and a runnable that's instantiated - // once for all. - val tempRunnable = object : Runnable { - // Use StringBuilder preferentially to StringBuffer because StringBuilder is NOT - // thread-safe. It's part of the point that both runnables run on the same thread - // so if anything is wrong in that space it's better to opportunistically use a class - // where things might go wrong, even if there is no guarantee of failure. - var memory = StringBuilder() - override fun run() { - memory.append("b") - } - } - repeat(ATTEMPTS) { i -> - handlerThread.threadHandler.post { tempRunnable.memory.append("a"); } - handlerThread.threadHandler.post(tempRunnable) - handlerThread.waitForIdle(TIMEOUT_MS) - assertEquals(tempRunnable.memory.toString(), "ab".repeat(i + 1)) - } - } - - // Statistical test : even if visibleOnHandlerThread doesn't work this is likely to succeed, - // but it will be at least flaky. - @Test - fun testVisibleOnHandlerThread() { - val handlerThread = HandlerThread("testHandler").apply { start() } - val handler = Handler(handlerThread.looper) - - repeat(ATTEMPTS) { attempt -> - var x = -10 - var y = -11 - y = visibleOnHandlerThread(handler, ThrowingSupplier<Int> { x = attempt; attempt }) - assertEquals(attempt, x) - assertEquals(attempt, y) - handler.post { assertEquals(attempt, x) } - } - - assertFailsWith<IllegalArgumentException> { - visibleOnHandlerThread(handler) { throw IllegalArgumentException() } - } - - // Null values may be returned by the supplier - assertNull(visibleOnHandlerThread(handler, ThrowingSupplier<Nothing?> { null })) - } -} diff --git a/common/tests/unit/src/com/android/testutils/TestDnsServerTest.kt b/common/tests/unit/src/com/android/testutils/TestDnsServerTest.kt deleted file mode 100644 index 6f4587b1..00000000 --- a/common/tests/unit/src/com/android/testutils/TestDnsServerTest.kt +++ /dev/null @@ -1,122 +0,0 @@ -/* - * 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.testutils - -import android.net.DnsResolver.CLASS_IN -import android.net.DnsResolver.TYPE_AAAA -import android.net.Network -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.filters.SmallTest -import com.android.net.module.util.DnsPacket -import com.android.net.module.util.DnsPacket.DnsRecord -import libcore.net.InetAddressUtils -import org.junit.After -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mockito -import java.net.DatagramPacket -import java.net.DatagramSocket -import java.net.InetAddress -import java.net.InetSocketAddress -import kotlin.test.assertEquals -import kotlin.test.assertFailsWith -import kotlin.test.assertFalse -import kotlin.test.assertTrue - -val TEST_V6_ADDR = InetAddressUtils.parseNumericAddress("2001:db8::3") -const val TEST_DOMAIN = "hello.example.com" - -@RunWith(AndroidJUnit4::class) -@SmallTest -class TestDnsServerTest { - private val network = Mockito.mock(Network::class.java) - private val localAddr = InetSocketAddress(InetAddress.getLocalHost(), 0 /* port */) - private val testServer: TestDnsServer = TestDnsServer(network, localAddr) - - @After - fun tearDown() { - if (testServer.isAlive) testServer.stop() - } - - @Test - fun testStartStop() { - repeat(100) { - val server = TestDnsServer(network, localAddr) - server.start() - assertTrue(server.isAlive) - server.stop() - assertFalse(server.isAlive) - } - - // Test illegal start/stop. - assertFailsWith<IllegalStateException> { testServer.stop() } - testServer.start() - assertTrue(testServer.isAlive) - assertFailsWith<IllegalStateException> { testServer.start() } - testServer.stop() - assertFalse(testServer.isAlive) - assertFailsWith<IllegalStateException> { testServer.stop() } - // TestDnsServer rejects start after stop. - assertFailsWith<IllegalStateException> { testServer.start() } - } - - @Test - fun testHandleDnsQuery() { - testServer.setAnswer(TEST_DOMAIN, listOf(TEST_V6_ADDR)) - testServer.start() - - // Mock query and send it to the test server. - val queryHeader = DnsPacket.DnsHeader(0xbeef /* id */, - 0x0 /* flag */, 1 /* qcount */, 0 /* ancount */) - val qlist = listOf(DnsRecord.makeQuestion(TEST_DOMAIN, TYPE_AAAA, CLASS_IN)) - val queryPacket = TestDnsServer.DnsQueryPacket(queryHeader, qlist, emptyList()) - val response = resolve(queryPacket, testServer.port) - - // Verify expected answer packet. Set QR bit of flag to 1 for response packet - // according to RFC 1035 section 4.1.1. - val answerHeader = DnsPacket.DnsHeader(0xbeef, - 1 shl 15 /* flag */, 1 /* qcount */, 1 /* ancount */) - val alist = listOf(DnsRecord.makeAOrAAAARecord(DnsPacket.ANSECTION, TEST_DOMAIN, - CLASS_IN, DEFAULT_TTL_S, TEST_V6_ADDR)) - val expectedAnswerPacket = TestDnsServer.DnsAnswerPacket(answerHeader, qlist, alist) - assertEquals(expectedAnswerPacket, response) - - // Clean up the server in tearDown. - } - - private fun resolve(queryDnsPacket: DnsPacket, serverPort: Int): TestDnsServer.DnsAnswerPacket { - val bytes = queryDnsPacket.bytes - // Create a new client socket, the socket will be bound to a - // random port other than the server port. - val socket = DatagramSocket(localAddr).also { it.soTimeout = 100 } - val queryPacket = DatagramPacket(bytes, bytes.size, localAddr.address, serverPort) - - // Send query and wait for the reply. - socket.send(queryPacket) - val buffer = ByteArray(MAX_BUF_SIZE) - val reply = DatagramPacket(buffer, buffer.size) - socket.receive(reply) - return TestDnsServer.DnsAnswerPacket(reply.data) - } - - // TODO: Add more tests, which includes: - // * Empty question RR packet (or more unexpected states) - // * No answer found (setAnswer empty list at L.78) - // * Test one or multi A record(s) - // * Test multi AAAA records - // * Test CNAME records -} diff --git a/common/tests/unit/src/com/android/testutils/TestableNetworkCallbackTest.kt b/common/tests/unit/src/com/android/testutils/TestableNetworkCallbackTest.kt deleted file mode 100644 index e838bdc5..00000000 --- a/common/tests/unit/src/com/android/testutils/TestableNetworkCallbackTest.kt +++ /dev/null @@ -1,474 +0,0 @@ -/* - * 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.testutils - -import android.annotation.SuppressLint -import android.net.LinkAddress -import android.net.LinkProperties -import android.net.Network -import android.net.NetworkCapabilities -import com.android.testutils.RecorderCallback.CallbackEntry -import com.android.testutils.RecorderCallback.CallbackEntry.Available -import com.android.testutils.RecorderCallback.CallbackEntry.BlockedStatus -import com.android.testutils.RecorderCallback.CallbackEntry.CapabilitiesChanged -import com.android.testutils.RecorderCallback.CallbackEntry.Companion.AVAILABLE -import com.android.testutils.RecorderCallback.CallbackEntry.Companion.BLOCKED_STATUS -import com.android.testutils.RecorderCallback.CallbackEntry.Companion.LINK_PROPERTIES_CHANGED -import com.android.testutils.RecorderCallback.CallbackEntry.Companion.LOSING -import com.android.testutils.RecorderCallback.CallbackEntry.Companion.LOST -import com.android.testutils.RecorderCallback.CallbackEntry.Companion.NETWORK_CAPS_UPDATED -import com.android.testutils.RecorderCallback.CallbackEntry.Companion.RESUMED -import com.android.testutils.RecorderCallback.CallbackEntry.Companion.SUSPENDED -import com.android.testutils.RecorderCallback.CallbackEntry.Companion.UNAVAILABLE -import com.android.testutils.RecorderCallback.CallbackEntry.LinkPropertiesChanged -import kotlin.reflect.KClass -import kotlin.test.assertEquals -import kotlin.test.assertFails -import kotlin.test.assertNull -import kotlin.test.assertTrue -import kotlin.test.fail -import org.junit.Assume.assumeTrue -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.JUnit4 - -const val SHORT_TIMEOUT_MS = 20L -const val DEFAULT_LINGER_DELAY_MS = 30000 -const val NOT_METERED = NetworkCapabilities.NET_CAPABILITY_NOT_METERED -const val WIFI = NetworkCapabilities.TRANSPORT_WIFI -const val CELLULAR = NetworkCapabilities.TRANSPORT_CELLULAR -const val TEST_INTERFACE_NAME = "testInterfaceName" - -@RunWith(JUnit4::class) -@SuppressLint("NewApi") // Uses hidden APIs, which the linter would identify as missing APIs. -class TestableNetworkCallbackTest { - private lateinit var mCallback: TestableNetworkCallback - - private fun makeHasNetwork(netId: Int) = object : TestableNetworkCallback.HasNetwork { - override val network: Network = Network(netId) - } - - @Before - fun setUp() { - mCallback = TestableNetworkCallback() - } - - @Test - fun testLastAvailableNetwork() { - // Make sure there is no last available network at first, then the last available network - // is returned after onAvailable is called. - val net2097 = Network(2097) - assertNull(mCallback.lastAvailableNetwork) - mCallback.onAvailable(net2097) - assertEquals(mCallback.lastAvailableNetwork, net2097) - - // Make sure calling onCapsChanged/onLinkPropertiesChanged don't affect the last available - // network. - mCallback.onCapabilitiesChanged(net2097, NetworkCapabilities()) - mCallback.onLinkPropertiesChanged(net2097, LinkProperties()) - assertEquals(mCallback.lastAvailableNetwork, net2097) - - // Make sure onLost clears the last available network. - mCallback.onLost(net2097) - assertNull(mCallback.lastAvailableNetwork) - - // Do the same but with a different network after onLost : make sure the last available - // network is the new one, not the original one. - val net2098 = Network(2098) - mCallback.onAvailable(net2098) - mCallback.onCapabilitiesChanged(net2098, NetworkCapabilities()) - mCallback.onLinkPropertiesChanged(net2098, LinkProperties()) - assertEquals(mCallback.lastAvailableNetwork, net2098) - - // Make sure onAvailable changes the last available network even if onLost was not called. - val net2099 = Network(2099) - mCallback.onAvailable(net2099) - assertEquals(mCallback.lastAvailableNetwork, net2099) - - // For legacy reasons, lastAvailableNetwork is null as soon as any is lost, not necessarily - // the last available one. Check that behavior. - mCallback.onLost(net2098) - assertNull(mCallback.lastAvailableNetwork) - - // Make sure that losing the really last available one still results in null. - mCallback.onLost(net2099) - assertNull(mCallback.lastAvailableNetwork) - - // Make sure multiple onAvailable in a row then onLost still results in null. - mCallback.onAvailable(net2097) - mCallback.onAvailable(net2098) - mCallback.onAvailable(net2099) - mCallback.onLost(net2097) - assertNull(mCallback.lastAvailableNetwork) - } - - @Test - fun testAssertNoCallback() { - mCallback.assertNoCallback(SHORT_TIMEOUT_MS) - mCallback.onAvailable(Network(100)) - assertFails { mCallback.assertNoCallback(SHORT_TIMEOUT_MS) } - val net = Network(101) - mCallback.assertNoCallback { it is Available } - mCallback.onAvailable(net) - // Expect no blocked status change. Receive other callback does not fail the test. - mCallback.assertNoCallback { it is BlockedStatus } - mCallback.onBlockedStatusChanged(net, true) - assertFails { mCallback.assertNoCallback { it is BlockedStatus } } - mCallback.onBlockedStatusChanged(net, false) - mCallback.onCapabilitiesChanged(net, NetworkCapabilities()) - assertFails { mCallback.assertNoCallback { it is CapabilitiesChanged } } - } - - @Test - fun testCapabilitiesWithAndWithout() { - val net = Network(101) - val matcher = makeHasNetwork(101) - val meteredNc = NetworkCapabilities() - val unmeteredNc = NetworkCapabilities().addCapability(NOT_METERED) - // Check that expecting caps (with or without) fails when no callback has been received. - assertFails { - mCallback.expectCaps(matcher, SHORT_TIMEOUT_MS) { it.hasCapability(NOT_METERED) } - } - assertFails { - mCallback.expectCaps(matcher, SHORT_TIMEOUT_MS) { !it.hasCapability(NOT_METERED) } - } - - // Add NOT_METERED and check that With succeeds and Without fails. - mCallback.onCapabilitiesChanged(net, unmeteredNc) - mCallback.expectCaps(matcher) { it.hasCapability(NOT_METERED) } - mCallback.onCapabilitiesChanged(net, unmeteredNc) - assertFails { - mCallback.expectCaps(matcher, SHORT_TIMEOUT_MS) { !it.hasCapability(NOT_METERED) } - } - - // Don't add NOT_METERED and check that With fails and Without succeeds. - mCallback.onCapabilitiesChanged(net, meteredNc) - assertFails { - mCallback.expectCaps(matcher, SHORT_TIMEOUT_MS) { it.hasCapability(NOT_METERED) } - } - mCallback.onCapabilitiesChanged(net, meteredNc) - mCallback.expectCaps(matcher) { !it.hasCapability(NOT_METERED) } - } - - @Test - fun testExpectWithPredicate() { - val net = Network(193) - val netCaps = NetworkCapabilities().addTransportType(CELLULAR) - // Check that expecting callbackThat anything fails when no callback has been received. - assertFails { mCallback.expect<CallbackEntry>(timeoutMs = SHORT_TIMEOUT_MS) { true } } - - // Basic test for true and false - mCallback.onAvailable(net) - mCallback.expect<Available> { true } - mCallback.onAvailable(net) - assertFails { mCallback.expect<CallbackEntry>(timeoutMs = SHORT_TIMEOUT_MS) { false } } - - // Try a positive and a negative case - mCallback.onBlockedStatusChanged(net, true) - mCallback.expect<CallbackEntry> { cb -> cb is BlockedStatus && cb.blocked } - mCallback.onCapabilitiesChanged(net, netCaps) - assertFails { mCallback.expect<CallbackEntry>(timeoutMs = SHORT_TIMEOUT_MS) { cb -> - cb is CapabilitiesChanged && cb.caps.hasTransport(WIFI) - } } - } - - @Test - fun testExpectCaps() { - val net = Network(101) - val netCaps = NetworkCapabilities().addCapability(NOT_METERED).addTransportType(WIFI) - // Check that expecting capabilitiesThat anything fails when no callback has been received. - assertFails { mCallback.expectCaps(net, SHORT_TIMEOUT_MS) { true } } - - // Basic test for true and false - mCallback.onCapabilitiesChanged(net, netCaps) - mCallback.expectCaps(net) { true } - mCallback.onCapabilitiesChanged(net, netCaps) - assertFails { mCallback.expectCaps(net, SHORT_TIMEOUT_MS) { false } } - - // Try a positive and a negative case - mCallback.onCapabilitiesChanged(net, netCaps) - mCallback.expectCaps(net) { - it.hasCapability(NOT_METERED) && it.hasTransport(WIFI) && !it.hasTransport(CELLULAR) - } - mCallback.onCapabilitiesChanged(net, netCaps) - assertFails { mCallback.expectCaps(net, SHORT_TIMEOUT_MS) { it.hasTransport(CELLULAR) } } - - // Try a matching callback on the wrong network - mCallback.onCapabilitiesChanged(net, netCaps) - assertFails { - mCallback.expectCaps(Network(100), SHORT_TIMEOUT_MS) { true } - } - } - - @Test - fun testLinkPropertiesCallbacks() { - val net = Network(112) - val linkAddress = LinkAddress("fe80::ace:d00d/64") - val mtu = 1984 - val linkProps = LinkProperties().apply { - this.mtu = mtu - interfaceName = TEST_INTERFACE_NAME - addLinkAddress(linkAddress) - } - - // Check that expecting linkPropsThat anything fails when no callback has been received. - assertFails { mCallback.expect<LinkPropertiesChanged>(net, SHORT_TIMEOUT_MS) { true } } - - // Basic test for true and false - mCallback.onLinkPropertiesChanged(net, linkProps) - mCallback.expect<LinkPropertiesChanged>(net) { true } - mCallback.onLinkPropertiesChanged(net, linkProps) - assertFails { mCallback.expect<LinkPropertiesChanged>(net, SHORT_TIMEOUT_MS) { false } } - - // Try a positive and negative case - mCallback.onLinkPropertiesChanged(net, linkProps) - mCallback.expect<LinkPropertiesChanged>(net) { - it.lp.interfaceName == TEST_INTERFACE_NAME && - it.lp.linkAddresses.contains(linkAddress) && - it.lp.mtu == mtu - } - mCallback.onLinkPropertiesChanged(net, linkProps) - assertFails { mCallback.expect<LinkPropertiesChanged>(net, SHORT_TIMEOUT_MS) { - it.lp.interfaceName != TEST_INTERFACE_NAME - } } - - // Try a matching callback on the wrong network - mCallback.onLinkPropertiesChanged(net, linkProps) - assertFails { mCallback.expect<LinkPropertiesChanged>(Network(114), SHORT_TIMEOUT_MS) { - it.lp.interfaceName == TEST_INTERFACE_NAME - } } - } - - @Test - fun testExpect() { - val net = Network(103) - // Test expectCallback fails when nothing was sent. - assertFails { mCallback.expect<BlockedStatus>(net, SHORT_TIMEOUT_MS) } - - // Test onAvailable is seen and can be expected - mCallback.onAvailable(net) - mCallback.expect<Available>(net, SHORT_TIMEOUT_MS) - - // Test onAvailable won't return calls with a different network - mCallback.onAvailable(Network(106)) - assertFails { mCallback.expect<Available>(net, SHORT_TIMEOUT_MS) } - - // Test onAvailable won't return calls with a different callback - mCallback.onAvailable(net) - assertFails { mCallback.expect<BlockedStatus>(net, SHORT_TIMEOUT_MS) } - } - - @Test - fun testAllExpectOverloads() { - // This test should never run, it only checks that all overloads exist and build - assumeTrue(false) - val hn = object : TestableNetworkCallback.HasNetwork { override val network = ANY_NETWORK } - - // Method with all arguments (version that takes a Network) - mCallback.expect(AVAILABLE, ANY_NETWORK, 10, "error") { true } - - // Java overloads omitting one argument. One line for omitting each argument, in positional - // order. Versions that take a Network. - mCallback.expect(AVAILABLE, 10, "error") { true } - mCallback.expect(AVAILABLE, ANY_NETWORK, "error") { true } - mCallback.expect(AVAILABLE, ANY_NETWORK, 10) { true } - mCallback.expect(AVAILABLE, ANY_NETWORK, 10, "error") - - // Java overloads for omitting two arguments. One line for omitting each pair of arguments. - // Versions that take a Network. - mCallback.expect(AVAILABLE, "error") { true } - mCallback.expect(AVAILABLE, 10) { true } - mCallback.expect(AVAILABLE, 10, "error") - mCallback.expect(AVAILABLE, ANY_NETWORK) { true } - mCallback.expect(AVAILABLE, ANY_NETWORK, "error") - mCallback.expect(AVAILABLE, ANY_NETWORK, 10) - - // Java overloads for omitting three arguments. One line for each remaining argument. - // Versions that take a Network. - mCallback.expect(AVAILABLE) { true } - mCallback.expect(AVAILABLE, "error") - mCallback.expect(AVAILABLE, 10) - mCallback.expect(AVAILABLE, ANY_NETWORK) - - // Java overload for omitting all four arguments. - mCallback.expect(AVAILABLE) - - // Same orders as above, but versions that take a HasNetwork. Except overloads that - // were already tested because they omitted the Network argument - mCallback.expect(AVAILABLE, hn, 10, "error") { true } - mCallback.expect(AVAILABLE, hn, "error") { true } - mCallback.expect(AVAILABLE, hn, 10) { true } - mCallback.expect(AVAILABLE, hn, 10, "error") - - mCallback.expect(AVAILABLE, hn) { true } - mCallback.expect(AVAILABLE, hn, "error") - mCallback.expect(AVAILABLE, hn, 10) - - mCallback.expect(AVAILABLE, hn) - - // Same as above but for reified versions. - mCallback.expect<Available>(ANY_NETWORK, 10, "error") { true } - mCallback.expect<Available>(timeoutMs = 10, errorMsg = "error") { true } - mCallback.expect<Available>(network = ANY_NETWORK, errorMsg = "error") { true } - mCallback.expect<Available>(network = ANY_NETWORK, timeoutMs = 10) { true } - mCallback.expect<Available>(network = ANY_NETWORK, timeoutMs = 10, errorMsg = "error") - - mCallback.expect<Available>(errorMsg = "error") { true } - mCallback.expect<Available>(timeoutMs = 10) { true } - mCallback.expect<Available>(timeoutMs = 10, errorMsg = "error") - mCallback.expect<Available>(network = ANY_NETWORK) { true } - mCallback.expect<Available>(network = ANY_NETWORK, errorMsg = "error") - mCallback.expect<Available>(network = ANY_NETWORK, timeoutMs = 10) - - mCallback.expect<Available> { true } - mCallback.expect<Available>(errorMsg = "error") - mCallback.expect<Available>(timeoutMs = 10) - mCallback.expect<Available>(network = ANY_NETWORK) - mCallback.expect<Available>() - - mCallback.expect<Available>(hn, 10, "error") { true } - mCallback.expect<Available>(network = hn, errorMsg = "error") { true } - mCallback.expect<Available>(network = hn, timeoutMs = 10) { true } - mCallback.expect<Available>(network = hn, timeoutMs = 10, errorMsg = "error") - - mCallback.expect<Available>(network = hn) { true } - mCallback.expect<Available>(network = hn, errorMsg = "error") - mCallback.expect<Available>(network = hn, timeoutMs = 10) - - mCallback.expect<Available>(network = hn) - } - - @Test - fun testExpectClass() { - val net = Network(1) - mCallback.onAvailable(net) - assertFails { mCallback.expect(LOST, net) } - } - - @Test - fun testPoll() { - assertNull(mCallback.poll(SHORT_TIMEOUT_MS)) - TNCInterpreter.interpretTestSpec(initial = mCallback, lineShift = 1, - threadTransform = { cb -> cb.createLinkedCopy() }, spec = """ - sleep; onAvailable(133) | poll(2) = Available(133) time 1..4 - | poll(1) = null - onCapabilitiesChanged(108) | poll(1) = CapabilitiesChanged(108) time 0..3 - onBlockedStatus(199) | poll(1) = BlockedStatus(199) time 0..3 - """) - } - - @Test - fun testEventuallyExpect() { - // TODO: Current test does not verify the inline one. Also verify the behavior after - // aligning two eventuallyExpect() - val net1 = Network(100) - val net2 = Network(101) - mCallback.onAvailable(net1) - mCallback.onCapabilitiesChanged(net1, NetworkCapabilities()) - mCallback.onLinkPropertiesChanged(net1, LinkProperties()) - mCallback.eventuallyExpect(LINK_PROPERTIES_CHANGED) { - net1.equals(it.network) - } - // No further new callback. Expect no callback. - assertFails { mCallback.eventuallyExpect(LINK_PROPERTIES_CHANGED, SHORT_TIMEOUT_MS) } - - // Verify no predicate set. - mCallback.onAvailable(net2) - mCallback.onLinkPropertiesChanged(net2, LinkProperties()) - mCallback.onBlockedStatusChanged(net1, false) - mCallback.eventuallyExpect(BLOCKED_STATUS) { net1.equals(it.network) } - // Verify no callback received if the callback does not happen. - assertFails { mCallback.eventuallyExpect(LOSING, SHORT_TIMEOUT_MS) } - } - - @Test - fun testEventuallyExpectOnMultiThreads() { - TNCInterpreter.interpretTestSpec(initial = mCallback, lineShift = 1, - threadTransform = { cb -> cb.createLinkedCopy() }, spec = """ - onAvailable(100) | eventually(CapabilitiesChanged(100), 1) fails - sleep ; onCapabilitiesChanged(100) | eventually(CapabilitiesChanged(100), 3) - onAvailable(101) ; onBlockedStatus(101) | eventually(BlockedStatus(100), 2) fails - onSuspended(100) ; sleep ; onLost(100) | eventually(Lost(100), 3) - """) - } -} - -private object TNCInterpreter : ConcurrentInterpreter<TestableNetworkCallback>(interpretTable) - -val EntryList = CallbackEntry::class.sealedSubclasses.map { it.simpleName }.joinToString("|") -private fun callbackEntryFromString(name: String): KClass<out CallbackEntry> { - return CallbackEntry::class.sealedSubclasses.first { it.simpleName == name } -} - -@SuppressLint("NewApi") // Uses hidden APIs, which the linter would identify as missing APIs. -private val interpretTable = listOf<InterpretMatcher<TestableNetworkCallback>>( - // Interpret "Available(xx)" as "call to onAvailable with netId xx", and likewise for - // all callback types. This is implemented above by enumerating the subclasses of - // CallbackEntry and reading their simpleName. - Regex("""(.*)\s+=\s+($EntryList)\((\d+)\)""") to { i, cb, t -> - val record = i.interpret(t.strArg(1), cb) - assertTrue(callbackEntryFromString(t.strArg(2)).isInstance(record)) - // Strictly speaking testing for is CallbackEntry is useless as it's been tested above - // but the compiler can't figure things out from the isInstance call. It does understand - // from the assertTrue(is CallbackEntry) that this is true, which allows to access - // the 'network' member below. - assertTrue(record is CallbackEntry) - assertEquals(record.network.netId, t.intArg(3)) - }, - // Interpret "onAvailable(xx)" as calling "onAvailable" with a netId of xx, and likewise for - // all callback types. NetworkCapabilities and LinkProperties just get an empty object - // as their argument. Losing gets the default linger timer. Blocked gets false. - Regex("""on($EntryList)\((\d+)\)""") to { i, cb, t -> - val net = Network(t.intArg(2)) - when (t.strArg(1)) { - "Available" -> cb.onAvailable(net) - // PreCheck not used in tests. Add it here if it becomes useful. - "CapabilitiesChanged" -> cb.onCapabilitiesChanged(net, NetworkCapabilities()) - "LinkPropertiesChanged" -> cb.onLinkPropertiesChanged(net, LinkProperties()) - "Suspended" -> cb.onNetworkSuspended(net) - "Resumed" -> cb.onNetworkResumed(net) - "Losing" -> cb.onLosing(net, DEFAULT_LINGER_DELAY_MS) - "Lost" -> cb.onLost(net) - "Unavailable" -> cb.onUnavailable() - "BlockedStatus" -> cb.onBlockedStatusChanged(net, false) - else -> fail("Unknown callback type") - } - }, - Regex("""poll\((\d+)\)""") to { i, cb, t -> cb.poll(t.timeArg(1)) }, - // Interpret "eventually(Available(xx), timeout)" as calling eventuallyExpect that expects - // CallbackEntry.AVAILABLE with netId of xx within timeout*INTERPRET_TIME_UNIT timeout, and - // likewise for all callback types. - Regex("""eventually\(($EntryList)\((\d+)\),\s+(\d+)\)""") to { i, cb, t -> - val net = Network(t.intArg(2)) - val timeout = t.timeArg(3) - when (t.strArg(1)) { - "Available" -> cb.eventuallyExpect(AVAILABLE, timeout) { net == it.network } - "Suspended" -> cb.eventuallyExpect(SUSPENDED, timeout) { net == it.network } - "Resumed" -> cb.eventuallyExpect(RESUMED, timeout) { net == it.network } - "Losing" -> cb.eventuallyExpect(LOSING, timeout) { net == it.network } - "Lost" -> cb.eventuallyExpect(LOST, timeout) { net == it.network } - "Unavailable" -> cb.eventuallyExpect(UNAVAILABLE, timeout) { net == it.network } - "BlockedStatus" -> cb.eventuallyExpect(BLOCKED_STATUS, timeout) { net == it.network } - "CapabilitiesChanged" -> - cb.eventuallyExpect(NETWORK_CAPS_UPDATED, timeout) { net == it.network } - "LinkPropertiesChanged" -> - cb.eventuallyExpect(LINK_PROPERTIES_CHANGED, timeout) { net == it.network } - else -> fail("Unknown callback type") - } - } -) diff --git a/common/tests/unit/src/com/android/testutils/TestableNetworkCallbackTestJava.java b/common/tests/unit/src/com/android/testutils/TestableNetworkCallbackTestJava.java deleted file mode 100644 index 4570d0ae..00000000 --- a/common/tests/unit/src/com/android/testutils/TestableNetworkCallbackTestJava.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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.testutils; - -import static com.android.testutils.RecorderCallback.CallbackEntry.AVAILABLE; -import static com.android.testutils.TestableNetworkCallbackKt.anyNetwork; - -import static org.junit.Assume.assumeTrue; - -import org.junit.Test; - -public class TestableNetworkCallbackTestJava { - @Test - void testAllExpectOverloads() { - // This test should never run, it only checks that all overloads exist and build - assumeTrue(false); - final TestableNetworkCallback callback = new TestableNetworkCallback(); - TestableNetworkCallback.HasNetwork hn = TestableNetworkCallbackKt::anyNetwork; - - // Method with all arguments (version that takes a Network) - callback.expect(AVAILABLE, anyNetwork(), 10, "error", cb -> true); - - // Overloads omitting one argument. One line for omitting each argument, in positional - // order. Versions that take a Network. - callback.expect(AVAILABLE, 10, "error", cb -> true); - callback.expect(AVAILABLE, anyNetwork(), "error", cb -> true); - callback.expect(AVAILABLE, anyNetwork(), 10, cb -> true); - callback.expect(AVAILABLE, anyNetwork(), 10, "error"); - - // Overloads for omitting two arguments. One line for omitting each pair of arguments. - // Versions that take a Network. - callback.expect(AVAILABLE, "error", cb -> true); - callback.expect(AVAILABLE, 10, cb -> true); - callback.expect(AVAILABLE, 10, "error"); - callback.expect(AVAILABLE, anyNetwork(), cb -> true); - callback.expect(AVAILABLE, anyNetwork(), "error"); - callback.expect(AVAILABLE, anyNetwork(), 10); - - // Overloads for omitting three arguments. One line for each remaining argument. - // Versions that take a Network. - callback.expect(AVAILABLE, cb -> true); - callback.expect(AVAILABLE, "error"); - callback.expect(AVAILABLE, 10); - callback.expect(AVAILABLE, anyNetwork()); - - // Java overload for omitting all four arguments. - callback.expect(AVAILABLE); - - // Same orders as above, but versions that take a HasNetwork. Except overloads that - // were already tested because they omitted the Network argument - callback.expect(AVAILABLE, hn, 10, "error", cb -> true); - callback.expect(AVAILABLE, hn, "error", cb -> true); - callback.expect(AVAILABLE, hn, 10, cb -> true); - callback.expect(AVAILABLE, hn, 10, "error"); - - callback.expect(AVAILABLE, hn, cb -> true); - callback.expect(AVAILABLE, hn, "error"); - callback.expect(AVAILABLE, hn, 10); - - callback.expect(AVAILABLE, hn); - } -} |