Deal with responses on MdnsServiceCache
To cache services and respond quickly, the MdnsServiceTypeClient should add all services to the MdnsServiceCache and remove any services from there as well. Bug: 265787401 Test: atest FrameworksNetTests Change-Id: If0a9e6b563a0992ac25b8cde7f3beb00700f1c11
This commit is contained in:
@@ -131,6 +131,7 @@ public class MdnsServiceTypeClientTests {
|
||||
private SocketKey socketKey;
|
||||
private HandlerThread thread;
|
||||
private Handler handler;
|
||||
private MdnsServiceCache serviceCache;
|
||||
private long latestDelayMs = 0;
|
||||
private Message delayMessage = null;
|
||||
private Handler realHandler = null;
|
||||
@@ -190,6 +191,7 @@ public class MdnsServiceTypeClientTests {
|
||||
thread = new HandlerThread("MdnsServiceTypeClientTests");
|
||||
thread.start();
|
||||
handler = new Handler(thread.getLooper());
|
||||
serviceCache = new MdnsServiceCache(thread.getLooper());
|
||||
|
||||
doAnswer(inv -> {
|
||||
latestDelayMs = 0;
|
||||
@@ -213,7 +215,8 @@ public class MdnsServiceTypeClientTests {
|
||||
|
||||
client =
|
||||
new MdnsServiceTypeClient(SERVICE_TYPE, mockSocketClient, currentThreadExecutor,
|
||||
mockDecoderClock, socketKey, mockSharedLog, thread.getLooper(), mockDeps) {
|
||||
mockDecoderClock, socketKey, mockSharedLog, thread.getLooper(), mockDeps,
|
||||
serviceCache) {
|
||||
@Override
|
||||
MdnsPacketWriter createMdnsPacketWriter() {
|
||||
return mockPacketWriter;
|
||||
@@ -908,7 +911,8 @@ public class MdnsServiceTypeClientTests {
|
||||
final String serviceInstanceName = "service-instance-1";
|
||||
client =
|
||||
new MdnsServiceTypeClient(SERVICE_TYPE, mockSocketClient, currentThreadExecutor,
|
||||
mockDecoderClock, socketKey, mockSharedLog, thread.getLooper(), mockDeps) {
|
||||
mockDecoderClock, socketKey, mockSharedLog, thread.getLooper(), mockDeps,
|
||||
serviceCache) {
|
||||
@Override
|
||||
MdnsPacketWriter createMdnsPacketWriter() {
|
||||
return mockPacketWriter;
|
||||
@@ -953,7 +957,8 @@ public class MdnsServiceTypeClientTests {
|
||||
final String serviceInstanceName = "service-instance-1";
|
||||
client =
|
||||
new MdnsServiceTypeClient(SERVICE_TYPE, mockSocketClient, currentThreadExecutor,
|
||||
mockDecoderClock, socketKey, mockSharedLog, thread.getLooper(), mockDeps) {
|
||||
mockDecoderClock, socketKey, mockSharedLog, thread.getLooper(), mockDeps,
|
||||
serviceCache) {
|
||||
@Override
|
||||
MdnsPacketWriter createMdnsPacketWriter() {
|
||||
return mockPacketWriter;
|
||||
@@ -986,7 +991,8 @@ public class MdnsServiceTypeClientTests {
|
||||
final String serviceInstanceName = "service-instance-1";
|
||||
client =
|
||||
new MdnsServiceTypeClient(SERVICE_TYPE, mockSocketClient, currentThreadExecutor,
|
||||
mockDecoderClock, socketKey, mockSharedLog, thread.getLooper(), mockDeps) {
|
||||
mockDecoderClock, socketKey, mockSharedLog, thread.getLooper(), mockDeps,
|
||||
serviceCache) {
|
||||
@Override
|
||||
MdnsPacketWriter createMdnsPacketWriter() {
|
||||
return mockPacketWriter;
|
||||
@@ -1106,7 +1112,8 @@ public class MdnsServiceTypeClientTests {
|
||||
@Test
|
||||
public void testProcessResponse_Resolve() throws Exception {
|
||||
client = new MdnsServiceTypeClient(SERVICE_TYPE, mockSocketClient, currentThreadExecutor,
|
||||
mockDecoderClock, socketKey, mockSharedLog, thread.getLooper(), mockDeps);
|
||||
mockDecoderClock, socketKey, mockSharedLog, thread.getLooper(), mockDeps,
|
||||
serviceCache);
|
||||
|
||||
final String instanceName = "service-instance";
|
||||
final String[] hostname = new String[] { "testhost "};
|
||||
@@ -1199,7 +1206,8 @@ public class MdnsServiceTypeClientTests {
|
||||
@Test
|
||||
public void testRenewTxtSrvInResolve() throws Exception {
|
||||
client = new MdnsServiceTypeClient(SERVICE_TYPE, mockSocketClient, currentThreadExecutor,
|
||||
mockDecoderClock, socketKey, mockSharedLog, thread.getLooper(), mockDeps);
|
||||
mockDecoderClock, socketKey, mockSharedLog, thread.getLooper(), mockDeps,
|
||||
serviceCache);
|
||||
|
||||
final String instanceName = "service-instance";
|
||||
final String[] hostname = new String[] { "testhost "};
|
||||
@@ -1312,7 +1320,8 @@ public class MdnsServiceTypeClientTests {
|
||||
@Test
|
||||
public void testProcessResponse_ResolveExcludesOtherServices() {
|
||||
client = new MdnsServiceTypeClient(SERVICE_TYPE, mockSocketClient, currentThreadExecutor,
|
||||
mockDecoderClock, socketKey, mockSharedLog, thread.getLooper(), mockDeps);
|
||||
mockDecoderClock, socketKey, mockSharedLog, thread.getLooper(), mockDeps,
|
||||
serviceCache);
|
||||
|
||||
final String requestedInstance = "instance1";
|
||||
final String otherInstance = "instance2";
|
||||
@@ -1376,7 +1385,8 @@ public class MdnsServiceTypeClientTests {
|
||||
@Test
|
||||
public void testProcessResponse_SubtypeDiscoveryLimitedToSubtype() {
|
||||
client = new MdnsServiceTypeClient(SERVICE_TYPE, mockSocketClient, currentThreadExecutor,
|
||||
mockDecoderClock, socketKey, mockSharedLog, thread.getLooper(), mockDeps);
|
||||
mockDecoderClock, socketKey, mockSharedLog, thread.getLooper(), mockDeps,
|
||||
serviceCache);
|
||||
|
||||
final String matchingInstance = "instance1";
|
||||
final String subtype = "_subtype";
|
||||
@@ -1457,7 +1467,8 @@ public class MdnsServiceTypeClientTests {
|
||||
@Test
|
||||
public void testNotifySocketDestroyed() throws Exception {
|
||||
client = new MdnsServiceTypeClient(SERVICE_TYPE, mockSocketClient, currentThreadExecutor,
|
||||
mockDecoderClock, socketKey, mockSharedLog, thread.getLooper(), mockDeps);
|
||||
mockDecoderClock, socketKey, mockSharedLog, thread.getLooper(), mockDeps,
|
||||
serviceCache);
|
||||
|
||||
final String requestedInstance = "instance1";
|
||||
final String otherInstance = "instance2";
|
||||
@@ -1512,16 +1523,109 @@ public class MdnsServiceTypeClientTests {
|
||||
verify(mockListenerOne, never()).onServiceNameRemoved(matchServiceName(otherInstance));
|
||||
|
||||
// mockListenerTwo gets notified for both though
|
||||
final InOrder inOrder2 = inOrder(mockListenerTwo);
|
||||
inOrder2.verify(mockListenerTwo).onServiceNameDiscovered(
|
||||
verify(mockListenerTwo).onServiceNameDiscovered(
|
||||
matchServiceName(requestedInstance));
|
||||
inOrder2.verify(mockListenerTwo).onServiceFound(matchServiceName(requestedInstance));
|
||||
inOrder2.verify(mockListenerTwo).onServiceNameDiscovered(matchServiceName(otherInstance));
|
||||
inOrder2.verify(mockListenerTwo).onServiceFound(matchServiceName(otherInstance));
|
||||
inOrder2.verify(mockListenerTwo).onServiceRemoved(matchServiceName(otherInstance));
|
||||
inOrder2.verify(mockListenerTwo).onServiceNameRemoved(matchServiceName(otherInstance));
|
||||
inOrder2.verify(mockListenerTwo).onServiceRemoved(matchServiceName(requestedInstance));
|
||||
inOrder2.verify(mockListenerTwo).onServiceNameRemoved(matchServiceName(requestedInstance));
|
||||
verify(mockListenerTwo).onServiceFound(matchServiceName(requestedInstance));
|
||||
verify(mockListenerTwo).onServiceNameDiscovered(matchServiceName(otherInstance));
|
||||
verify(mockListenerTwo).onServiceFound(matchServiceName(otherInstance));
|
||||
verify(mockListenerTwo).onServiceRemoved(matchServiceName(otherInstance));
|
||||
verify(mockListenerTwo).onServiceNameRemoved(matchServiceName(otherInstance));
|
||||
verify(mockListenerTwo).onServiceRemoved(matchServiceName(requestedInstance));
|
||||
verify(mockListenerTwo).onServiceNameRemoved(matchServiceName(requestedInstance));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServicesAreCached() throws Exception {
|
||||
final String serviceName = "service-instance";
|
||||
final String ipV4Address = "192.0.2.0";
|
||||
// Register a listener
|
||||
startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
|
||||
verify(mockDeps, times(1)).removeMessages(any(), eq(EVENT_START_QUERYTASK));
|
||||
InOrder inOrder = inOrder(mockListenerOne);
|
||||
|
||||
// Process a response which has ip address to make response become complete.
|
||||
final String subtype = "ABCDE";
|
||||
processResponse(createResponse(
|
||||
serviceName, ipV4Address, 5353, subtype,
|
||||
Collections.emptyMap(), TEST_TTL),
|
||||
socketKey);
|
||||
|
||||
// Verify that onServiceNameDiscovered is called.
|
||||
inOrder.verify(mockListenerOne).onServiceNameDiscovered(serviceInfoCaptor.capture());
|
||||
verifyServiceInfo(serviceInfoCaptor.getAllValues().get(0),
|
||||
serviceName,
|
||||
SERVICE_TYPE_LABELS,
|
||||
List.of(ipV4Address) /* ipv4Address */,
|
||||
List.of() /* ipv6Address */,
|
||||
5353 /* port */,
|
||||
Collections.singletonList(subtype) /* subTypes */,
|
||||
Collections.singletonMap("key", null) /* attributes */,
|
||||
socketKey);
|
||||
|
||||
// Verify that onServiceFound is called.
|
||||
inOrder.verify(mockListenerOne).onServiceFound(serviceInfoCaptor.capture());
|
||||
verifyServiceInfo(serviceInfoCaptor.getAllValues().get(1),
|
||||
serviceName,
|
||||
SERVICE_TYPE_LABELS,
|
||||
List.of(ipV4Address) /* ipv4Address */,
|
||||
List.of() /* ipv6Address */,
|
||||
5353 /* port */,
|
||||
Collections.singletonList(subtype) /* subTypes */,
|
||||
Collections.singletonMap("key", null) /* attributes */,
|
||||
socketKey);
|
||||
|
||||
// Unregister the listener
|
||||
stopSendAndReceive(mockListenerOne);
|
||||
verify(mockDeps, times(2)).removeMessages(any(), eq(EVENT_START_QUERYTASK));
|
||||
|
||||
// Register another listener.
|
||||
startSendAndReceive(mockListenerTwo, MdnsSearchOptions.getDefaultOptions());
|
||||
verify(mockDeps, times(3)).removeMessages(any(), eq(EVENT_START_QUERYTASK));
|
||||
InOrder inOrder2 = inOrder(mockListenerTwo);
|
||||
|
||||
// The services are cached in MdnsServiceCache, verify that onServiceNameDiscovered is
|
||||
// called immediately.
|
||||
inOrder2.verify(mockListenerTwo).onServiceNameDiscovered(serviceInfoCaptor.capture());
|
||||
verifyServiceInfo(serviceInfoCaptor.getAllValues().get(2),
|
||||
serviceName,
|
||||
SERVICE_TYPE_LABELS,
|
||||
List.of(ipV4Address) /* ipv4Address */,
|
||||
List.of() /* ipv6Address */,
|
||||
5353 /* port */,
|
||||
Collections.singletonList(subtype) /* subTypes */,
|
||||
Collections.singletonMap("key", null) /* attributes */,
|
||||
socketKey);
|
||||
|
||||
// The services are cached in MdnsServiceCache, verify that onServiceFound is
|
||||
// called immediately.
|
||||
inOrder2.verify(mockListenerTwo).onServiceFound(serviceInfoCaptor.capture());
|
||||
verifyServiceInfo(serviceInfoCaptor.getAllValues().get(3),
|
||||
serviceName,
|
||||
SERVICE_TYPE_LABELS,
|
||||
List.of(ipV4Address) /* ipv4Address */,
|
||||
List.of() /* ipv6Address */,
|
||||
5353 /* port */,
|
||||
Collections.singletonList(subtype) /* subTypes */,
|
||||
Collections.singletonMap("key", null) /* attributes */,
|
||||
socketKey);
|
||||
|
||||
// Process a response with a different ip address, port and updated text attributes.
|
||||
final String ipV6Address = "2001:db8::";
|
||||
processResponse(createResponse(
|
||||
serviceName, ipV6Address, 5354, subtype,
|
||||
Collections.singletonMap("key", "value"), TEST_TTL), socketKey);
|
||||
|
||||
// Verify the onServiceUpdated is called.
|
||||
inOrder2.verify(mockListenerTwo).onServiceUpdated(serviceInfoCaptor.capture());
|
||||
verifyServiceInfo(serviceInfoCaptor.getAllValues().get(4),
|
||||
serviceName,
|
||||
SERVICE_TYPE_LABELS,
|
||||
List.of(ipV4Address) /* ipv4Address */,
|
||||
List.of(ipV6Address) /* ipv6Address */,
|
||||
5354 /* port */,
|
||||
Collections.singletonList(subtype) /* subTypes */,
|
||||
Collections.singletonMap("key", "value") /* attributes */,
|
||||
socketKey);
|
||||
}
|
||||
|
||||
private static MdnsServiceInfo matchServiceName(String name) {
|
||||
|
||||
Reference in New Issue
Block a user