From 8092ae7d29d7f781647f2b3e81a3b00e75e3b08c Mon Sep 17 00:00:00 2001 From: Chuwei He Date: Tue, 25 Mar 2025 16:52:03 +0900 Subject: [PATCH] Add EthernetPort class This patch adds EthernetPort class which is used to track configuration of ethernet networks internally. Bug: 397536853 Test: atest ConnectivityCoverageTests:android.net.connectivity. com.android.server.ethernet.EthernetPortTest Flag: EXEMPT mainline Change-Id: Iba1c4461ae7d666aa31c076baa33c32c2c1f7603 --- .../android/server/ethernet/EthernetPort.java | 97 ++++++++++++++ .../server/ethernet/EthernetPortTest.java | 121 ++++++++++++++++++ 2 files changed, 218 insertions(+) create mode 100644 service-t/src/com/android/server/ethernet/EthernetPort.java create mode 100644 tests/unit/java/com/android/server/ethernet/EthernetPortTest.java diff --git a/service-t/src/com/android/server/ethernet/EthernetPort.java b/service-t/src/com/android/server/ethernet/EthernetPort.java new file mode 100644 index 0000000000..eb7a0bd885 --- /dev/null +++ b/service-t/src/com/android/server/ethernet/EthernetPort.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.ethernet; + +import android.annotation.Nullable; +import android.net.MacAddress; +import android.text.TextUtils; + +import java.util.Objects; + +/** + * A class representing an ethernet port. This class is used as an internal class to track existing + * ethernet interfaces managed by EthernetTracker. + */ +public class EthernetPort { + private final String mInterfaceName; + + private final MacAddress mMacAddress; + + private final int mInterfaceIndex; + + /** + * Creates an EthernetPort for the given interface name, MAC address and index. + */ + public EthernetPort(String interfaceName, MacAddress macAddress, int index) { + if (TextUtils.isEmpty(interfaceName) || macAddress == null || index <= 0) { + throw new IllegalArgumentException("Ethernet port should have valid interface name, " + + "MAC address and interface index."); + } + + mInterfaceName = interfaceName; + mMacAddress = macAddress; + mInterfaceIndex = index; + } + + /** + * Get the name of the ethernet interface port. + */ + public String getInterfaceName() { + return mInterfaceName; + } + + /** + * Get the MAC address of the ethernet port. + */ + public MacAddress getMacAddress() { + return mMacAddress; + } + + /** + * Get the interface index of the ethernet port. + */ + public int getInterfaceIndex() { + return mInterfaceIndex; + } + + @Override + public String toString() { + return "Interface name: " + mInterfaceName + ", MAC address: " + mMacAddress + + ", Interface index: " + mInterfaceIndex; + } + + @Override + public int hashCode() { + return Objects.hash(mMacAddress, mInterfaceName, mInterfaceIndex); + } + + @Override + public boolean equals(@Nullable Object o) { + if (o == this) { + return true; + } + + if (!(o instanceof EthernetPort)) { + return false; + } + + final EthernetPort other = (EthernetPort) o; + return Objects.equals(this.mInterfaceName, other.mInterfaceName) + && Objects.equals(this.mMacAddress, other.mMacAddress) + && this.mInterfaceIndex == other.mInterfaceIndex; + } +} diff --git a/tests/unit/java/com/android/server/ethernet/EthernetPortTest.java b/tests/unit/java/com/android/server/ethernet/EthernetPortTest.java new file mode 100644 index 0000000000..0aa133405f --- /dev/null +++ b/tests/unit/java/com/android/server/ethernet/EthernetPortTest.java @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.ethernet; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertThrows; + +import android.net.MacAddress; +import android.os.Build; + +import androidx.test.filters.SmallTest; + +import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; +import com.android.testutils.DevSdkIgnoreRunner; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@SmallTest +@RunWith(DevSdkIgnoreRunner.class) +@IgnoreUpTo(Build.VERSION_CODES.S_V2) +public class EthernetPortTest { + private final String mTestInterfaceName = "eth0"; + private final MacAddress mTestMacAddress = MacAddress.fromString("0A:1B:2C:3D:4E:5F"); + private final int mTestInterfaceIndex = 1; + + @Test + public void testMakeEthernetPort() { + EthernetPort port = new EthernetPort( + mTestInterfaceName, mTestMacAddress, mTestInterfaceIndex); + assertEquals(mTestInterfaceName, port.getInterfaceName()); + assertEquals(mTestMacAddress, port.getMacAddress()); + assertEquals(mTestInterfaceIndex, port.getInterfaceIndex()); + } + + @Test + public void testMakeEthernetPortWithEmptyInterfaceName() { + assertThrows("Ethernet port should have valid interface name, MAC address and " + + "interface index.", + IllegalArgumentException.class, + () -> new EthernetPort("", mTestMacAddress, mTestInterfaceIndex)); + } + + @Test + public void testMakeEthernetPortWithNullInterfaceName() { + assertThrows("Ethernet port should have valid interface name, MAC address and " + + "interface index.", + IllegalArgumentException.class, + () -> new EthernetPort(null, mTestMacAddress, mTestInterfaceIndex)); + } + + @Test + public void testMakeEthernetPortWithNullMacAddress() { + assertThrows("Ethernet port should have valid interface name, MAC address and " + + "interface index.", + IllegalArgumentException.class, + () -> new EthernetPort(mTestInterfaceName, null, mTestInterfaceIndex)); + } + + @Test + public void testMakeEthernetPortWithInvalidInterfaceIndex() { + assertThrows("Ethernet port should have valid interface name, MAC address and " + + "interface index.", + IllegalArgumentException.class, + () -> new EthernetPort(mTestInterfaceName, mTestMacAddress, 0)); + } + + @Test + public void testHashCodeConsistency() { + EthernetPort port = new EthernetPort( + mTestInterfaceName, mTestMacAddress, mTestInterfaceIndex); + int hash1 = port.hashCode(); + int hash2 = port.hashCode(); + assertEquals(hash1, hash2); + } + + @Test + public void testHashCodeOfDifferentConfig() { + EthernetPort port1 = new EthernetPort( + mTestInterfaceName, mTestMacAddress, mTestInterfaceIndex); + EthernetPort port2 = new EthernetPort( + "eth1", MacAddress.fromString("DE:AD:BE:EF:00:01"), 2); + int hash1 = port1.hashCode(); + int hash2 = port2.hashCode(); + assertNotEquals(hash1, hash2); + } + + @Test + public void testHashCodeOfTheSameConfig() { + EthernetPort port1 = new EthernetPort( + mTestInterfaceName, mTestMacAddress, mTestInterfaceIndex); + EthernetPort port2 = new EthernetPort( + mTestInterfaceName, mTestMacAddress, mTestInterfaceIndex); + int hash1 = port1.hashCode(); + int hash2 = port2.hashCode(); + assertEquals(hash1, hash2); + } + + @Test + public void testToString() { + EthernetPort port = new EthernetPort( + mTestInterfaceName, mTestMacAddress, mTestInterfaceIndex); + String expect = "Interface name: eth0, MAC address: 0a:1b:2c:3d:4e:5f, Interface index: 1"; + assertEquals(expect, port.toString()); + } +}