Remove the ServiceTypeClient after socket destroyed
The ServiceTypeClient should be removed after socket destroyed because it's no longer used by any request. The requests will be matched to the newly created ServiceTypeClient. Bug: 278635632 Test: atest FrameworksNetTests CtsNetTestCases (cherry picked from https://android-review.googlesource.com/q/commit:f2a51ac5f8cc6b1cfaaa0f8fd5c28af522806ca0) Merged-In: Ia917b14d3666f3bfe8e874606a34800a4ce65c5a Change-Id: Ia917b14d3666f3bfe8e874606a34800a4ce65c5a
This commit is contained in:
committed by
Cherrypicker Worker
parent
20e768a2f3
commit
45c1eaadb4
@@ -20,6 +20,7 @@ import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
|
||||
|
||||
import static org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -193,6 +194,60 @@ public class MdnsDiscoveryManagerTests {
|
||||
verify(mockServiceTypeClientTwo2).processResponse(responseForSubtype, ifIndex, NETWORK_2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSocketCreatedAndDestroyed() throws IOException {
|
||||
// Create a ServiceTypeClient for SERVICE_TYPE_1 and NETWORK_1
|
||||
final MdnsSearchOptions options1 =
|
||||
MdnsSearchOptions.newBuilder().setNetwork(NETWORK_1).build();
|
||||
final SocketCreationCallback callback = expectSocketCreationCallback(
|
||||
SERVICE_TYPE_1, mockListenerOne, options1);
|
||||
callback.onSocketCreated(NETWORK_1);
|
||||
verify(mockServiceTypeClientOne1).startSendAndReceive(mockListenerOne, options1);
|
||||
|
||||
// Create a ServiceTypeClient for SERVICE_TYPE_2 and NETWORK_2
|
||||
final MdnsSearchOptions options2 =
|
||||
MdnsSearchOptions.newBuilder().setNetwork(NETWORK_2).build();
|
||||
final SocketCreationCallback callback2 = expectSocketCreationCallback(
|
||||
SERVICE_TYPE_2, mockListenerTwo, options2);
|
||||
callback2.onSocketCreated(NETWORK_2);
|
||||
verify(mockServiceTypeClientTwo2).startSendAndReceive(mockListenerTwo, options2);
|
||||
|
||||
// Receive a response, it should be processed on both clients.
|
||||
final MdnsPacket response = createMdnsPacket(SERVICE_TYPE_1);
|
||||
final int ifIndex = 1;
|
||||
discoveryManager.onResponseReceived(response, ifIndex, null /* network */);
|
||||
verify(mockServiceTypeClientOne1).processResponse(response, ifIndex, null /* network */);
|
||||
verify(mockServiceTypeClientTwo2).processResponse(response, ifIndex, null /* network */);
|
||||
|
||||
// The client for NETWORK_1 receives the callback that the NETWORK_1 has been destroyed,
|
||||
// mockServiceTypeClientOne1 should send service removed notifications and remove from the
|
||||
// list of clients.
|
||||
callback.onSocketDestroyed(NETWORK_1);
|
||||
verify(mockServiceTypeClientOne1).notifyAllServicesRemoved();
|
||||
|
||||
// Receive a response again, it should be processed only on mockServiceTypeClientTwo2.
|
||||
// Because the mockServiceTypeClientOne1 is removed from the list of clients, it is no
|
||||
// longer able to process responses.
|
||||
discoveryManager.onResponseReceived(response, ifIndex, null /* network */);
|
||||
verify(mockServiceTypeClientOne1, times(1))
|
||||
.processResponse(response, ifIndex, null /* network */);
|
||||
verify(mockServiceTypeClientTwo2, times(2))
|
||||
.processResponse(response, ifIndex, null /* network */);
|
||||
|
||||
// The client for NETWORK_2 receives the callback that the NETWORK_1 has been destroyed,
|
||||
// mockServiceTypeClientTwo2 shouldn't send any notifications.
|
||||
callback2.onSocketDestroyed(NETWORK_1);
|
||||
verify(mockServiceTypeClientTwo2, never()).notifyAllServicesRemoved();
|
||||
|
||||
// Receive a response again, mockServiceTypeClientTwo2 is still in the list of clients, it's
|
||||
// still able to process responses.
|
||||
discoveryManager.onResponseReceived(response, ifIndex, null /* network */);
|
||||
verify(mockServiceTypeClientOne1, times(1))
|
||||
.processResponse(response, ifIndex, null /* network */);
|
||||
verify(mockServiceTypeClientTwo2, times(3))
|
||||
.processResponse(response, ifIndex, null /* network */);
|
||||
}
|
||||
|
||||
private MdnsPacket createMdnsPacket(String serviceType) {
|
||||
final String[] type = TextUtils.split(serviceType, "\\.");
|
||||
final ArrayList<String> name = new ArrayList<>(type.length + 1);
|
||||
|
||||
@@ -1056,6 +1056,61 @@ public class MdnsServiceTypeClientTests {
|
||||
inOrder.verify(mockListenerTwo).onServiceRemoved(matchServiceName(otherInstance));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyAllServicesRemoved() {
|
||||
client = new MdnsServiceTypeClient(
|
||||
SERVICE_TYPE, mockSocketClient, currentThreadExecutor, mockNetwork, mockSharedLog);
|
||||
|
||||
final String requestedInstance = "instance1";
|
||||
final String otherInstance = "instance2";
|
||||
final String ipV4Address = "192.0.2.0";
|
||||
|
||||
final MdnsSearchOptions resolveOptions = MdnsSearchOptions.newBuilder()
|
||||
// Use different case in the options
|
||||
.setResolveInstanceName("Instance1").build();
|
||||
|
||||
client.startSendAndReceive(mockListenerOne, resolveOptions);
|
||||
client.startSendAndReceive(mockListenerTwo, MdnsSearchOptions.getDefaultOptions());
|
||||
|
||||
// Complete response from instanceName
|
||||
client.processResponse(createResponse(
|
||||
requestedInstance, ipV4Address, 5353, SERVICE_TYPE_LABELS,
|
||||
Collections.emptyMap() /* textAttributes */, TEST_TTL),
|
||||
INTERFACE_INDEX, mockNetwork);
|
||||
|
||||
// Complete response from otherInstanceName
|
||||
client.processResponse(createResponse(
|
||||
otherInstance, ipV4Address, 5353, SERVICE_TYPE_LABELS,
|
||||
Collections.emptyMap() /* textAttributes */, TEST_TTL),
|
||||
INTERFACE_INDEX, mockNetwork);
|
||||
|
||||
client.notifyAllServicesRemoved();
|
||||
|
||||
// mockListenerOne gets notified for the requested instance
|
||||
final InOrder inOrder1 = inOrder(mockListenerOne);
|
||||
inOrder1.verify(mockListenerOne).onServiceNameDiscovered(
|
||||
matchServiceName(requestedInstance));
|
||||
inOrder1.verify(mockListenerOne).onServiceFound(matchServiceName(requestedInstance));
|
||||
inOrder1.verify(mockListenerOne).onServiceRemoved(matchServiceName(requestedInstance));
|
||||
inOrder1.verify(mockListenerOne).onServiceNameRemoved(matchServiceName(requestedInstance));
|
||||
verify(mockListenerOne, never()).onServiceFound(matchServiceName(otherInstance));
|
||||
verify(mockListenerOne, never()).onServiceNameDiscovered(matchServiceName(otherInstance));
|
||||
verify(mockListenerOne, never()).onServiceRemoved(matchServiceName(otherInstance));
|
||||
verify(mockListenerOne, never()).onServiceNameRemoved(matchServiceName(otherInstance));
|
||||
|
||||
// mockListenerTwo gets notified for both though
|
||||
final InOrder inOrder2 = inOrder(mockListenerTwo);
|
||||
inOrder2.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));
|
||||
}
|
||||
|
||||
private static MdnsServiceInfo matchServiceName(String name) {
|
||||
return argThat(info -> info.getServiceInstanceName().equals(name));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user