summaryrefslogtreecommitdiff
path: root/tests/unit/java/com/android/server/NsdServiceTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'tests/unit/java/com/android/server/NsdServiceTest.java')
-rw-r--r--tests/unit/java/com/android/server/NsdServiceTest.java102
1 files changed, 78 insertions, 24 deletions
diff --git a/tests/unit/java/com/android/server/NsdServiceTest.java b/tests/unit/java/com/android/server/NsdServiceTest.java
index 4d2970af95..4172553af7 100644
--- a/tests/unit/java/com/android/server/NsdServiceTest.java
+++ b/tests/unit/java/com/android/server/NsdServiceTest.java
@@ -20,6 +20,7 @@ import static libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChange
import static libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -33,14 +34,19 @@ import static org.mockito.Mockito.when;
import android.compat.testing.PlatformCompatChangeRule;
import android.content.ContentResolver;
import android.content.Context;
+import android.net.nsd.INsdManagerCallback;
+import android.net.nsd.INsdServiceConnector;
import android.net.nsd.NsdManager;
import android.net.nsd.NsdServiceInfo;
+import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
+import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import androidx.annotation.NonNull;
import androidx.test.filters.SmallTest;
import com.android.server.NsdService.DaemonConnection;
@@ -56,11 +62,15 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
+import org.mockito.AdditionalAnswers;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import java.util.LinkedList;
+import java.util.Queue;
+
// TODOs:
// - test client can send requests and receive replies
// - test NSD_ON ENABLE/DISABLED listening
@@ -73,6 +83,11 @@ public class NsdServiceTest {
private static final long CLEANUP_DELAY_MS = 500;
private static final long TIMEOUT_MS = 500;
+ // Records INsdManagerCallback created when NsdService#connect is called.
+ // Only accessed on the test thread, since NsdService#connect is called by the NsdManager
+ // constructor called on the test thread.
+ private final Queue<INsdManagerCallback> mCreatedCallbacks = new LinkedList<>();
+
@Rule
public TestRule compatChangeRule = new PlatformCompatChangeRule();
@Mock Context mContext;
@@ -83,6 +98,16 @@ public class NsdServiceTest {
HandlerThread mThread;
TestHandler mHandler;
+ private static class LinkToDeathRecorder extends Binder {
+ IBinder.DeathRecipient mDr;
+
+ @Override
+ public void linkToDeath(@NonNull DeathRecipient recipient, int flags) {
+ super.linkToDeath(recipient, flags);
+ mDr = recipient;
+ }
+ }
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -103,26 +128,30 @@ public class NsdServiceTest {
@Test
@DisableCompatChanges(NsdManager.RUN_NATIVE_NSD_ONLY_IF_LEGACY_APPS)
- public void testPreSClients() {
+ public void testPreSClients() throws Exception {
when(mSettings.isEnabled()).thenReturn(true);
NsdService service = makeService();
// Pre S client connected, the daemon should be started.
- NsdManager client1 = connectClient(service);
+ connectClient(service);
waitForIdle();
+ final INsdManagerCallback cb1 = getCallback();
+ final IBinder.DeathRecipient deathRecipient1 = verifyLinkToDeath(cb1);
verify(mDaemon, times(1)).maybeStart();
verifyDaemonCommands("start-service");
- NsdManager client2 = connectClient(service);
+ connectClient(service);
waitForIdle();
+ final INsdManagerCallback cb2 = getCallback();
+ final IBinder.DeathRecipient deathRecipient2 = verifyLinkToDeath(cb2);
verify(mDaemon, times(1)).maybeStart();
- client1.disconnect();
+ deathRecipient1.binderDied();
// Still 1 client remains, daemon shouldn't be stopped.
waitForIdle();
verify(mDaemon, never()).maybeStop();
- client2.disconnect();
+ deathRecipient2.binderDied();
// All clients are disconnected, the daemon should be stopped.
verifyDelayMaybeStopDaemon(CLEANUP_DELAY_MS);
verifyDaemonCommands("stop-service");
@@ -130,43 +159,51 @@ public class NsdServiceTest {
@Test
@EnableCompatChanges(NsdManager.RUN_NATIVE_NSD_ONLY_IF_LEGACY_APPS)
- public void testNoDaemonStartedWhenClientsConnect() {
+ public void testNoDaemonStartedWhenClientsConnect() throws Exception {
when(mSettings.isEnabled()).thenReturn(true);
-
- NsdService service = makeService();
+ final NsdService service = makeService();
// Creating an NsdManager will not cause any cmds executed, which means
// no daemon is started.
- NsdManager client1 = connectClient(service);
+ connectClient(service);
waitForIdle();
verify(mDaemon, never()).execute(any());
+ final INsdManagerCallback cb1 = getCallback();
+ final IBinder.DeathRecipient deathRecipient1 = verifyLinkToDeath(cb1);
// Creating another NsdManager will not cause any cmds executed.
- NsdManager client2 = connectClient(service);
+ connectClient(service);
waitForIdle();
verify(mDaemon, never()).execute(any());
+ final INsdManagerCallback cb2 = getCallback();
+ final IBinder.DeathRecipient deathRecipient2 = verifyLinkToDeath(cb2);
// If there is no active request, try to clean up the daemon
// every time the client disconnects.
- client1.disconnect();
+ deathRecipient1.binderDied();
verifyDelayMaybeStopDaemon(CLEANUP_DELAY_MS);
reset(mDaemon);
- client2.disconnect();
+ deathRecipient2.binderDied();
verifyDelayMaybeStopDaemon(CLEANUP_DELAY_MS);
+ }
- client1.disconnect();
- client2.disconnect();
+ private IBinder.DeathRecipient verifyLinkToDeath(INsdManagerCallback cb)
+ throws Exception {
+ final IBinder.DeathRecipient dr = ((LinkToDeathRecorder) cb.asBinder()).mDr;
+ assertNotNull(dr);
+ return dr;
}
@Test
@EnableCompatChanges(NsdManager.RUN_NATIVE_NSD_ONLY_IF_LEGACY_APPS)
- public void testClientRequestsAreGCedAtDisconnection() {
+ public void testClientRequestsAreGCedAtDisconnection() throws Exception {
when(mSettings.isEnabled()).thenReturn(true);
-
NsdService service = makeService();
- NsdManager client = connectClient(service);
+ NsdManager client = connectClient(service);
waitForIdle();
+ final INsdManagerCallback cb1 = getCallback();
+ final IBinder.DeathRecipient deathRecipient = verifyLinkToDeath(cb1);
verify(mDaemon, never()).maybeStart();
verify(mDaemon, never()).execute(any());
@@ -195,18 +232,16 @@ public class NsdServiceTest {
verifyDaemonCommand("resolve 4 a_name a_type local.");
// Client disconnects, stop the daemon after CLEANUP_DELAY_MS.
- client.disconnect();
+ deathRecipient.binderDied();
verifyDelayMaybeStopDaemon(CLEANUP_DELAY_MS);
// checks that request are cleaned
verifyDaemonCommands("stop-register 2", "stop-discover 3",
"stop-resolve 4", "stop-service");
-
- client.disconnect();
}
@Test
@EnableCompatChanges(NsdManager.RUN_NATIVE_NSD_ONLY_IF_LEGACY_APPS)
- public void testCleanupDelayNoRequestActive() {
+ public void testCleanupDelayNoRequestActive() throws Exception {
when(mSettings.isEnabled()).thenReturn(true);
NsdService service = makeService();
@@ -218,6 +253,8 @@ public class NsdServiceTest {
client.registerService(request, PROTOCOL, listener1);
waitForIdle();
verify(mDaemon, times(1)).maybeStart();
+ final INsdManagerCallback cb1 = getCallback();
+ final IBinder.DeathRecipient deathRecipient = verifyLinkToDeath(cb1);
verifyDaemonCommands("start-service", "register 2 a_name a_type 2201");
client.unregisterService(listener1);
@@ -226,7 +263,7 @@ public class NsdServiceTest {
verifyDelayMaybeStopDaemon(CLEANUP_DELAY_MS);
verifyDaemonCommand("stop-service");
reset(mDaemon);
- client.disconnect();
+ deathRecipient.binderDied();
// Client disconnects, after CLEANUP_DELAY_MS, maybeStop the daemon.
verifyDelayMaybeStopDaemon(CLEANUP_DELAY_MS);
}
@@ -240,12 +277,29 @@ public class NsdServiceTest {
mDaemonCallback = callback;
return mDaemon;
};
- NsdService service = new NsdService(mContext, mSettings,
- mHandler, supplier, CLEANUP_DELAY_MS);
+ final NsdService service = new NsdService(mContext, mSettings,
+ mHandler, supplier, CLEANUP_DELAY_MS) {
+ @Override
+ public INsdServiceConnector connect(INsdManagerCallback baseCb) {
+ // Wrap the callback in a transparent mock, to mock asBinder returning a
+ // LinkToDeathRecorder. This will allow recording the binder death recipient
+ // registered on the callback. Use a transparent mock and not a spy as the actual
+ // implementation class is not public and cannot be spied on by Mockito.
+ final INsdManagerCallback cb = mock(INsdManagerCallback.class,
+ AdditionalAnswers.delegatesTo(baseCb));
+ doReturn(new LinkToDeathRecorder()).when(cb).asBinder();
+ mCreatedCallbacks.add(cb);
+ return super.connect(cb);
+ }
+ };
verify(mDaemon, never()).execute(any(String.class));
return service;
}
+ private INsdManagerCallback getCallback() {
+ return mCreatedCallbacks.remove();
+ }
+
NsdManager connectClient(NsdService service) {
return new NsdManager(mContext, service);
}