Update NSD tests without AsyncChannel
Update the tests to use the newer NsdManager based on Binder interfaces instead of AsyncChannel. Bug: 190249673 Test: atest NsdManagerTest NsdServiceTest Change-Id: I0991b598331e335a0bc211f010da7f034fb2441b
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user