Merge "Add MdnsMultinetworkSocketClient"
This commit is contained in:
@@ -46,7 +46,7 @@ public class MdnsDiscoveryManagerTests {
|
||||
private static final String SERVICE_TYPE_2 = "_test._tcp.local";
|
||||
|
||||
@Mock private ExecutorProvider executorProvider;
|
||||
@Mock private MdnsSocketClient socketClient;
|
||||
@Mock private MdnsSocketClientBase socketClient;
|
||||
@Mock private MdnsServiceTypeClient mockServiceTypeClientOne;
|
||||
@Mock private MdnsServiceTypeClient mockServiceTypeClientTwo;
|
||||
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.connectivity.mdns;
|
||||
|
||||
import static com.android.server.connectivity.mdns.MdnsSocketProvider.SocketCallback;
|
||||
import static com.android.server.connectivity.mdns.MulticastPacketReader.PacketHandler;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.timeout;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.net.InetAddresses;
|
||||
import android.net.Network;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
|
||||
import com.android.net.module.util.HexDump;
|
||||
import com.android.testutils.DevSdkIgnoreRule;
|
||||
import com.android.testutils.DevSdkIgnoreRunner;
|
||||
import com.android.testutils.HandlerUtils;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(DevSdkIgnoreRunner.class)
|
||||
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S_V2)
|
||||
public class MdnsMultinetworkSocketClientTest {
|
||||
private static final byte[] BUFFER = new byte[10];
|
||||
private static final long DEFAULT_TIMEOUT = 2000L;
|
||||
@Mock private Network mNetwork;
|
||||
@Mock private MdnsSocketProvider mProvider;
|
||||
@Mock private MdnsInterfaceSocket mSocket;
|
||||
@Mock private MdnsServiceBrowserListener mListener;
|
||||
@Mock private MdnsSocketClientBase.Callback mCallback;
|
||||
private MdnsMultinetworkSocketClient mSocketClient;
|
||||
private Handler mHandler;
|
||||
|
||||
@Before
|
||||
public void setUp() throws SocketException {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
final HandlerThread thread = new HandlerThread("MdnsMultinetworkSocketClientTest");
|
||||
thread.start();
|
||||
mHandler = new Handler(thread.getLooper());
|
||||
mSocketClient = new MdnsMultinetworkSocketClient(thread.getLooper(), mProvider);
|
||||
mHandler.post(() -> mSocketClient.setCallback(mCallback));
|
||||
}
|
||||
|
||||
private SocketCallback expectSocketCallback() {
|
||||
final ArgumentCaptor<SocketCallback> callbackCaptor =
|
||||
ArgumentCaptor.forClass(SocketCallback.class);
|
||||
mHandler.post(() -> mSocketClient.notifyNetworkRequested(mListener, mNetwork));
|
||||
verify(mProvider, timeout(DEFAULT_TIMEOUT))
|
||||
.requestSocket(eq(mNetwork), callbackCaptor.capture());
|
||||
return callbackCaptor.getValue();
|
||||
}
|
||||
|
||||
private NetworkInterface createEmptyNetworkInterface() {
|
||||
try {
|
||||
Constructor<NetworkInterface> constructor =
|
||||
NetworkInterface.class.getDeclaredConstructor();
|
||||
constructor.setAccessible(true);
|
||||
return constructor.newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendPacket() throws IOException {
|
||||
final SocketCallback callback = expectSocketCallback();
|
||||
final DatagramPacket ipv4Packet = new DatagramPacket(BUFFER, 0 /* offset */, BUFFER.length,
|
||||
InetAddresses.parseNumericAddress("192.0.2.1"), 0 /* port */);
|
||||
final DatagramPacket ipv6Packet = new DatagramPacket(BUFFER, 0 /* offset */, BUFFER.length,
|
||||
InetAddresses.parseNumericAddress("2001:db8::"), 0 /* port */);
|
||||
doReturn(true).when(mSocket).hasJoinedIpv4();
|
||||
doReturn(true).when(mSocket).hasJoinedIpv6();
|
||||
doReturn(createEmptyNetworkInterface()).when(mSocket).getInterface();
|
||||
// Notify socket created
|
||||
callback.onSocketCreated(mNetwork, mSocket, List.of());
|
||||
|
||||
// Send packet to IPv4 with target network and verify sending has been called.
|
||||
mSocketClient.sendMulticastPacket(ipv4Packet, mNetwork);
|
||||
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
|
||||
verify(mSocket).send(ipv4Packet);
|
||||
|
||||
// Send packet to IPv6 without target network and verify sending has been called.
|
||||
mSocketClient.sendMulticastPacket(ipv6Packet);
|
||||
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
|
||||
verify(mSocket).send(ipv6Packet);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReceivePacket() {
|
||||
final SocketCallback callback = expectSocketCallback();
|
||||
final byte[] data = HexDump.hexStringToByteArray(
|
||||
// scapy.raw(scapy.dns_compress(
|
||||
// scapy.DNS(rd=0, qr=1, aa=1, qd = None,
|
||||
// an =
|
||||
// scapy.DNSRR(type='PTR', rrname='_testtype._tcp.local',
|
||||
// rdata='testservice._testtype._tcp.local', rclass='IN', ttl=4500) /
|
||||
// scapy.DNSRRSRV(rrname='testservice._testtype._tcp.local', rclass=0x8001,
|
||||
// port=31234, target='Android.local', ttl=120))
|
||||
// )).hex().upper()
|
||||
"000084000000000200000000095F7465737474797065045F746370056C6F63616C00000C0001000011"
|
||||
+ "94000E0B7465737473657276696365C00CC02C00218001000000780010000000007A0207"
|
||||
+ "416E64726F6964C01B");
|
||||
|
||||
doReturn(createEmptyNetworkInterface()).when(mSocket).getInterface();
|
||||
// Notify socket created
|
||||
callback.onSocketCreated(mNetwork, mSocket, List.of());
|
||||
|
||||
final ArgumentCaptor<PacketHandler> handlerCaptor =
|
||||
ArgumentCaptor.forClass(PacketHandler.class);
|
||||
verify(mSocket).addPacketHandler(handlerCaptor.capture());
|
||||
|
||||
// Send the data and verify the received records.
|
||||
final PacketHandler handler = handlerCaptor.getValue();
|
||||
handler.handlePacket(data, data.length, null /* src */);
|
||||
final ArgumentCaptor<MdnsResponse> responseCaptor =
|
||||
ArgumentCaptor.forClass(MdnsResponse.class);
|
||||
verify(mCallback).onResponseReceived(responseCaptor.capture());
|
||||
final MdnsResponse response = responseCaptor.getValue();
|
||||
assertTrue(response.hasPointerRecords());
|
||||
assertArrayEquals("_testtype._tcp.local".split("\\."),
|
||||
response.getPointerRecords().get(0).getName());
|
||||
assertTrue(response.hasServiceRecord());
|
||||
assertEquals("testservice", response.getServiceRecord().getServiceInstanceName());
|
||||
assertEquals("Android.local".split("\\."),
|
||||
response.getServiceRecord().getServiceHost());
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@@ -80,7 +80,10 @@ public class MdnsServiceTypeClientTests {
|
||||
private static final int INTERFACE_INDEX = 999;
|
||||
private static final String SERVICE_TYPE = "_googlecast._tcp.local";
|
||||
private static final String[] SERVICE_TYPE_LABELS = TextUtils.split(SERVICE_TYPE, "\\.");
|
||||
private static final Network NETWORK = mock(Network.class);
|
||||
private static final InetSocketAddress IPV4_ADDRESS = new InetSocketAddress(
|
||||
MdnsConstants.getMdnsIPv4Address(), MdnsConstants.MDNS_PORT);
|
||||
private static final InetSocketAddress IPV6_ADDRESS = new InetSocketAddress(
|
||||
MdnsConstants.getMdnsIPv6Address(), MdnsConstants.MDNS_PORT);
|
||||
|
||||
@Mock
|
||||
private MdnsServiceBrowserListener mockListenerOne;
|
||||
@@ -89,13 +92,16 @@ public class MdnsServiceTypeClientTests {
|
||||
@Mock
|
||||
private MdnsPacketWriter mockPacketWriter;
|
||||
@Mock
|
||||
private MdnsSocketClient mockSocketClient;
|
||||
private MdnsMultinetworkSocketClient mockSocketClient;
|
||||
@Mock
|
||||
private Network mockNetwork;
|
||||
@Captor
|
||||
private ArgumentCaptor<MdnsServiceInfo> serviceInfoCaptor;
|
||||
|
||||
private final byte[] buf = new byte[10];
|
||||
|
||||
private DatagramPacket[] expectedPackets;
|
||||
private DatagramPacket[] expectedIPv4Packets;
|
||||
private DatagramPacket[] expectedIPv6Packets;
|
||||
private ScheduledFuture<?>[] expectedSendFutures;
|
||||
private FakeExecutor currentThreadExecutor = new FakeExecutor();
|
||||
|
||||
@@ -106,30 +112,52 @@ public class MdnsServiceTypeClientTests {
|
||||
public void setUp() throws IOException {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
expectedPackets = new DatagramPacket[16];
|
||||
expectedIPv4Packets = new DatagramPacket[16];
|
||||
expectedIPv6Packets = new DatagramPacket[16];
|
||||
expectedSendFutures = new ScheduledFuture<?>[16];
|
||||
|
||||
for (int i = 0; i < expectedSendFutures.length; ++i) {
|
||||
expectedPackets[i] = new DatagramPacket(buf, 0, 5);
|
||||
expectedIPv4Packets[i] = new DatagramPacket(buf, 0 /* offset */, 5 /* length */,
|
||||
MdnsConstants.getMdnsIPv4Address(), MdnsConstants.MDNS_PORT);
|
||||
expectedIPv6Packets[i] = new DatagramPacket(buf, 0 /* offset */, 5 /* length */,
|
||||
MdnsConstants.getMdnsIPv6Address(), MdnsConstants.MDNS_PORT);
|
||||
expectedSendFutures[i] = Mockito.mock(ScheduledFuture.class);
|
||||
}
|
||||
when(mockPacketWriter.getPacket(any(SocketAddress.class)))
|
||||
.thenReturn(expectedPackets[0])
|
||||
.thenReturn(expectedPackets[1])
|
||||
.thenReturn(expectedPackets[2])
|
||||
.thenReturn(expectedPackets[3])
|
||||
.thenReturn(expectedPackets[4])
|
||||
.thenReturn(expectedPackets[5])
|
||||
.thenReturn(expectedPackets[6])
|
||||
.thenReturn(expectedPackets[7])
|
||||
.thenReturn(expectedPackets[8])
|
||||
.thenReturn(expectedPackets[9])
|
||||
.thenReturn(expectedPackets[10])
|
||||
.thenReturn(expectedPackets[11])
|
||||
.thenReturn(expectedPackets[12])
|
||||
.thenReturn(expectedPackets[13])
|
||||
.thenReturn(expectedPackets[14])
|
||||
.thenReturn(expectedPackets[15]);
|
||||
when(mockPacketWriter.getPacket(IPV4_ADDRESS))
|
||||
.thenReturn(expectedIPv4Packets[0])
|
||||
.thenReturn(expectedIPv4Packets[1])
|
||||
.thenReturn(expectedIPv4Packets[2])
|
||||
.thenReturn(expectedIPv4Packets[3])
|
||||
.thenReturn(expectedIPv4Packets[4])
|
||||
.thenReturn(expectedIPv4Packets[5])
|
||||
.thenReturn(expectedIPv4Packets[6])
|
||||
.thenReturn(expectedIPv4Packets[7])
|
||||
.thenReturn(expectedIPv4Packets[8])
|
||||
.thenReturn(expectedIPv4Packets[9])
|
||||
.thenReturn(expectedIPv4Packets[10])
|
||||
.thenReturn(expectedIPv4Packets[11])
|
||||
.thenReturn(expectedIPv4Packets[12])
|
||||
.thenReturn(expectedIPv4Packets[13])
|
||||
.thenReturn(expectedIPv4Packets[14])
|
||||
.thenReturn(expectedIPv4Packets[15]);
|
||||
|
||||
when(mockPacketWriter.getPacket(IPV6_ADDRESS))
|
||||
.thenReturn(expectedIPv6Packets[0])
|
||||
.thenReturn(expectedIPv6Packets[1])
|
||||
.thenReturn(expectedIPv6Packets[2])
|
||||
.thenReturn(expectedIPv6Packets[3])
|
||||
.thenReturn(expectedIPv6Packets[4])
|
||||
.thenReturn(expectedIPv6Packets[5])
|
||||
.thenReturn(expectedIPv6Packets[6])
|
||||
.thenReturn(expectedIPv6Packets[7])
|
||||
.thenReturn(expectedIPv6Packets[8])
|
||||
.thenReturn(expectedIPv6Packets[9])
|
||||
.thenReturn(expectedIPv6Packets[10])
|
||||
.thenReturn(expectedIPv6Packets[11])
|
||||
.thenReturn(expectedIPv6Packets[12])
|
||||
.thenReturn(expectedIPv6Packets[13])
|
||||
.thenReturn(expectedIPv6Packets[14])
|
||||
.thenReturn(expectedIPv6Packets[15]);
|
||||
|
||||
client =
|
||||
new MdnsServiceTypeClient(SERVICE_TYPE, mockSocketClient, currentThreadExecutor) {
|
||||
@@ -282,8 +310,8 @@ public class MdnsServiceTypeClientTests {
|
||||
//MdnsConfigsFlagsImpl.alwaysAskForUnicastResponseInEachBurst.override(true);
|
||||
MdnsSearchOptions searchOptions =
|
||||
MdnsSearchOptions.newBuilder().addSubtype("12345").setIsPassiveMode(false).build();
|
||||
QueryTaskConfig config =
|
||||
new QueryTaskConfig(searchOptions.getSubtypes(), searchOptions.isPassiveMode(), 1);
|
||||
QueryTaskConfig config = new QueryTaskConfig(
|
||||
searchOptions.getSubtypes(), searchOptions.isPassiveMode(), 1, mockNetwork);
|
||||
|
||||
// This is the first query. We will ask for unicast response.
|
||||
assertTrue(config.expectUnicastResponse);
|
||||
@@ -311,8 +339,8 @@ public class MdnsServiceTypeClientTests {
|
||||
public void testQueryTaskConfig_askForUnicastInFirstQuery() {
|
||||
MdnsSearchOptions searchOptions =
|
||||
MdnsSearchOptions.newBuilder().addSubtype("12345").setIsPassiveMode(false).build();
|
||||
QueryTaskConfig config =
|
||||
new QueryTaskConfig(searchOptions.getSubtypes(), searchOptions.isPassiveMode(), 1);
|
||||
QueryTaskConfig config = new QueryTaskConfig(
|
||||
searchOptions.getSubtypes(), searchOptions.isPassiveMode(), 1, mockNetwork);
|
||||
|
||||
// This is the first query. We will ask for unicast response.
|
||||
assertTrue(config.expectUnicastResponse);
|
||||
@@ -409,7 +437,7 @@ public class MdnsServiceTypeClientTests {
|
||||
MdnsResponse response = mock(MdnsResponse.class);
|
||||
when(response.getServiceInstanceName()).thenReturn("service-instance-1");
|
||||
doReturn(INTERFACE_INDEX).when(response).getInterfaceIndex();
|
||||
doReturn(NETWORK).when(response).getNetwork();
|
||||
doReturn(mockNetwork).when(response).getNetwork();
|
||||
when(response.isComplete()).thenReturn(false);
|
||||
|
||||
client.processResponse(response);
|
||||
@@ -423,7 +451,7 @@ public class MdnsServiceTypeClientTests {
|
||||
List.of() /* subTypes */,
|
||||
Collections.singletonMap("key", null) /* attributes */,
|
||||
INTERFACE_INDEX,
|
||||
NETWORK);
|
||||
mockNetwork);
|
||||
|
||||
verify(mockListenerOne, never()).onServiceFound(any(MdnsServiceInfo.class));
|
||||
verify(mockListenerOne, never()).onServiceUpdated(any(MdnsServiceInfo.class));
|
||||
@@ -443,7 +471,7 @@ public class MdnsServiceTypeClientTests {
|
||||
/* subtype= */ "ABCDE",
|
||||
Collections.emptyMap(),
|
||||
/* interfaceIndex= */ 20,
|
||||
NETWORK);
|
||||
mockNetwork);
|
||||
client.processResponse(initialResponse);
|
||||
|
||||
// Process a second response with a different port and updated text attributes.
|
||||
@@ -455,7 +483,7 @@ public class MdnsServiceTypeClientTests {
|
||||
/* subtype= */ "ABCDE",
|
||||
Collections.singletonMap("key", "value"),
|
||||
/* interfaceIndex= */ 20,
|
||||
NETWORK);
|
||||
mockNetwork);
|
||||
client.processResponse(secondResponse);
|
||||
|
||||
// Verify onServiceNameDiscovered was called once for the initial response.
|
||||
@@ -469,7 +497,7 @@ public class MdnsServiceTypeClientTests {
|
||||
Collections.singletonList("ABCDE") /* subTypes */,
|
||||
Collections.singletonMap("key", null) /* attributes */,
|
||||
20 /* interfaceIndex */,
|
||||
NETWORK);
|
||||
mockNetwork);
|
||||
|
||||
// Verify onServiceFound was called once for the initial response.
|
||||
verify(mockListenerOne).onServiceFound(serviceInfoCaptor.capture());
|
||||
@@ -480,7 +508,7 @@ public class MdnsServiceTypeClientTests {
|
||||
assertEquals(initialServiceInfo.getSubtypes(), Collections.singletonList("ABCDE"));
|
||||
assertNull(initialServiceInfo.getAttributeByKey("key"));
|
||||
assertEquals(initialServiceInfo.getInterfaceIndex(), 20);
|
||||
assertEquals(NETWORK, initialServiceInfo.getNetwork());
|
||||
assertEquals(mockNetwork, initialServiceInfo.getNetwork());
|
||||
|
||||
// Verify onServiceUpdated was called once for the second response.
|
||||
verify(mockListenerOne).onServiceUpdated(serviceInfoCaptor.capture());
|
||||
@@ -492,7 +520,7 @@ public class MdnsServiceTypeClientTests {
|
||||
assertEquals(updatedServiceInfo.getSubtypes(), Collections.singletonList("ABCDE"));
|
||||
assertEquals(updatedServiceInfo.getAttributeByKey("key"), "value");
|
||||
assertEquals(updatedServiceInfo.getInterfaceIndex(), 20);
|
||||
assertEquals(NETWORK, updatedServiceInfo.getNetwork());
|
||||
assertEquals(mockNetwork, updatedServiceInfo.getNetwork());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -509,7 +537,7 @@ public class MdnsServiceTypeClientTests {
|
||||
/* subtype= */ "ABCDE",
|
||||
Collections.emptyMap(),
|
||||
/* interfaceIndex= */ 20,
|
||||
NETWORK);
|
||||
mockNetwork);
|
||||
client.processResponse(initialResponse);
|
||||
|
||||
// Process a second response with a different port and updated text attributes.
|
||||
@@ -521,7 +549,7 @@ public class MdnsServiceTypeClientTests {
|
||||
/* subtype= */ "ABCDE",
|
||||
Collections.singletonMap("key", "value"),
|
||||
/* interfaceIndex= */ 20,
|
||||
NETWORK);
|
||||
mockNetwork);
|
||||
client.processResponse(secondResponse);
|
||||
|
||||
System.out.println("secondResponses ip"
|
||||
@@ -538,7 +566,7 @@ public class MdnsServiceTypeClientTests {
|
||||
Collections.singletonList("ABCDE") /* subTypes */,
|
||||
Collections.singletonMap("key", null) /* attributes */,
|
||||
20 /* interfaceIndex */,
|
||||
NETWORK);
|
||||
mockNetwork);
|
||||
|
||||
// Verify onServiceFound was called once for the initial response.
|
||||
verify(mockListenerOne).onServiceFound(serviceInfoCaptor.capture());
|
||||
@@ -549,7 +577,7 @@ public class MdnsServiceTypeClientTests {
|
||||
assertEquals(initialServiceInfo.getSubtypes(), Collections.singletonList("ABCDE"));
|
||||
assertNull(initialServiceInfo.getAttributeByKey("key"));
|
||||
assertEquals(initialServiceInfo.getInterfaceIndex(), 20);
|
||||
assertEquals(NETWORK, initialServiceInfo.getNetwork());
|
||||
assertEquals(mockNetwork, initialServiceInfo.getNetwork());
|
||||
|
||||
// Verify onServiceUpdated was called once for the second response.
|
||||
verify(mockListenerOne).onServiceUpdated(serviceInfoCaptor.capture());
|
||||
@@ -561,7 +589,7 @@ public class MdnsServiceTypeClientTests {
|
||||
assertEquals(updatedServiceInfo.getSubtypes(), Collections.singletonList("ABCDE"));
|
||||
assertEquals(updatedServiceInfo.getAttributeByKey("key"), "value");
|
||||
assertEquals(updatedServiceInfo.getInterfaceIndex(), 20);
|
||||
assertEquals(NETWORK, updatedServiceInfo.getNetwork());
|
||||
assertEquals(mockNetwork, updatedServiceInfo.getNetwork());
|
||||
}
|
||||
|
||||
private void verifyServiceRemovedNoCallback(MdnsServiceBrowserListener listener) {
|
||||
@@ -599,12 +627,12 @@ public class MdnsServiceTypeClientTests {
|
||||
/* subtype= */ "ABCDE",
|
||||
Collections.emptyMap(),
|
||||
INTERFACE_INDEX,
|
||||
NETWORK);
|
||||
mockNetwork);
|
||||
client.processResponse(initialResponse);
|
||||
MdnsResponse response = mock(MdnsResponse.class);
|
||||
doReturn("goodbye-service").when(response).getServiceInstanceName();
|
||||
doReturn(INTERFACE_INDEX).when(response).getInterfaceIndex();
|
||||
doReturn(NETWORK).when(response).getNetwork();
|
||||
doReturn(mockNetwork).when(response).getNetwork();
|
||||
doReturn(true).when(response).isGoodbye();
|
||||
client.processResponse(response);
|
||||
// Verify removed callback won't be called if the service is not existed.
|
||||
@@ -615,9 +643,9 @@ public class MdnsServiceTypeClientTests {
|
||||
doReturn(serviceName).when(response).getServiceInstanceName();
|
||||
client.processResponse(response);
|
||||
verifyServiceRemovedCallback(
|
||||
mockListenerOne, serviceName, SERVICE_TYPE_LABELS, INTERFACE_INDEX, NETWORK);
|
||||
mockListenerOne, serviceName, SERVICE_TYPE_LABELS, INTERFACE_INDEX, mockNetwork);
|
||||
verifyServiceRemovedCallback(
|
||||
mockListenerTwo, serviceName, SERVICE_TYPE_LABELS, INTERFACE_INDEX, NETWORK);
|
||||
mockListenerTwo, serviceName, SERVICE_TYPE_LABELS, INTERFACE_INDEX, mockNetwork);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -631,7 +659,7 @@ public class MdnsServiceTypeClientTests {
|
||||
/* subtype= */ "ABCDE",
|
||||
Collections.emptyMap(),
|
||||
INTERFACE_INDEX,
|
||||
NETWORK);
|
||||
mockNetwork);
|
||||
client.processResponse(initialResponse);
|
||||
|
||||
client.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
|
||||
@@ -647,7 +675,7 @@ public class MdnsServiceTypeClientTests {
|
||||
Collections.singletonList("ABCDE") /* subTypes */,
|
||||
Collections.singletonMap("key", null) /* attributes */,
|
||||
INTERFACE_INDEX,
|
||||
NETWORK);
|
||||
mockNetwork);
|
||||
|
||||
// Verify onServiceFound was called once for the existing response.
|
||||
verify(mockListenerOne).onServiceFound(serviceInfoCaptor.capture());
|
||||
@@ -684,7 +712,7 @@ public class MdnsServiceTypeClientTests {
|
||||
MdnsResponse initialResponse =
|
||||
createMockResponse(
|
||||
serviceInstanceName, "192.168.1.1", 5353, List.of("ABCDE"),
|
||||
Map.of(), INTERFACE_INDEX, NETWORK);
|
||||
Map.of(), INTERFACE_INDEX, mockNetwork);
|
||||
client.processResponse(initialResponse);
|
||||
|
||||
// Clear the scheduled runnable.
|
||||
@@ -718,7 +746,7 @@ public class MdnsServiceTypeClientTests {
|
||||
MdnsResponse initialResponse =
|
||||
createMockResponse(
|
||||
serviceInstanceName, "192.168.1.1", 5353, List.of("ABCDE"),
|
||||
Map.of(), INTERFACE_INDEX, NETWORK);
|
||||
Map.of(), INTERFACE_INDEX, mockNetwork);
|
||||
client.processResponse(initialResponse);
|
||||
|
||||
// Clear the scheduled runnable.
|
||||
@@ -737,7 +765,7 @@ public class MdnsServiceTypeClientTests {
|
||||
|
||||
// Verify removed callback was called.
|
||||
verifyServiceRemovedCallback(mockListenerOne, serviceInstanceName, SERVICE_TYPE_LABELS,
|
||||
INTERFACE_INDEX, NETWORK);
|
||||
INTERFACE_INDEX, mockNetwork);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -758,7 +786,7 @@ public class MdnsServiceTypeClientTests {
|
||||
MdnsResponse initialResponse =
|
||||
createMockResponse(
|
||||
serviceInstanceName, "192.168.1.1", 5353, List.of("ABCDE"),
|
||||
Map.of(), INTERFACE_INDEX, NETWORK);
|
||||
Map.of(), INTERFACE_INDEX, mockNetwork);
|
||||
client.processResponse(initialResponse);
|
||||
|
||||
// Clear the scheduled runnable.
|
||||
@@ -792,7 +820,7 @@ public class MdnsServiceTypeClientTests {
|
||||
MdnsResponse initialResponse =
|
||||
createMockResponse(
|
||||
serviceInstanceName, "192.168.1.1", 5353, List.of("ABCDE"),
|
||||
Map.of(), INTERFACE_INDEX, NETWORK);
|
||||
Map.of(), INTERFACE_INDEX, mockNetwork);
|
||||
client.processResponse(initialResponse);
|
||||
|
||||
// Clear the scheduled runnable.
|
||||
@@ -804,7 +832,7 @@ public class MdnsServiceTypeClientTests {
|
||||
|
||||
// Verify removed callback was called.
|
||||
verifyServiceRemovedCallback(mockListenerOne, serviceInstanceName, SERVICE_TYPE_LABELS,
|
||||
INTERFACE_INDEX, NETWORK);
|
||||
INTERFACE_INDEX, mockNetwork);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -824,7 +852,7 @@ public class MdnsServiceTypeClientTests {
|
||||
"ABCDE" /* subtype */,
|
||||
Collections.emptyMap(),
|
||||
INTERFACE_INDEX,
|
||||
NETWORK);
|
||||
mockNetwork);
|
||||
client.processResponse(initialResponse);
|
||||
|
||||
// Process a second response which has ip address to make response become complete.
|
||||
@@ -836,7 +864,7 @@ public class MdnsServiceTypeClientTests {
|
||||
"ABCDE" /* subtype */,
|
||||
Collections.emptyMap(),
|
||||
INTERFACE_INDEX,
|
||||
NETWORK);
|
||||
mockNetwork);
|
||||
client.processResponse(secondResponse);
|
||||
|
||||
// Process a third response with a different ip address, port and updated text attributes.
|
||||
@@ -848,7 +876,7 @@ public class MdnsServiceTypeClientTests {
|
||||
"ABCDE" /* subtype */,
|
||||
Collections.singletonMap("key", "value"),
|
||||
INTERFACE_INDEX,
|
||||
NETWORK);
|
||||
mockNetwork);
|
||||
client.processResponse(thirdResponse);
|
||||
|
||||
// Process the last response which is goodbye message.
|
||||
@@ -868,7 +896,7 @@ public class MdnsServiceTypeClientTests {
|
||||
Collections.singletonList("ABCDE") /* subTypes */,
|
||||
Collections.singletonMap("key", null) /* attributes */,
|
||||
INTERFACE_INDEX,
|
||||
NETWORK);
|
||||
mockNetwork);
|
||||
|
||||
// Verify onServiceFound was second called for the second response.
|
||||
inOrder.verify(mockListenerOne).onServiceFound(serviceInfoCaptor.capture());
|
||||
@@ -881,7 +909,7 @@ public class MdnsServiceTypeClientTests {
|
||||
Collections.singletonList("ABCDE") /* subTypes */,
|
||||
Collections.singletonMap("key", null) /* attributes */,
|
||||
INTERFACE_INDEX,
|
||||
NETWORK);
|
||||
mockNetwork);
|
||||
|
||||
// Verify onServiceUpdated was third called for the third response.
|
||||
inOrder.verify(mockListenerOne).onServiceUpdated(serviceInfoCaptor.capture());
|
||||
@@ -894,7 +922,7 @@ public class MdnsServiceTypeClientTests {
|
||||
Collections.singletonList("ABCDE") /* subTypes */,
|
||||
Collections.singletonMap("key", "value") /* attributes */,
|
||||
INTERFACE_INDEX,
|
||||
NETWORK);
|
||||
mockNetwork);
|
||||
|
||||
// Verify onServiceRemoved was called for the last response.
|
||||
inOrder.verify(mockListenerOne).onServiceRemoved(serviceInfoCaptor.capture());
|
||||
@@ -907,7 +935,7 @@ public class MdnsServiceTypeClientTests {
|
||||
Collections.singletonList("ABCDE") /* subTypes */,
|
||||
Collections.singletonMap("key", "value") /* attributes */,
|
||||
INTERFACE_INDEX,
|
||||
NETWORK);
|
||||
mockNetwork);
|
||||
|
||||
// Verify onServiceNameRemoved was called for the last response.
|
||||
inOrder.verify(mockListenerOne).onServiceNameRemoved(serviceInfoCaptor.capture());
|
||||
@@ -920,18 +948,34 @@ public class MdnsServiceTypeClientTests {
|
||||
Collections.singletonList("ABCDE") /* subTypes */,
|
||||
Collections.singletonMap("key", "value") /* attributes */,
|
||||
INTERFACE_INDEX,
|
||||
NETWORK);
|
||||
mockNetwork);
|
||||
}
|
||||
|
||||
// verifies that the right query was enqueued with the right delay, and send query by executing
|
||||
// the runnable.
|
||||
private void verifyAndSendQuery(int index, long timeInMs, boolean expectsUnicastResponse) {
|
||||
verifyAndSendQuery(
|
||||
index, timeInMs, expectsUnicastResponse, true /* multipleSocketDiscovery */);
|
||||
}
|
||||
|
||||
private void verifyAndSendQuery(int index, long timeInMs, boolean expectsUnicastResponse,
|
||||
boolean multipleSocketDiscovery) {
|
||||
assertEquals(currentThreadExecutor.getAndClearLastScheduledDelayInMs(), timeInMs);
|
||||
currentThreadExecutor.getAndClearLastScheduledRunnable().run();
|
||||
if (expectsUnicastResponse) {
|
||||
verify(mockSocketClient).sendUnicastPacket(expectedPackets[index]);
|
||||
verify(mockSocketClient).sendUnicastPacket(
|
||||
expectedIPv4Packets[index], null /* network */);
|
||||
if (multipleSocketDiscovery) {
|
||||
verify(mockSocketClient).sendUnicastPacket(
|
||||
expectedIPv6Packets[index], null /* network */);
|
||||
}
|
||||
} else {
|
||||
verify(mockSocketClient).sendMulticastPacket(expectedPackets[index]);
|
||||
verify(mockSocketClient).sendMulticastPacket(
|
||||
expectedIPv4Packets[index], null /* network */);
|
||||
if (multipleSocketDiscovery) {
|
||||
verify(mockSocketClient).sendMulticastPacket(
|
||||
expectedIPv6Packets[index], null /* network */);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ public class MdnsSocketProviderTest {
|
||||
.getNetworkInterfaceByName(LOCAL_ONLY_IFACE_NAME);
|
||||
doReturn(mTetheredIfaceWrapper).when(mDeps).getNetworkInterfaceByName(TETHERED_IFACE_NAME);
|
||||
doReturn(mock(MdnsInterfaceSocket.class))
|
||||
.when(mDeps).createMdnsInterfaceSocket(any(), anyInt());
|
||||
.when(mDeps).createMdnsInterfaceSocket(any(), anyInt(), any(), any());
|
||||
final HandlerThread thread = new HandlerThread("MdnsSocketProviderTest");
|
||||
thread.start();
|
||||
mHandler = new Handler(thread.getLooper());
|
||||
@@ -165,7 +165,7 @@ public class MdnsSocketProviderTest {
|
||||
}
|
||||
|
||||
public void expectedSocketCreatedForNetwork(Network network, List<LinkAddress> addresses) {
|
||||
final SocketEvent event = mHistory.poll(DEFAULT_TIMEOUT, c -> true);
|
||||
final SocketEvent event = mHistory.poll(0L /* timeoutMs */, c -> true);
|
||||
assertNotNull(event);
|
||||
assertTrue(event instanceof SocketCreatedEvent);
|
||||
assertEquals(network, event.mNetwork);
|
||||
@@ -173,7 +173,7 @@ public class MdnsSocketProviderTest {
|
||||
}
|
||||
|
||||
public void expectedInterfaceDestroyedForNetwork(Network network) {
|
||||
final SocketEvent event = mHistory.poll(DEFAULT_TIMEOUT, c -> true);
|
||||
final SocketEvent event = mHistory.poll(0L /* timeoutMs */, c -> true);
|
||||
assertNotNull(event);
|
||||
assertTrue(event instanceof InterfaceDestroyedEvent);
|
||||
assertEquals(network, event.mNetwork);
|
||||
@@ -181,7 +181,7 @@ public class MdnsSocketProviderTest {
|
||||
|
||||
public void expectedAddressesChangedForNetwork(Network network,
|
||||
List<LinkAddress> addresses) {
|
||||
final SocketEvent event = mHistory.poll(DEFAULT_TIMEOUT, c -> true);
|
||||
final SocketEvent event = mHistory.poll(0L /* timeoutMs */, c -> true);
|
||||
assertNotNull(event);
|
||||
assertTrue(event instanceof AddressesChangedEvent);
|
||||
assertEquals(network, event.mNetwork);
|
||||
@@ -260,7 +260,8 @@ public class MdnsSocketProviderTest {
|
||||
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
|
||||
testCallback1.expectedNoCallback();
|
||||
testCallback2.expectedNoCallback();
|
||||
testCallback3.expectedNoCallback();
|
||||
// Expect the socket destroy for tethered interface.
|
||||
testCallback3.expectedInterfaceDestroyedForNetwork(LOCAL_NETWORK);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user