summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2019-06-10 05:47:38 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2019-06-10 05:47:38 +0000
commit67be1d71aa5d45763746ebb46881ce29ae4c4b7d (patch)
treef98bcdf4ceb47671a72a4fe9b997fd0c1417825f
parent10c2cc18e43fb3fd15c8dd6dec58c8c8d7730c55 (diff)
parent53ed1acaa6187e6505fb400281078a5153f81342 (diff)
Merge "Add an IpClientIntegrationTest"
-rw-r--r--src/android/net/dhcp/DhcpDiscoverPacket.java2
-rw-r--r--src/android/net/dhcp/DhcpPacket.java28
-rw-r--r--src/com/android/server/NetworkObserverRegistry.java12
-rw-r--r--tests/integration/Android.bp42
-rw-r--r--tests/integration/AndroidManifest.xml34
-rw-r--r--tests/integration/AndroidTest.xml29
-rw-r--r--tests/integration/src/android/net/ip/IpClientIntegrationTest.java312
-rw-r--r--tests/unit/Android.bp15
8 files changed, 448 insertions, 26 deletions
diff --git a/src/android/net/dhcp/DhcpDiscoverPacket.java b/src/android/net/dhcp/DhcpDiscoverPacket.java
index 11f2b61..9707d13 100644
--- a/src/android/net/dhcp/DhcpDiscoverPacket.java
+++ b/src/android/net/dhcp/DhcpDiscoverPacket.java
@@ -22,7 +22,7 @@ import java.nio.ByteBuffer;
/**
* This class implements the DHCP-DISCOVER packet.
*/
-class DhcpDiscoverPacket extends DhcpPacket {
+public class DhcpDiscoverPacket extends DhcpPacket {
/**
* The IP address of the client which sent this packet.
*/
diff --git a/src/android/net/dhcp/DhcpPacket.java b/src/android/net/dhcp/DhcpPacket.java
index a15d423..d5c3efb 100644
--- a/src/android/net/dhcp/DhcpPacket.java
+++ b/src/android/net/dhcp/DhcpPacket.java
@@ -108,22 +108,22 @@ public abstract class DhcpPacket {
/**
* The client DHCP port.
*/
- static final short DHCP_CLIENT = (short) 68;
+ public static final short DHCP_CLIENT = (short) 68;
/**
* The server DHCP port.
*/
- static final short DHCP_SERVER = (short) 67;
+ public static final short DHCP_SERVER = (short) 67;
/**
* The message op code indicating a request from a client.
*/
- protected static final byte DHCP_BOOTREQUEST = (byte) 1;
+ public static final byte DHCP_BOOTREQUEST = (byte) 1;
/**
* The message op code indicating a response from the server.
*/
- protected static final byte DHCP_BOOTREPLY = (byte) 2;
+ public static final byte DHCP_BOOTREPLY = (byte) 2;
/**
* The code type used to identify an Ethernet MAC address in the
@@ -139,7 +139,7 @@ public abstract class DhcpPacket {
/**
* The magic cookie that identifies this as a DHCP packet instead of BOOTP.
*/
- private static final int DHCP_MAGIC_COOKIE = 0x63825363;
+ public static final int DHCP_MAGIC_COOKIE = 0x63825363;
/**
* DHCP Optional Type: DHCP Subnet Mask
@@ -221,16 +221,16 @@ public abstract class DhcpPacket {
/**
* DHCP Optional Type: DHCP Message Type
*/
- protected static final byte DHCP_MESSAGE_TYPE = 53;
+ public static final byte DHCP_MESSAGE_TYPE = 53;
// the actual type values
- protected static final byte DHCP_MESSAGE_TYPE_DISCOVER = 1;
- protected static final byte DHCP_MESSAGE_TYPE_OFFER = 2;
- protected static final byte DHCP_MESSAGE_TYPE_REQUEST = 3;
- protected static final byte DHCP_MESSAGE_TYPE_DECLINE = 4;
- protected static final byte DHCP_MESSAGE_TYPE_ACK = 5;
- protected static final byte DHCP_MESSAGE_TYPE_NAK = 6;
- protected static final byte DHCP_MESSAGE_TYPE_RELEASE = 7;
- protected static final byte DHCP_MESSAGE_TYPE_INFORM = 8;
+ public static final byte DHCP_MESSAGE_TYPE_DISCOVER = 1;
+ public static final byte DHCP_MESSAGE_TYPE_OFFER = 2;
+ public static final byte DHCP_MESSAGE_TYPE_REQUEST = 3;
+ public static final byte DHCP_MESSAGE_TYPE_DECLINE = 4;
+ public static final byte DHCP_MESSAGE_TYPE_ACK = 5;
+ public static final byte DHCP_MESSAGE_TYPE_NAK = 6;
+ public static final byte DHCP_MESSAGE_TYPE_RELEASE = 7;
+ public static final byte DHCP_MESSAGE_TYPE_INFORM = 8;
/**
* DHCP Optional Type: DHCP Server Identifier
diff --git a/src/com/android/server/NetworkObserverRegistry.java b/src/com/android/server/NetworkObserverRegistry.java
index afe166b..b83bc5c 100644
--- a/src/com/android/server/NetworkObserverRegistry.java
+++ b/src/com/android/server/NetworkObserverRegistry.java
@@ -42,19 +42,13 @@ public class NetworkObserverRegistry extends INetdUnsolicitedEventListener.Stub
private static final String TAG = NetworkObserverRegistry.class.getSimpleName();
/**
- * Constructs a new NetworkObserverRegistry.
- *
- * <p>Only one registry should be used per process since netd will silently ignore multiple
- * registrations from the same process.
- */
- NetworkObserverRegistry() {}
-
- /**
* Start listening for Netd events.
*
* <p>This should be called before allowing any observer to be registered.
+ * Note there is no unregister method. The only way to unregister is when the process
+ * terminates.
*/
- void register(@NonNull INetd netd) throws RemoteException {
+ public void register(@NonNull INetd netd) throws RemoteException {
netd.registerUnsolicitedEventListener(this);
}
diff --git a/tests/integration/Android.bp b/tests/integration/Android.bp
new file mode 100644
index 0000000..ec8257f
--- /dev/null
+++ b/tests/integration/Android.bp
@@ -0,0 +1,42 @@
+//
+// 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.
+//
+
+android_test {
+ name: "NetworkStackIntegrationTests",
+ certificate: "networkstack",
+ srcs: ["src/**/*.java"],
+ test_suites: ["device-tests"],
+ static_libs: [
+ "androidx.annotation_annotation",
+ "androidx.test.rules",
+ "mockito-target-extended-minus-junit4",
+ "NetworkStackBase",
+ "testables",
+ ],
+ libs: [
+ "android.test.runner",
+ "android.test.base",
+ "android.test.mock",
+ ],
+ defaults: ["libnetworkstackutilsjni_deps"],
+ jni_libs: [
+ // For mockito extended
+ "libdexmakerjvmtiagent",
+ "libstaticjvmtiagent",
+ // For NetworkStackUtils included in NetworkStackBase
+ "libnetworkstackutilsjni",
+ ],
+}
diff --git a/tests/integration/AndroidManifest.xml b/tests/integration/AndroidManifest.xml
new file mode 100644
index 0000000..bfd3735
--- /dev/null
+++ b/tests/integration/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.server.networkstack.integrationtests"
+ android:sharedUserId="android.uid.networkstack">
+
+ <!-- Note: do not add any privileged or signature permissions that are granted
+ to the network stack app. Otherwise, the test APK will install, but when the device is
+ rebooted, it will bootloop with something like:
+
+ 05-14 00:41:02.723 18330 18330 E AndroidRuntime: java.lang.IllegalStateException: Signature|privileged permissions not in privapp-permissions whitelist: {com.android.server.networkstack.integrationtests: android.permission.CONNECTIVITY_INTERNAL}
+ -->
+
+ <application android:debuggable="true">
+ <uses-library android:name="android.test.runner" />
+ </application>
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.server.networkstack.integrationtests"
+ android:label="Networking stack integration tests">
+ </instrumentation>
+</manifest>
diff --git a/tests/integration/AndroidTest.xml b/tests/integration/AndroidTest.xml
new file mode 100644
index 0000000..c592568
--- /dev/null
+++ b/tests/integration/AndroidTest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Runs Integration Tests for NetworkStack">
+ <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+ <option name="test-file-name" value="NetworkStackIntegrationTests.apk" />
+ </target_preparer>
+
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="framework-base-presubmit" />
+ <option name="test-tag" value="NetworkStackIntegrationTests" />
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="com.android.server.networkstack.integrationtests" />
+ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+ <option name="hidden-api-checks" value="false"/>
+ </test>
+</configuration>
diff --git a/tests/integration/src/android/net/ip/IpClientIntegrationTest.java b/tests/integration/src/android/net/ip/IpClientIntegrationTest.java
new file mode 100644
index 0000000..ae6afdb
--- /dev/null
+++ b/tests/integration/src/android/net/ip/IpClientIntegrationTest.java
@@ -0,0 +1,312 @@
+/*
+ * 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 android.net.ip;
+
+import static android.net.dhcp.DhcpPacket.DHCP_BOOTREQUEST;
+import static android.net.dhcp.DhcpPacket.DHCP_CLIENT;
+import static android.net.dhcp.DhcpPacket.DHCP_MAGIC_COOKIE;
+import static android.net.dhcp.DhcpPacket.DHCP_MESSAGE_TYPE;
+import static android.net.dhcp.DhcpPacket.DHCP_MESSAGE_TYPE_DISCOVER;
+import static android.net.dhcp.DhcpPacket.DHCP_SERVER;
+import static android.net.dhcp.DhcpPacket.ENCAP_L2;
+import static android.net.dhcp.DhcpPacket.ETHER_BROADCAST;
+
+import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_ALL;
+
+import static junit.framework.Assert.fail;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.AlarmManager;
+import android.app.Instrumentation;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.Resources;
+import android.net.ConnectivityManager;
+import android.net.IIpMemoryStore;
+import android.net.INetd;
+import android.net.TestNetworkInterface;
+import android.net.TestNetworkManager;
+import android.net.dhcp.DhcpDiscoverPacket;
+import android.net.dhcp.DhcpPacket;
+import android.net.dhcp.DhcpPacket.ParseException;
+import android.net.shared.ProvisioningConfiguration;
+import android.net.util.InterfaceParams;
+import android.net.util.PacketReader;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+
+import androidx.annotation.Nullable;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.server.NetworkObserverRegistry;
+import com.android.server.NetworkStackService;
+
+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.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests for IpClient.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class IpClientIntegrationTest {
+ @Mock private Context mContext;
+ @Mock private ConnectivityManager mCm;
+ @Mock private INetd mNetd;
+ @Mock private Resources mResources;
+ @Mock private IIpClientCallbacks mCb;
+ @Mock private AlarmManager mAlarm;
+ @Mock private IpClient.Dependencies mDependencies;
+ @Mock private ContentResolver mContentResolver;
+ @Mock private NetworkStackService.NetworkStackServiceManager mNetworkStackServiceManager;
+ @Mock private IIpMemoryStore mIpMemoryStore;
+ @Mock private InterfaceParams mInterfaceParams;
+
+ private String mIfaceName;
+ private HandlerThread mPacketReaderThread;
+ private TapPacketReader mPacketReader;
+ private IpClient mIpc;
+
+ private static final int DATA_BUFFER_LEN = 4096;
+ private static final long PACKET_TIMEOUT_MS = 5_000;
+
+ // Ethernet header
+ private static final int ETH_HEADER_LEN = 14;
+ private static final int ETH_DEST_ADDR_OFFSET = 0;
+ private static final int ETH_MAC_ADDR_LEN = 6;
+
+ // IP header
+ private static final int IPV4_HEADER_LEN = 20;
+ private static final int IPV4_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 16;
+ private static final int IPV4_ADDR_LEN = 4;
+
+ // UDP header
+ private static final int UDP_HEADER_LEN = 8;
+ private static final int UDP_HEADER_OFFSET = ETH_HEADER_LEN + IPV4_HEADER_LEN;
+ private static final int UDP_SRC_PORT_OFFSET = UDP_HEADER_OFFSET + 0;
+
+ // DHCP header
+ private static final int DHCP_HEADER_OFFSET = ETH_HEADER_LEN + IPV4_HEADER_LEN
+ + UDP_HEADER_LEN;
+ private static final int DHCP_MESSAGE_OP_CODE_OFFSET = DHCP_HEADER_OFFSET + 0;
+ private static final int DHCP_TRANSACTION_ID_OFFSET = DHCP_HEADER_OFFSET + 4;
+ private static final int DHCP_OPTION_MAGIC_COOKIE_OFFSET = DHCP_HEADER_OFFSET + 236;
+ private static final int DHCP_OPTION_MESSAGE_TYPE_OFFSET = DHCP_OPTION_MAGIC_COOKIE_OFFSET + 4;
+ private static final int DHCP_OPTION_MESSAGE_TYPE_LEN_OFFSET =
+ DHCP_OPTION_MESSAGE_TYPE_OFFSET + 1;
+ private static final int DHCP_OPTION_MESSAGE_TYPE_VALUE_OFFSET =
+ DHCP_OPTION_MESSAGE_TYPE_OFFSET + 2;
+
+ private static class TapPacketReader extends PacketReader {
+ private final ParcelFileDescriptor mTapFd;
+ private final LinkedBlockingQueue<byte[]> mReceivedPackets =
+ new LinkedBlockingQueue<byte[]>();
+
+ TapPacketReader(Handler h, ParcelFileDescriptor tapFd) {
+ super(h, DATA_BUFFER_LEN);
+ mTapFd = tapFd;
+ }
+
+ @Override
+ protected FileDescriptor createFd() {
+ return mTapFd.getFileDescriptor();
+ }
+
+ @Override
+ protected void handlePacket(byte[] recvbuf, int length) {
+ final byte[] newPacket = Arrays.copyOf(recvbuf, length);
+ try {
+ mReceivedPackets.put(newPacket);
+ } catch (InterruptedException e) {
+ fail("fail to put the new packet in the queue");
+ }
+ }
+
+ /**
+ * Get the next packet that was received on the interface.
+ *
+ */
+ @Nullable
+ public byte[] popPacket(long timeoutMs) {
+ try {
+ return mReceivedPackets.poll(timeoutMs, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ // Fall through
+ }
+ return null;
+ }
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ when(mContext.getSystemService(eq(Context.ALARM_SERVICE))).thenReturn(mAlarm);
+ when(mContext.getSystemService(eq(ConnectivityManager.class))).thenReturn(mCm);
+ when(mContext.getResources()).thenReturn(mResources);
+ when(mDependencies.getNetd(any())).thenReturn(mNetd);
+ when(mContext.getContentResolver()).thenReturn(mContentResolver);
+ when(mDependencies.getInterfaceParams(any())).thenReturn(mInterfaceParams);
+ when(mNetworkStackServiceManager.getIpMemoryStoreService()).thenReturn(mIpMemoryStore);
+
+ setUpTapInterface();
+ setUpIpClient();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (mPacketReader != null) {
+ mPacketReader.stop(); // Also closes the socket
+ }
+ if (mPacketReaderThread != null) {
+ mPacketReaderThread.quitSafely();
+ }
+ }
+
+ private void setUpTapInterface() {
+ final Instrumentation inst = InstrumentationRegistry.getInstrumentation();
+ // Adopt the shell permission identity to create a test TAP interface.
+ inst.getUiAutomation().adoptShellPermissionIdentity();
+
+ final TestNetworkInterface iface;
+ try {
+ final TestNetworkManager tnm = (TestNetworkManager)
+ inst.getContext().getSystemService(Context.TEST_NETWORK_SERVICE);
+ iface = tnm.createTapInterface();
+ } finally {
+ // Drop the identity in order to regain the network stack permissions, which the shell
+ // does not have.
+ inst.getUiAutomation().dropShellPermissionIdentity();
+ }
+ mIfaceName = iface.getInterfaceName();
+
+ mPacketReaderThread = new HandlerThread(IpClientIntegrationTest.class.getSimpleName());
+ mPacketReaderThread.start();
+
+ final ParcelFileDescriptor tapFd = iface.getFileDescriptor();
+ mPacketReader = new TapPacketReader(mPacketReaderThread.getThreadHandler(), tapFd);
+ mPacketReader.start();
+ }
+
+ private void setUpIpClient() throws Exception {
+ final Instrumentation inst = InstrumentationRegistry.getInstrumentation();
+ final IBinder netdIBinder =
+ (IBinder) inst.getContext().getSystemService(Context.NETD_SERVICE);
+ final INetd netd = INetd.Stub.asInterface(netdIBinder);
+ when(mContext.getSystemService(eq(Context.NETD_SERVICE))).thenReturn(netdIBinder);
+ assertNotNull(netd);
+
+ final NetworkObserverRegistry reg = new NetworkObserverRegistry();
+ reg.register(netd);
+ mIpc = new IpClient(mContext, mIfaceName, mCb, reg, mNetworkStackServiceManager);
+ }
+
+ private boolean packetContainsExpectedField(final byte[] packet, final int offset,
+ final byte[] expected) {
+ if (packet.length < offset + expected.length) return false;
+ for (int i = 0; i < expected.length; ++i) {
+ if (packet[offset + i] != expected[i]) return false;
+ }
+ return true;
+ }
+
+ private boolean isDhcpPacket(final byte[] packet) {
+ final ByteBuffer buffer = ByteBuffer.wrap(packet);
+
+ // check the packet length
+ if (packet.length < DHCP_HEADER_OFFSET) return false;
+
+ // check the source port and dest port in UDP header
+ buffer.position(UDP_SRC_PORT_OFFSET);
+ final short udpSrcPort = buffer.getShort();
+ final short udpDstPort = buffer.getShort();
+ if (udpSrcPort != DHCP_CLIENT || udpDstPort != DHCP_SERVER) return false;
+
+ // check DHCP message type
+ buffer.position(DHCP_MESSAGE_OP_CODE_OFFSET);
+ final byte dhcpOpCode = buffer.get();
+ if (dhcpOpCode != DHCP_BOOTREQUEST) return false;
+
+ // check DHCP magic cookie
+ buffer.position(DHCP_OPTION_MAGIC_COOKIE_OFFSET);
+ final int dhcpMagicCookie = buffer.getInt();
+ if (dhcpMagicCookie != DHCP_MAGIC_COOKIE) return false;
+
+ return true;
+ }
+
+ private void verifyDhcpDiscoverPacketReceived(final byte[] packet)
+ throws ParseException {
+ assertTrue(packetContainsExpectedField(packet, ETH_DEST_ADDR_OFFSET, ETHER_BROADCAST));
+ assertTrue(packetContainsExpectedField(packet, IPV4_DEST_ADDR_OFFSET,
+ IPV4_ADDR_ALL.getAddress()));
+
+ // check if received dhcp packet includes DHCP Message Type option and expected
+ // type/length/value.
+ assertTrue(packet[DHCP_OPTION_MESSAGE_TYPE_OFFSET] == DHCP_MESSAGE_TYPE);
+ assertTrue(packet[DHCP_OPTION_MESSAGE_TYPE_OFFSET + 1] == 1);
+ assertTrue(packet[DHCP_OPTION_MESSAGE_TYPE_OFFSET + 2] == DHCP_MESSAGE_TYPE_DISCOVER);
+ final DhcpPacket dhcpPacket = DhcpPacket.decodeFullPacket(
+ packet, packet.length, ENCAP_L2);
+ assertTrue(dhcpPacket instanceof DhcpDiscoverPacket);
+ }
+
+ @Test
+ public void testDhcpInit() throws Exception {
+ ProvisioningConfiguration config = new ProvisioningConfiguration.Builder()
+ .withoutIpReachabilityMonitor()
+ .build();
+
+ mIpc.startProvisioning(config);
+ verify(mCb, times(1)).setNeighborDiscoveryOffload(true);
+
+ byte[] packet;
+ while ((packet = mPacketReader.popPacket(PACKET_TIMEOUT_MS)) != null) {
+ try {
+ if (!isDhcpPacket(packet)) continue;
+ verifyDhcpDiscoverPacketReceived(packet);
+ mIpc.shutdown();
+ return;
+ } catch (DhcpPacket.ParseException e) {
+ fail("parse exception: " + e);
+ }
+ }
+
+ fail("No DHCPDISCOVER received on interface");
+ }
+}
diff --git a/tests/unit/Android.bp b/tests/unit/Android.bp
index 48b13b0..5d90a61 100644
--- a/tests/unit/Android.bp
+++ b/tests/unit/Android.bp
@@ -32,11 +32,22 @@ android_test {
"android.test.base",
"android.test.mock",
],
+ defaults: ["libnetworkstackutilsjni_deps"],
jni_libs: [
// For mockito extended
"libdexmakerjvmtiagent",
"libstaticjvmtiagent",
- // For ApfTest
+ "libnetworkstackutilsjni",
+ ],
+}
+
+// Additional dependencies of libnetworkstackutilsjni that are not provided by the system when
+// running as a test application.
+// Using java_defaults as jni_libs does not support filegroups.
+java_defaults {
+ name: "libnetworkstackutilsjni_deps",
+ jni_libs: [
+ "libartbase",
"libbacktrace",
"libbase",
"libbinder",
@@ -57,7 +68,6 @@ android_test {
"libnativehelper",
"libnativehelper_compat_libc++",
"libnetworkstacktestsjni",
- "libnetworkstackutilsjni",
"libpackagelistparser",
"libpcre2",
"libprocessgroup",
@@ -75,6 +85,7 @@ android_test {
],
}
+// JNI code for ApfTest
cc_library_shared {
name: "libnetworkstacktestsjni",
srcs: [