From 0a118cefb8df3d5a00d5f4c5e0bccb6a2188af85 Mon Sep 17 00:00:00 2001 From: Hugo Benichi Date: Fri, 28 Apr 2017 15:31:10 +0900 Subject: [PATCH] NsdService: test coverage for client requests. Adding coverage for: - NsdManager client disconnection - in-flight request GC Test: new test passes Bug: 37013369, 33298084 Change-Id: I92039f297cf99352bbf4196797933d89c0b819ff --- .../java/android/net/nsd/NsdServiceTest.java | 97 ++++++++++++++++--- 1 file changed, 84 insertions(+), 13 deletions(-) diff --git a/tests/net/java/android/net/nsd/NsdServiceTest.java b/tests/net/java/android/net/nsd/NsdServiceTest.java index acc390c8d4..68cb251cf8 100644 --- a/tests/net/java/android/net/nsd/NsdServiceTest.java +++ b/tests/net/java/android/net/nsd/NsdServiceTest.java @@ -16,68 +16,121 @@ package com.android.server; +import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.any; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.reset; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.os.Handler; +import android.os.HandlerThread; import android.os.Looper; import android.os.Message; -import android.os.test.TestLooper; import android.content.Context; import android.content.ContentResolver; import android.net.nsd.NsdManager; +import android.net.nsd.NsdServiceInfo; import com.android.server.NsdService.DaemonConnection; import com.android.server.NsdService.DaemonConnectionSupplier; import com.android.server.NsdService.NativeCallbackReceiver; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; +import org.junit.After; 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; // TODOs: -// - test client disconnects // - test client can send requests and receive replies // - test NSD_ON ENABLE/DISABLED listening @RunWith(AndroidJUnit4.class) @SmallTest public class NsdServiceTest { + static final int PROTOCOL = NsdManager.PROTOCOL_DNS_SD; + + long mTimeoutMs = 100; // non-final so that tests can adjust the value. + @Mock Context mContext; @Mock ContentResolver mResolver; @Mock NsdService.NsdSettings mSettings; @Mock DaemonConnection mDaemon; NativeCallbackReceiver mDaemonCallback; - TestLooper mLooper; + HandlerThread mThread; TestHandler mHandler; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - mLooper = new TestLooper(); - mHandler = new TestHandler(mLooper.getLooper()); + mThread = new HandlerThread("mock-service-handler"); + mThread.start(); + mHandler = new TestHandler(mThread.getLooper()); when(mContext.getContentResolver()).thenReturn(mResolver); } + @After + public void tearDown() throws Exception { + mThread.quit(); + } + @Test - public void testClientsCanConnect() { + public void testClientsCanConnectAndDisconnect() { when(mSettings.isEnabled()).thenReturn(true); NsdService service = makeService(); NsdManager client1 = connectClient(service); - verify(mDaemon, timeout(100).times(1)).execute("start-service"); + verify(mDaemon, timeout(100).times(1)).start(); NsdManager client2 = connectClient(service); - // TODO: disconnect client1 - // TODO: disconnect client2 + client1.disconnect(); + client2.disconnect(); + + verify(mDaemon, timeout(mTimeoutMs).times(1)).stop(); + } + + @Test + public void testClientRequestsAreGCedAtDisconnection() { + when(mSettings.isEnabled()).thenReturn(true); + when(mDaemon.execute(any())).thenReturn(true); + + NsdService service = makeService(); + NsdManager client = connectClient(service); + + verify(mDaemon, timeout(100).times(1)).start(); + + NsdServiceInfo request = new NsdServiceInfo("a_name", "a_type"); + request.setPort(2201); + + // Client registration request + NsdManager.RegistrationListener listener1 = mock(NsdManager.RegistrationListener.class); + client.registerService(request, PROTOCOL, listener1); + verifyDaemonCommand("register 2 a_name a_type 2201"); + + // Client discovery request + NsdManager.DiscoveryListener listener2 = mock(NsdManager.DiscoveryListener.class); + client.discoverServices("a_type", PROTOCOL, listener2); + verifyDaemonCommand("discover 3 a_type"); + + // Client resolve request + NsdManager.ResolveListener listener3 = mock(NsdManager.ResolveListener.class); + client.resolveService(request, listener3); + verifyDaemonCommand("resolve 4 a_name a_type local."); + + // Client disconnects + client.disconnect(); + verify(mDaemon, timeout(mTimeoutMs).times(1)).stop(); + + // checks that request are cleaned + verifyDaemonCommands("stop-register 2", "stop-discover 3", "stop-resolve 4"); } NsdService makeService() { @@ -91,10 +144,28 @@ public class NsdServiceTest { } NsdManager connectClient(NsdService service) { - mLooper.startAutoDispatch(); - NsdManager client = new NsdManager(mContext, service); - mLooper.stopAutoDispatch(); - return client; + return new NsdManager(mContext, service); + } + + void verifyDaemonCommands(String... wants) { + verifyDaemonCommand(String.join(" ", wants), wants.length); + } + + void verifyDaemonCommand(String want) { + verifyDaemonCommand(want, 1); + } + + void verifyDaemonCommand(String want, int n) { + ArgumentCaptor argumentsCaptor = ArgumentCaptor.forClass(Object.class); + verify(mDaemon, timeout(mTimeoutMs).times(n)).execute(argumentsCaptor.capture()); + String got = ""; + for (Object o : argumentsCaptor.getAllValues()) { + got += o + " "; + } + assertEquals(want, got.trim()); + // rearm deamon for next command verification + reset(mDaemon); + when(mDaemon.execute(any())).thenReturn(true); } public static class TestHandler extends Handler {