Moving src/webrtc into src/.
In order to eliminate the WebRTC Subtree mirror in Chromium, WebRTC is moving the content of the src/webrtc directory up to the src/ directory. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true TBR=tommi@webrtc.org Bug: chromium:611808 Change-Id: Iac59c5b51b950f174119565bac87955a7994bc38 Reviewed-on: https://webrtc-review.googlesource.com/1560 Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org> Reviewed-by: Henrik Kjellander <kjellander@webrtc.org> Cr-Commit-Position: refs/heads/master@{#19845}
This commit is contained in:
committed by
Commit Bot
parent
6674846b4a
commit
bb547203bf
@ -0,0 +1,271 @@
|
||||
/*
|
||||
* Copyright 2016 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
package org.appspot.apprtc;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.doCallRealMethod;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothHeadset;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.media.AudioManager;
|
||||
import android.util.Log;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import org.appspot.apprtc.AppRTCBluetoothManager.State;
|
||||
import org.chromium.testing.local.LocalRobolectricTestRunner;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
import org.robolectric.shadows.ShadowLog;
|
||||
|
||||
/**
|
||||
* Verifies basic behavior of the AppRTCBluetoothManager class.
|
||||
* Note that the test object uses an AppRTCAudioManager (injected in ctor),
|
||||
* but a mocked version is used instead. Hence, the parts "driven" by the AppRTC
|
||||
* audio manager are not included in this test.
|
||||
*/
|
||||
@RunWith(LocalRobolectricTestRunner.class)
|
||||
@Config(manifest = Config.NONE)
|
||||
public class BluetoothManagerTest {
|
||||
private static final String TAG = "BluetoothManagerTest";
|
||||
private static final String BLUETOOTH_TEST_DEVICE_NAME = "BluetoothTestDevice";
|
||||
|
||||
private BroadcastReceiver bluetoothHeadsetStateReceiver;
|
||||
private BluetoothProfile.ServiceListener bluetoothServiceListener;
|
||||
private BluetoothHeadset mockedBluetoothHeadset;
|
||||
private BluetoothDevice mockedBluetoothDevice;
|
||||
private List<BluetoothDevice> mockedBluetoothDeviceList;
|
||||
private AppRTCBluetoothManager bluetoothManager;
|
||||
private AppRTCAudioManager mockedAppRtcAudioManager;
|
||||
private AudioManager mockedAudioManager;
|
||||
private Context context;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
ShadowLog.stream = System.out;
|
||||
context = ShadowApplication.getInstance().getApplicationContext();
|
||||
mockedAppRtcAudioManager = mock(AppRTCAudioManager.class);
|
||||
mockedAudioManager = mock(AudioManager.class);
|
||||
mockedBluetoothHeadset = mock(BluetoothHeadset.class);
|
||||
mockedBluetoothDevice = mock(BluetoothDevice.class);
|
||||
mockedBluetoothDeviceList = new LinkedList<BluetoothDevice>();
|
||||
|
||||
// Simulate that bluetooth SCO audio is available by default.
|
||||
when(mockedAudioManager.isBluetoothScoAvailableOffCall()).thenReturn(true);
|
||||
|
||||
// Create the test object and override protected methods for this test.
|
||||
bluetoothManager = new AppRTCBluetoothManager(context, mockedAppRtcAudioManager) {
|
||||
@Override
|
||||
protected AudioManager getAudioManager(Context context) {
|
||||
Log.d(TAG, "getAudioManager");
|
||||
return mockedAudioManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
|
||||
Log.d(TAG, "registerReceiver");
|
||||
if (filter.hasAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)
|
||||
&& filter.hasAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
|
||||
// Gives access to the real broadcast receiver so the test can use it.
|
||||
bluetoothHeadsetStateReceiver = receiver;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void unregisterReceiver(BroadcastReceiver receiver) {
|
||||
Log.d(TAG, "unregisterReceiver");
|
||||
if (receiver == bluetoothHeadsetStateReceiver) {
|
||||
bluetoothHeadsetStateReceiver = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean getBluetoothProfileProxy(
|
||||
Context context, BluetoothProfile.ServiceListener listener, int profile) {
|
||||
Log.d(TAG, "getBluetoothProfileProxy");
|
||||
if (profile == BluetoothProfile.HEADSET) {
|
||||
// Allows the test to access the real Bluetooth service listener object.
|
||||
bluetoothServiceListener = listener;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasPermission(Context context, String permission) {
|
||||
Log.d(TAG, "hasPermission(" + permission + ")");
|
||||
// Ensure that the client asks for Bluetooth permission.
|
||||
return (permission == android.Manifest.permission.BLUETOOTH);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void logBluetoothAdapterInfo(BluetoothAdapter localAdapter) {
|
||||
// Do nothing in tests. No need to mock BluetoothAdapter.
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Verify that Bluetooth service listener for headset profile is properly initialized.
|
||||
@Test
|
||||
public void testBluetoothServiceListenerInitialized() {
|
||||
bluetoothManager.start();
|
||||
assertNotNull(bluetoothServiceListener);
|
||||
verify(mockedAppRtcAudioManager, never()).updateAudioDeviceState();
|
||||
}
|
||||
|
||||
// Verify that broadcast receivers for Bluetooth SCO audio state and Bluetooth headset state
|
||||
// are properly registered and unregistered.
|
||||
@Test
|
||||
public void testBluetoothBroadcastReceiversAreRegistered() {
|
||||
bluetoothManager.start();
|
||||
assertNotNull(bluetoothHeadsetStateReceiver);
|
||||
bluetoothManager.stop();
|
||||
assertNull(bluetoothHeadsetStateReceiver);
|
||||
}
|
||||
|
||||
// Verify that the Bluetooth manager starts and stops with correct states.
|
||||
@Test
|
||||
public void testBluetoothDefaultStartStopStates() {
|
||||
bluetoothManager.start();
|
||||
assertEquals(bluetoothManager.getState(), State.HEADSET_UNAVAILABLE);
|
||||
bluetoothManager.stop();
|
||||
assertEquals(bluetoothManager.getState(), State.UNINITIALIZED);
|
||||
}
|
||||
|
||||
// Verify correct state after receiving BluetoothServiceListener.onServiceConnected()
|
||||
// when no BT device is enabled.
|
||||
@Test
|
||||
public void testBluetoothServiceListenerConnectedWithNoHeadset() {
|
||||
bluetoothManager.start();
|
||||
assertEquals(bluetoothManager.getState(), State.HEADSET_UNAVAILABLE);
|
||||
simulateBluetoothServiceConnectedWithNoConnectedHeadset();
|
||||
verify(mockedAppRtcAudioManager, times(1)).updateAudioDeviceState();
|
||||
assertEquals(bluetoothManager.getState(), State.HEADSET_UNAVAILABLE);
|
||||
}
|
||||
|
||||
// Verify correct state after receiving BluetoothServiceListener.onServiceConnected()
|
||||
// when one emulated (test) BT device is enabled. Android does not support more than
|
||||
// one connected BT headset.
|
||||
@Test
|
||||
public void testBluetoothServiceListenerConnectedWithHeadset() {
|
||||
bluetoothManager.start();
|
||||
assertEquals(bluetoothManager.getState(), State.HEADSET_UNAVAILABLE);
|
||||
simulateBluetoothServiceConnectedWithConnectedHeadset();
|
||||
verify(mockedAppRtcAudioManager, times(1)).updateAudioDeviceState();
|
||||
assertEquals(bluetoothManager.getState(), State.HEADSET_AVAILABLE);
|
||||
}
|
||||
|
||||
// Verify correct state after receiving BluetoothProfile.ServiceListener.onServiceDisconnected().
|
||||
@Test
|
||||
public void testBluetoothServiceListenerDisconnected() {
|
||||
bluetoothManager.start();
|
||||
assertEquals(bluetoothManager.getState(), State.HEADSET_UNAVAILABLE);
|
||||
simulateBluetoothServiceDisconnected();
|
||||
verify(mockedAppRtcAudioManager, times(1)).updateAudioDeviceState();
|
||||
assertEquals(bluetoothManager.getState(), State.HEADSET_UNAVAILABLE);
|
||||
}
|
||||
|
||||
// Verify correct state after BluetoothServiceListener.onServiceConnected() and
|
||||
// the intent indicating that the headset is actually connected. Both these callbacks
|
||||
// results in calls to updateAudioDeviceState() on the AppRTC audio manager.
|
||||
// No BT SCO is enabled here to keep the test limited.
|
||||
@Test
|
||||
public void testBluetoothHeadsetConnected() {
|
||||
bluetoothManager.start();
|
||||
assertEquals(bluetoothManager.getState(), State.HEADSET_UNAVAILABLE);
|
||||
simulateBluetoothServiceConnectedWithConnectedHeadset();
|
||||
simulateBluetoothHeadsetConnected();
|
||||
verify(mockedAppRtcAudioManager, times(2)).updateAudioDeviceState();
|
||||
assertEquals(bluetoothManager.getState(), State.HEADSET_AVAILABLE);
|
||||
}
|
||||
|
||||
// Verify correct state sequence for a case when a BT headset is available,
|
||||
// followed by BT SCO audio being enabled and then stopped.
|
||||
@Test
|
||||
public void testBluetoothScoAudioStartAndStop() {
|
||||
bluetoothManager.start();
|
||||
assertEquals(bluetoothManager.getState(), State.HEADSET_UNAVAILABLE);
|
||||
simulateBluetoothServiceConnectedWithConnectedHeadset();
|
||||
assertEquals(bluetoothManager.getState(), State.HEADSET_AVAILABLE);
|
||||
bluetoothManager.startScoAudio();
|
||||
assertEquals(bluetoothManager.getState(), State.SCO_CONNECTING);
|
||||
simulateBluetoothScoConnectionConnected();
|
||||
assertEquals(bluetoothManager.getState(), State.SCO_CONNECTED);
|
||||
bluetoothManager.stopScoAudio();
|
||||
simulateBluetoothScoConnectionDisconnected();
|
||||
assertEquals(bluetoothManager.getState(), State.SCO_DISCONNECTING);
|
||||
bluetoothManager.stop();
|
||||
assertEquals(bluetoothManager.getState(), State.UNINITIALIZED);
|
||||
verify(mockedAppRtcAudioManager, times(3)).updateAudioDeviceState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Private helper methods.
|
||||
*/
|
||||
private void simulateBluetoothServiceConnectedWithNoConnectedHeadset() {
|
||||
mockedBluetoothDeviceList.clear();
|
||||
when(mockedBluetoothHeadset.getConnectedDevices()).thenReturn(mockedBluetoothDeviceList);
|
||||
bluetoothServiceListener.onServiceConnected(BluetoothProfile.HEADSET, mockedBluetoothHeadset);
|
||||
// In real life, the AppRTC audio manager makes this call.
|
||||
bluetoothManager.updateDevice();
|
||||
}
|
||||
|
||||
private void simulateBluetoothServiceConnectedWithConnectedHeadset() {
|
||||
mockedBluetoothDeviceList.clear();
|
||||
mockedBluetoothDeviceList.add(mockedBluetoothDevice);
|
||||
when(mockedBluetoothHeadset.getConnectedDevices()).thenReturn(mockedBluetoothDeviceList);
|
||||
when(mockedBluetoothDevice.getName()).thenReturn(BLUETOOTH_TEST_DEVICE_NAME);
|
||||
bluetoothServiceListener.onServiceConnected(BluetoothProfile.HEADSET, mockedBluetoothHeadset);
|
||||
// In real life, the AppRTC audio manager makes this call.
|
||||
bluetoothManager.updateDevice();
|
||||
}
|
||||
|
||||
private void simulateBluetoothServiceDisconnected() {
|
||||
bluetoothServiceListener.onServiceDisconnected(BluetoothProfile.HEADSET);
|
||||
}
|
||||
|
||||
private void simulateBluetoothHeadsetConnected() {
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
|
||||
intent.putExtra(BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.STATE_CONNECTED);
|
||||
bluetoothHeadsetStateReceiver.onReceive(context, intent);
|
||||
}
|
||||
|
||||
private void simulateBluetoothScoConnectionConnected() {
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
|
||||
intent.putExtra(BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.STATE_AUDIO_CONNECTED);
|
||||
bluetoothHeadsetStateReceiver.onReceive(context, intent);
|
||||
}
|
||||
|
||||
private void simulateBluetoothScoConnectionDisconnected() {
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
|
||||
intent.putExtra(BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
|
||||
bluetoothHeadsetStateReceiver.onReceive(context, intent);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright 2016 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
package org.appspot.apprtc;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.isNotNull;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.timeout;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
import org.chromium.testing.local.LocalRobolectricTestRunner;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowLog;
|
||||
import org.webrtc.IceCandidate;
|
||||
import org.webrtc.SessionDescription;
|
||||
|
||||
/**
|
||||
* Test for DirectRTCClient. Test is very simple and only tests the overall sanity of the class
|
||||
* behaviour.
|
||||
*/
|
||||
@RunWith(LocalRobolectricTestRunner.class)
|
||||
@Config(manifest = Config.NONE)
|
||||
public class DirectRTCClientTest {
|
||||
private static final String ROOM_URL = "";
|
||||
private static final boolean LOOPBACK = false;
|
||||
|
||||
private static final String DUMMY_SDP_MID = "sdpMid";
|
||||
private static final String DUMMY_SDP = "sdp";
|
||||
|
||||
public static final int SERVER_WAIT = 100;
|
||||
public static final int NETWORK_TIMEOUT = 1000;
|
||||
|
||||
private DirectRTCClient client;
|
||||
private DirectRTCClient server;
|
||||
|
||||
AppRTCClient.SignalingEvents clientEvents;
|
||||
AppRTCClient.SignalingEvents serverEvents;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
ShadowLog.stream = System.out;
|
||||
|
||||
clientEvents = mock(AppRTCClient.SignalingEvents.class);
|
||||
serverEvents = mock(AppRTCClient.SignalingEvents.class);
|
||||
|
||||
client = new DirectRTCClient(clientEvents);
|
||||
server = new DirectRTCClient(serverEvents);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidIpPattern() {
|
||||
// Strings that should match the pattern.
|
||||
// clang-format off
|
||||
final String[] ipAddresses = new String[] {
|
||||
"0.0.0.0",
|
||||
"127.0.0.1",
|
||||
"192.168.0.1",
|
||||
"0.0.0.0:8888",
|
||||
"127.0.0.1:8888",
|
||||
"192.168.0.1:8888",
|
||||
"::",
|
||||
"::1",
|
||||
"2001:0db8:85a3:0000:0000:8a2e:0370:7946",
|
||||
"[::]",
|
||||
"[::1]",
|
||||
"[2001:0db8:85a3:0000:0000:8a2e:0370:7946]",
|
||||
"[::]:8888",
|
||||
"[::1]:8888",
|
||||
"[2001:0db8:85a3:0000:0000:8a2e:0370:7946]:8888"
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
for (String ip : ipAddresses) {
|
||||
assertTrue(ip + " didn't match IP_PATTERN even though it should.",
|
||||
DirectRTCClient.IP_PATTERN.matcher(ip).matches());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidIpPattern() {
|
||||
// Strings that shouldn't match the pattern.
|
||||
// clang-format off
|
||||
final String[] invalidIpAddresses = new String[] {
|
||||
"Hello, World!",
|
||||
"aaaa",
|
||||
"1111",
|
||||
"[hello world]",
|
||||
"hello:world"
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
for (String invalidIp : invalidIpAddresses) {
|
||||
assertFalse(invalidIp + " matched IP_PATTERN even though it shouldn't.",
|
||||
DirectRTCClient.IP_PATTERN.matcher(invalidIp).matches());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(sakal): Replace isNotNull(class) with isNotNull() once Java 8 is used.
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test
|
||||
public void testDirectRTCClient() {
|
||||
server.connectToRoom(new AppRTCClient.RoomConnectionParameters(ROOM_URL, "0.0.0.0", LOOPBACK));
|
||||
try {
|
||||
Thread.sleep(SERVER_WAIT);
|
||||
} catch (InterruptedException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
client.connectToRoom(
|
||||
new AppRTCClient.RoomConnectionParameters(ROOM_URL, "127.0.0.1", LOOPBACK));
|
||||
verify(serverEvents, timeout(NETWORK_TIMEOUT))
|
||||
.onConnectedToRoom(any(AppRTCClient.SignalingParameters.class));
|
||||
|
||||
SessionDescription offerSdp = new SessionDescription(SessionDescription.Type.OFFER, DUMMY_SDP);
|
||||
server.sendOfferSdp(offerSdp);
|
||||
verify(clientEvents, timeout(NETWORK_TIMEOUT))
|
||||
.onConnectedToRoom(any(AppRTCClient.SignalingParameters.class));
|
||||
|
||||
SessionDescription answerSdp =
|
||||
new SessionDescription(SessionDescription.Type.ANSWER, DUMMY_SDP);
|
||||
client.sendAnswerSdp(answerSdp);
|
||||
verify(serverEvents, timeout(NETWORK_TIMEOUT))
|
||||
.onRemoteDescription(isNotNull(SessionDescription.class));
|
||||
|
||||
IceCandidate candidate = new IceCandidate(DUMMY_SDP_MID, 0, DUMMY_SDP);
|
||||
server.sendLocalIceCandidate(candidate);
|
||||
verify(clientEvents, timeout(NETWORK_TIMEOUT))
|
||||
.onRemoteIceCandidate(isNotNull(IceCandidate.class));
|
||||
|
||||
client.sendLocalIceCandidate(candidate);
|
||||
verify(serverEvents, timeout(NETWORK_TIMEOUT))
|
||||
.onRemoteIceCandidate(isNotNull(IceCandidate.class));
|
||||
|
||||
client.disconnectFromRoom();
|
||||
verify(clientEvents, timeout(NETWORK_TIMEOUT)).onChannelClose();
|
||||
verify(serverEvents, timeout(NETWORK_TIMEOUT)).onChannelClose();
|
||||
|
||||
verifyNoMoreInteractions(clientEvents);
|
||||
verifyNoMoreInteractions(serverEvents);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Copyright 2016 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
package org.appspot.apprtc;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.timeout;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
import org.chromium.base.test.util.DisabledTest;
|
||||
import org.chromium.testing.local.LocalRobolectricTestRunner;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowLog;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@RunWith(LocalRobolectricTestRunner.class)
|
||||
@Config(manifest = Config.NONE)
|
||||
public class TCPChannelClientTest {
|
||||
private static final int PORT = 8888;
|
||||
/**
|
||||
* How long we wait before trying to connect to the server. Chosen quite arbitrarily and
|
||||
* could be made smaller if need be.
|
||||
*/
|
||||
private static final int SERVER_WAIT = 10;
|
||||
private static final int CONNECT_TIMEOUT = 100;
|
||||
private static final int SEND_TIMEOUT = 100;
|
||||
private static final int DISCONNECT_TIMEOUT = 100;
|
||||
private static final int TERMINATION_TIMEOUT = 1000;
|
||||
private static final String TEST_MESSAGE_SERVER = "Hello, Server!";
|
||||
private static final String TEST_MESSAGE_CLIENT = "Hello, Client!";
|
||||
|
||||
@Mock TCPChannelClient.TCPChannelEvents serverEvents;
|
||||
@Mock TCPChannelClient.TCPChannelEvents clientEvents;
|
||||
|
||||
private ExecutorService executor;
|
||||
private TCPChannelClient server;
|
||||
private TCPChannelClient client;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
ShadowLog.stream = System.out;
|
||||
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
executor = Executors.newSingleThreadExecutor();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
verifyNoMoreEvents();
|
||||
|
||||
executeAndWait(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
client.disconnect();
|
||||
server.disconnect();
|
||||
}
|
||||
});
|
||||
|
||||
// Stop the executor thread
|
||||
executor.shutdown();
|
||||
try {
|
||||
executor.awaitTermination(TERMINATION_TIMEOUT, TimeUnit.MILLISECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnectIPv4() {
|
||||
setUpIPv4Server();
|
||||
try {
|
||||
Thread.sleep(SERVER_WAIT);
|
||||
} catch (InterruptedException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
setUpIPv4Client();
|
||||
|
||||
verify(serverEvents, timeout(CONNECT_TIMEOUT)).onTCPConnected(true);
|
||||
verify(clientEvents, timeout(CONNECT_TIMEOUT)).onTCPConnected(false);
|
||||
}
|
||||
|
||||
// @Test
|
||||
// Disabled because it fails when IPv6 is not supported on the bot.
|
||||
// TODO(ehmaldonado): Enable when bugs.webrtc.org/6437 is fixed.
|
||||
@DisabledTest
|
||||
public void testConnectIPv6() {
|
||||
setUpIPv6Server();
|
||||
try {
|
||||
Thread.sleep(SERVER_WAIT);
|
||||
} catch (InterruptedException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
setUpIPv6Client();
|
||||
|
||||
verify(serverEvents, timeout(CONNECT_TIMEOUT)).onTCPConnected(true);
|
||||
verify(clientEvents, timeout(CONNECT_TIMEOUT)).onTCPConnected(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendData() {
|
||||
testConnectIPv4();
|
||||
|
||||
executeAndWait(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
client.send(TEST_MESSAGE_SERVER);
|
||||
server.send(TEST_MESSAGE_CLIENT);
|
||||
}
|
||||
});
|
||||
|
||||
verify(serverEvents, timeout(SEND_TIMEOUT)).onTCPMessage(TEST_MESSAGE_SERVER);
|
||||
verify(clientEvents, timeout(SEND_TIMEOUT)).onTCPMessage(TEST_MESSAGE_CLIENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisconnectServer() {
|
||||
testConnectIPv4();
|
||||
executeAndWait(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
server.disconnect();
|
||||
}
|
||||
});
|
||||
|
||||
verify(serverEvents, timeout(DISCONNECT_TIMEOUT)).onTCPClose();
|
||||
verify(clientEvents, timeout(DISCONNECT_TIMEOUT)).onTCPClose();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisconnectClient() {
|
||||
testConnectIPv4();
|
||||
executeAndWait(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
client.disconnect();
|
||||
}
|
||||
});
|
||||
|
||||
verify(serverEvents, timeout(DISCONNECT_TIMEOUT)).onTCPClose();
|
||||
verify(clientEvents, timeout(DISCONNECT_TIMEOUT)).onTCPClose();
|
||||
}
|
||||
|
||||
private void setUpIPv4Server() {
|
||||
setUpServer("0.0.0.0", PORT);
|
||||
}
|
||||
|
||||
private void setUpIPv4Client() {
|
||||
setUpClient("127.0.0.1", PORT);
|
||||
}
|
||||
|
||||
private void setUpIPv6Server() {
|
||||
setUpServer("::", PORT);
|
||||
}
|
||||
|
||||
private void setUpIPv6Client() {
|
||||
setUpClient("::1", PORT);
|
||||
}
|
||||
|
||||
private void setUpServer(String ip, int port) {
|
||||
server = new TCPChannelClient(executor, serverEvents, ip, port);
|
||||
}
|
||||
|
||||
private void setUpClient(String ip, int port) {
|
||||
client = new TCPChannelClient(executor, clientEvents, ip, port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies no more server or client events have been issued
|
||||
*/
|
||||
private void verifyNoMoreEvents() {
|
||||
verifyNoMoreInteractions(serverEvents);
|
||||
verifyNoMoreInteractions(clientEvents);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queues runnable to be run and waits for it to be executed by the executor thread
|
||||
*/
|
||||
public void executeAndWait(Runnable runnable) {
|
||||
try {
|
||||
executor.submit(runnable).get();
|
||||
} catch (Exception e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user