1 /* 2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 package org.appspot.apprtc; 12 13 import static org.junit.Assert.assertFalse; 14 import static org.junit.Assert.assertTrue; 15 import static org.junit.Assert.fail; 16 import static org.mockito.ArgumentMatchers.any; 17 import static org.mockito.ArgumentMatchers.isNotNull; 18 import static org.mockito.Mockito.mock; 19 import static org.mockito.Mockito.timeout; 20 import static org.mockito.Mockito.verify; 21 import static org.mockito.Mockito.verifyNoMoreInteractions; 22 23 import org.chromium.testing.local.LocalRobolectricTestRunner; 24 import org.junit.Before; 25 import org.junit.Test; 26 import org.junit.runner.RunWith; 27 import org.robolectric.annotation.Config; 28 import org.robolectric.shadows.ShadowLog; 29 import org.webrtc.IceCandidate; 30 import org.webrtc.SessionDescription; 31 32 /** 33 * Test for DirectRTCClient. Test is very simple and only tests the overall sanity of the class 34 * behaviour. 35 */ 36 @RunWith(LocalRobolectricTestRunner.class) 37 @Config(manifest = Config.NONE) 38 public class DirectRTCClientTest { 39 private static final String ROOM_URL = ""; 40 private static final boolean LOOPBACK = false; 41 42 private static final String DUMMY_SDP_MID = "sdpMid"; 43 private static final String DUMMY_SDP = "sdp"; 44 45 public static final int SERVER_WAIT = 100; 46 public static final int NETWORK_TIMEOUT = 1000; 47 48 private DirectRTCClient client; 49 private DirectRTCClient server; 50 51 AppRTCClient.SignalingEvents clientEvents; 52 AppRTCClient.SignalingEvents serverEvents; 53 54 @Before setUp()55 public void setUp() { 56 ShadowLog.stream = System.out; 57 58 clientEvents = mock(AppRTCClient.SignalingEvents.class); 59 serverEvents = mock(AppRTCClient.SignalingEvents.class); 60 61 client = new DirectRTCClient(clientEvents); 62 server = new DirectRTCClient(serverEvents); 63 } 64 65 @Test testValidIpPattern()66 public void testValidIpPattern() { 67 // Strings that should match the pattern. 68 // clang-format off 69 final String[] ipAddresses = new String[] { 70 "0.0.0.0", 71 "127.0.0.1", 72 "192.168.0.1", 73 "0.0.0.0:8888", 74 "127.0.0.1:8888", 75 "192.168.0.1:8888", 76 "::", 77 "::1", 78 "2001:0db8:85a3:0000:0000:8a2e:0370:7946", 79 "[::]", 80 "[::1]", 81 "[2001:0db8:85a3:0000:0000:8a2e:0370:7946]", 82 "[::]:8888", 83 "[::1]:8888", 84 "[2001:0db8:85a3:0000:0000:8a2e:0370:7946]:8888" 85 }; 86 // clang-format on 87 88 for (String ip : ipAddresses) { 89 assertTrue(ip + " didn't match IP_PATTERN even though it should.", 90 DirectRTCClient.IP_PATTERN.matcher(ip).matches()); 91 } 92 } 93 94 @Test testInvalidIpPattern()95 public void testInvalidIpPattern() { 96 // Strings that shouldn't match the pattern. 97 // clang-format off 98 final String[] invalidIpAddresses = new String[] { 99 "Hello, World!", 100 "aaaa", 101 "1111", 102 "[hello world]", 103 "hello:world" 104 }; 105 // clang-format on 106 107 for (String invalidIp : invalidIpAddresses) { 108 assertFalse(invalidIp + " matched IP_PATTERN even though it shouldn't.", 109 DirectRTCClient.IP_PATTERN.matcher(invalidIp).matches()); 110 } 111 } 112 113 // TODO(sakal): Replace isNotNull(class) with isNotNull() once Java 8 is used. 114 @SuppressWarnings("deprecation") 115 @Test testDirectRTCClient()116 public void testDirectRTCClient() { 117 server.connectToRoom(new AppRTCClient.RoomConnectionParameters(ROOM_URL, "0.0.0.0", LOOPBACK)); 118 try { 119 Thread.sleep(SERVER_WAIT); 120 } catch (InterruptedException e) { 121 fail(e.getMessage()); 122 } 123 client.connectToRoom( 124 new AppRTCClient.RoomConnectionParameters(ROOM_URL, "127.0.0.1", LOOPBACK)); 125 verify(serverEvents, timeout(NETWORK_TIMEOUT)) 126 .onConnectedToRoom(any(AppRTCClient.SignalingParameters.class)); 127 128 SessionDescription offerSdp = new SessionDescription(SessionDescription.Type.OFFER, DUMMY_SDP); 129 server.sendOfferSdp(offerSdp); 130 verify(clientEvents, timeout(NETWORK_TIMEOUT)) 131 .onConnectedToRoom(any(AppRTCClient.SignalingParameters.class)); 132 133 SessionDescription answerSdp = 134 new SessionDescription(SessionDescription.Type.ANSWER, DUMMY_SDP); 135 client.sendAnswerSdp(answerSdp); 136 verify(serverEvents, timeout(NETWORK_TIMEOUT)) 137 .onRemoteDescription(isNotNull(SessionDescription.class)); 138 139 IceCandidate candidate = new IceCandidate(DUMMY_SDP_MID, 0, DUMMY_SDP); 140 server.sendLocalIceCandidate(candidate); 141 verify(clientEvents, timeout(NETWORK_TIMEOUT)) 142 .onRemoteIceCandidate(isNotNull(IceCandidate.class)); 143 144 client.sendLocalIceCandidate(candidate); 145 verify(serverEvents, timeout(NETWORK_TIMEOUT)) 146 .onRemoteIceCandidate(isNotNull(IceCandidate.class)); 147 148 client.disconnectFromRoom(); 149 verify(clientEvents, timeout(NETWORK_TIMEOUT)).onChannelClose(); 150 verify(serverEvents, timeout(NETWORK_TIMEOUT)).onChannelClose(); 151 152 verifyNoMoreInteractions(clientEvents); 153 verifyNoMoreInteractions(serverEvents); 154 } 155 } 156