1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.net.ip; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertTrue; 22 import static org.junit.Assert.fail; 23 import static org.mockito.Mockito.any; 24 import static org.mockito.Mockito.anyString; 25 import static org.mockito.Mockito.eq; 26 import static org.mockito.Mockito.never; 27 import static org.mockito.Mockito.reset; 28 import static org.mockito.Mockito.timeout; 29 import static org.mockito.Mockito.times; 30 import static org.mockito.Mockito.verify; 31 import static org.mockito.Mockito.verifyNoMoreInteractions; 32 import static org.mockito.Mockito.when; 33 34 import android.app.AlarmManager; 35 import android.content.ContentResolver; 36 import android.content.Context; 37 import android.content.res.Resources; 38 import android.net.ConnectivityManager; 39 import android.net.INetd; 40 import android.net.IpPrefix; 41 import android.net.LinkAddress; 42 import android.net.LinkProperties; 43 import android.net.MacAddress; 44 import android.net.NetworkStackIpMemoryStore; 45 import android.net.RouteInfo; 46 import android.net.ipmemorystore.NetworkAttributes; 47 import android.net.shared.InitialConfiguration; 48 import android.net.shared.ProvisioningConfiguration; 49 import android.net.util.InterfaceParams; 50 51 import androidx.test.filters.SmallTest; 52 import androidx.test.runner.AndroidJUnit4; 53 54 import com.android.internal.R; 55 import com.android.server.NetworkObserver; 56 import com.android.server.NetworkObserverRegistry; 57 import com.android.server.NetworkStackService; 58 59 import org.junit.Before; 60 import org.junit.Test; 61 import org.junit.runner.RunWith; 62 import org.mockito.ArgumentCaptor; 63 import org.mockito.Mock; 64 import org.mockito.MockitoAnnotations; 65 66 import java.net.InetAddress; 67 import java.util.Arrays; 68 import java.util.HashSet; 69 import java.util.List; 70 import java.util.Set; 71 72 /** 73 * Tests for IpClient. 74 */ 75 @RunWith(AndroidJUnit4.class) 76 @SmallTest 77 public class IpClientTest { 78 private static final int DEFAULT_AVOIDBADWIFI_CONFIG_VALUE = 1; 79 80 private static final String VALID = "VALID"; 81 private static final String INVALID = "INVALID"; 82 private static final String TEST_IFNAME = "test_wlan0"; 83 private static final int TEST_IFINDEX = 1001; 84 // See RFC 7042#section-2.1.2 for EUI-48 documentation values. 85 private static final MacAddress TEST_MAC = MacAddress.fromString("00:00:5E:00:53:01"); 86 private static final int TEST_TIMEOUT_MS = 400; 87 private static final String TEST_L2KEY = "some l2key"; 88 private static final String TEST_GROUPHINT = "some grouphint"; 89 90 @Mock private Context mContext; 91 @Mock private ConnectivityManager mCm; 92 @Mock private NetworkObserverRegistry mObserverRegistry; 93 @Mock private INetd mNetd; 94 @Mock private Resources mResources; 95 @Mock private IIpClientCallbacks mCb; 96 @Mock private AlarmManager mAlarm; 97 @Mock private IpClient.Dependencies mDependencies; 98 @Mock private ContentResolver mContentResolver; 99 @Mock private NetworkStackService.NetworkStackServiceManager mNetworkStackServiceManager; 100 @Mock private NetworkStackIpMemoryStore mIpMemoryStore; 101 102 private NetworkObserver mObserver; 103 private InterfaceParams mIfParams; 104 105 @Before setUp()106 public void setUp() throws Exception { 107 MockitoAnnotations.initMocks(this); 108 109 when(mContext.getSystemService(eq(Context.ALARM_SERVICE))).thenReturn(mAlarm); 110 when(mContext.getSystemService(eq(ConnectivityManager.class))).thenReturn(mCm); 111 when(mContext.getResources()).thenReturn(mResources); 112 when(mDependencies.getNetd(any())).thenReturn(mNetd); 113 when(mResources.getInteger(R.integer.config_networkAvoidBadWifi)) 114 .thenReturn(DEFAULT_AVOIDBADWIFI_CONFIG_VALUE); 115 when(mContext.getContentResolver()).thenReturn(mContentResolver); 116 117 mIfParams = null; 118 } 119 setTestInterfaceParams(String ifname)120 private void setTestInterfaceParams(String ifname) { 121 mIfParams = (ifname != null) 122 ? new InterfaceParams(ifname, TEST_IFINDEX, TEST_MAC) 123 : null; 124 when(mDependencies.getInterfaceParams(anyString())).thenReturn(mIfParams); 125 } 126 makeIpClient(String ifname)127 private IpClient makeIpClient(String ifname) throws Exception { 128 setTestInterfaceParams(ifname); 129 final IpClient ipc = new IpClient(mContext, ifname, mCb, mObserverRegistry, 130 mNetworkStackServiceManager, mDependencies); 131 verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceSetEnableIPv6(ifname, false); 132 verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceClearAddrs(ifname); 133 ArgumentCaptor<NetworkObserver> arg = ArgumentCaptor.forClass(NetworkObserver.class); 134 verify(mObserverRegistry, times(1)).registerObserverForNonblockingCallback(arg.capture()); 135 mObserver = arg.getValue(); 136 reset(mObserverRegistry); 137 reset(mNetd); 138 // Verify IpClient doesn't call onLinkPropertiesChange() when it starts. 139 verify(mCb, never()).onLinkPropertiesChange(any()); 140 reset(mCb); 141 return ipc; 142 } 143 makeEmptyLinkProperties(String iface)144 private static LinkProperties makeEmptyLinkProperties(String iface) { 145 final LinkProperties empty = new LinkProperties(); 146 empty.setInterfaceName(iface); 147 return empty; 148 } 149 verifyNetworkAttributesStored(final String l2Key, final NetworkAttributes attributes)150 private void verifyNetworkAttributesStored(final String l2Key, 151 final NetworkAttributes attributes) { 152 // TODO : when storing is implemented, turn this on 153 // verify(mIpMemoryStore).storeNetworkAttributes(eq(l2Key), eq(attributes), any()); 154 } 155 156 @Test testNullInterfaceNameMostDefinitelyThrows()157 public void testNullInterfaceNameMostDefinitelyThrows() throws Exception { 158 setTestInterfaceParams(null); 159 try { 160 final IpClient ipc = new IpClient(mContext, null, mCb, mObserverRegistry, 161 mNetworkStackServiceManager, mDependencies); 162 ipc.shutdown(); 163 fail(); 164 } catch (NullPointerException npe) { 165 // Phew; null interface names not allowed. 166 } 167 } 168 169 @Test testNullCallbackMostDefinitelyThrows()170 public void testNullCallbackMostDefinitelyThrows() throws Exception { 171 final String ifname = "lo"; 172 setTestInterfaceParams(ifname); 173 try { 174 final IpClient ipc = new IpClient(mContext, ifname, null, mObserverRegistry, 175 mNetworkStackServiceManager, mDependencies); 176 ipc.shutdown(); 177 fail(); 178 } catch (NullPointerException npe) { 179 // Phew; null callbacks not allowed. 180 } 181 } 182 183 @Test testInvalidInterfaceDoesNotThrow()184 public void testInvalidInterfaceDoesNotThrow() throws Exception { 185 setTestInterfaceParams(TEST_IFNAME); 186 final IpClient ipc = new IpClient(mContext, TEST_IFNAME, mCb, mObserverRegistry, 187 mNetworkStackServiceManager, mDependencies); 188 verifyNoMoreInteractions(mIpMemoryStore); 189 ipc.shutdown(); 190 } 191 192 @Test testInterfaceNotFoundFailsImmediately()193 public void testInterfaceNotFoundFailsImmediately() throws Exception { 194 setTestInterfaceParams(null); 195 final IpClient ipc = new IpClient(mContext, TEST_IFNAME, mCb, mObserverRegistry, 196 mNetworkStackServiceManager, mDependencies); 197 ipc.startProvisioning(new ProvisioningConfiguration()); 198 verify(mCb, times(1)).onProvisioningFailure(any()); 199 verify(mIpMemoryStore, never()).storeNetworkAttributes(any(), any(), any()); 200 ipc.shutdown(); 201 } 202 203 @Test testDefaultProvisioningConfiguration()204 public void testDefaultProvisioningConfiguration() throws Exception { 205 final String iface = TEST_IFNAME; 206 final IpClient ipc = makeIpClient(iface); 207 208 ProvisioningConfiguration config = new ProvisioningConfiguration.Builder() 209 .withoutIPv4() 210 // TODO: mock IpReachabilityMonitor's dependencies (NetworkInterface, PowerManager) 211 // and enable it in this test 212 .withoutIpReachabilityMonitor() 213 .build(); 214 215 ipc.startProvisioning(config); 216 verify(mCb, times(1)).setNeighborDiscoveryOffload(true); 217 verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).setFallbackMulticastFilter(false); 218 verify(mCb, never()).onProvisioningFailure(any()); 219 verify(mIpMemoryStore, never()).storeNetworkAttributes(any(), any(), any()); 220 221 ipc.shutdown(); 222 verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceSetEnableIPv6(iface, false); 223 verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceClearAddrs(iface); 224 verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)) 225 .onLinkPropertiesChange(makeEmptyLinkProperties(iface)); 226 } 227 228 @Test testProvisioningWithInitialConfiguration()229 public void testProvisioningWithInitialConfiguration() throws Exception { 230 final String iface = TEST_IFNAME; 231 final IpClient ipc = makeIpClient(iface); 232 final String l2Key = TEST_L2KEY; 233 final String groupHint = TEST_GROUPHINT; 234 235 String[] addresses = { 236 "fe80::a4be:f92:e1f7:22d1/64", 237 "fe80::f04a:8f6:6a32:d756/64", 238 "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64" 239 }; 240 String[] prefixes = { "fe80::/64", "fd2c:4e57:8e3c::/64" }; 241 242 ProvisioningConfiguration config = new ProvisioningConfiguration.Builder() 243 .withoutIPv4() 244 .withoutIpReachabilityMonitor() 245 .withInitialConfiguration(conf(links(addresses), prefixes(prefixes), ips())) 246 .build(); 247 248 ipc.startProvisioning(config); 249 verify(mCb, times(1)).setNeighborDiscoveryOffload(true); 250 verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).setFallbackMulticastFilter(false); 251 verify(mCb, never()).onProvisioningFailure(any()); 252 ipc.setL2KeyAndGroupHint(l2Key, groupHint); 253 254 for (String addr : addresses) { 255 String[] parts = addr.split("/"); 256 verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)) 257 .interfaceAddAddress(iface, parts[0], Integer.parseInt(parts[1])); 258 } 259 260 final int lastAddr = addresses.length - 1; 261 262 // Add N - 1 addresses 263 for (int i = 0; i < lastAddr; i++) { 264 mObserver.onInterfaceAddressUpdated(new LinkAddress(addresses[i]), iface); 265 verify(mCb, timeout(TEST_TIMEOUT_MS)).onLinkPropertiesChange(any()); 266 reset(mCb); 267 } 268 269 // Add Nth address 270 mObserver.onInterfaceAddressUpdated(new LinkAddress(addresses[lastAddr]), iface); 271 LinkProperties want = linkproperties(links(addresses), routes(prefixes)); 272 want.setInterfaceName(iface); 273 verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).onProvisioningSuccess(want); 274 verifyNetworkAttributesStored(l2Key, new NetworkAttributes.Builder() 275 .setGroupHint(groupHint) 276 .build()); 277 278 ipc.shutdown(); 279 verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceSetEnableIPv6(iface, false); 280 verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceClearAddrs(iface); 281 verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)) 282 .onLinkPropertiesChange(makeEmptyLinkProperties(iface)); 283 verifyNoMoreInteractions(mIpMemoryStore); 284 } 285 286 @Test testIsProvisioned()287 public void testIsProvisioned() throws Exception { 288 InitialConfiguration empty = conf(links(), prefixes()); 289 IsProvisionedTestCase[] testcases = { 290 // nothing 291 notProvisionedCase(links(), routes(), dns(), null), 292 notProvisionedCase(links(), routes(), dns(), empty), 293 294 // IPv4 295 provisionedCase(links("192.0.2.12/24"), routes(), dns(), empty), 296 297 // IPv6 298 notProvisionedCase( 299 links("fe80::a4be:f92:e1f7:22d1/64", "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"), 300 routes(), dns(), empty), 301 notProvisionedCase( 302 links("fe80::a4be:f92:e1f7:22d1/64", "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"), 303 routes("fe80::/64", "fd2c:4e57:8e3c::/64"), dns("fd00:1234:5678::1000"), empty), 304 provisionedCase( 305 links("2001:db8:dead:beef:f00::a0/64", "fe80::1/64"), 306 routes("::/0"), 307 dns("2001:db8:dead:beef:f00::02"), empty), 308 309 // Initial configuration 310 provisionedCase( 311 links("fe80::e1f7:22d1/64", "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"), 312 routes("fe80::/64", "fd2c:4e57:8e3c::/64"), 313 dns(), 314 conf(links("fe80::e1f7:22d1/64", "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"), 315 prefixes( "fe80::/64", "fd2c:4e57:8e3c::/64"), ips())) 316 }; 317 318 for (IsProvisionedTestCase testcase : testcases) { 319 if (IpClient.isProvisioned(testcase.lp, testcase.config) != testcase.isProvisioned) { 320 fail(testcase.errorMessage()); 321 } 322 } 323 } 324 325 static class IsProvisionedTestCase { 326 boolean isProvisioned; 327 LinkProperties lp; 328 InitialConfiguration config; 329 errorMessage()330 String errorMessage() { 331 return String.format("expected %s with config %s to be %s, but was %s", 332 lp, config, provisioned(isProvisioned), provisioned(!isProvisioned)); 333 } 334 provisioned(boolean isProvisioned)335 static String provisioned(boolean isProvisioned) { 336 return isProvisioned ? "provisioned" : "not provisioned"; 337 } 338 } 339 provisionedCase(Set<LinkAddress> lpAddrs, Set<RouteInfo> lpRoutes, Set<InetAddress> lpDns, InitialConfiguration config)340 static IsProvisionedTestCase provisionedCase(Set<LinkAddress> lpAddrs, Set<RouteInfo> lpRoutes, 341 Set<InetAddress> lpDns, InitialConfiguration config) { 342 return provisioningTest(true, lpAddrs, lpRoutes, lpDns, config); 343 } 344 notProvisionedCase(Set<LinkAddress> lpAddrs, Set<RouteInfo> lpRoutes, Set<InetAddress> lpDns, InitialConfiguration config)345 static IsProvisionedTestCase notProvisionedCase(Set<LinkAddress> lpAddrs, 346 Set<RouteInfo> lpRoutes, Set<InetAddress> lpDns, InitialConfiguration config) { 347 return provisioningTest(false, lpAddrs, lpRoutes, lpDns, config); 348 } 349 provisioningTest(boolean isProvisioned, Set<LinkAddress> lpAddrs, Set<RouteInfo> lpRoutes, Set<InetAddress> lpDns, InitialConfiguration config)350 static IsProvisionedTestCase provisioningTest(boolean isProvisioned, Set<LinkAddress> lpAddrs, 351 Set<RouteInfo> lpRoutes, Set<InetAddress> lpDns, InitialConfiguration config) { 352 IsProvisionedTestCase testcase = new IsProvisionedTestCase(); 353 testcase.isProvisioned = isProvisioned; 354 testcase.lp = new LinkProperties(); 355 testcase.lp.setLinkAddresses(lpAddrs); 356 for (RouteInfo route : lpRoutes) { 357 testcase.lp.addRoute(route); 358 } 359 for (InetAddress dns : lpDns) { 360 testcase.lp.addDnsServer(dns); 361 } 362 testcase.config = config; 363 return testcase; 364 } 365 366 @Test testInitialConfigurations()367 public void testInitialConfigurations() throws Exception { 368 InitialConfigurationTestCase[] testcases = { 369 validConf("valid IPv4 configuration", 370 links("192.0.2.12/24"), prefixes("192.0.2.0/24"), dns("192.0.2.2")), 371 validConf("another valid IPv4 configuration", 372 links("192.0.2.12/24"), prefixes("192.0.2.0/24"), dns()), 373 validConf("valid IPv6 configurations", 374 links("2001:db8:dead:beef:f00::a0/64", "fe80::1/64"), 375 prefixes("2001:db8:dead:beef::/64", "fe80::/64"), 376 dns("2001:db8:dead:beef:f00::02")), 377 validConf("valid IPv6 configurations", 378 links("fe80::1/64"), prefixes("fe80::/64"), dns()), 379 validConf("valid IPv6/v4 configuration", 380 links("2001:db8:dead:beef:f00::a0/48", "192.0.2.12/24"), 381 prefixes("2001:db8:dead:beef::/64", "192.0.2.0/24"), 382 dns("192.0.2.2", "2001:db8:dead:beef:f00::02")), 383 validConf("valid IPv6 configuration without any GUA.", 384 links("fd00:1234:5678::1/48"), 385 prefixes("fd00:1234:5678::/48"), 386 dns("fd00:1234:5678::1000")), 387 388 invalidConf("empty configuration", links(), prefixes(), dns()), 389 invalidConf("v4 addr and dns not in any prefix", 390 links("192.0.2.12/24"), prefixes("198.51.100.0/24"), dns("192.0.2.2")), 391 invalidConf("v4 addr not in any prefix", 392 links("198.51.2.12/24"), prefixes("198.51.100.0/24"), dns("192.0.2.2")), 393 invalidConf("v4 dns addr not in any prefix", 394 links("192.0.2.12/24"), prefixes("192.0.2.0/24"), dns("198.51.100.2")), 395 invalidConf("v6 addr not in any prefix", 396 links("2001:db8:dead:beef:f00::a0/64", "fe80::1/64"), 397 prefixes("2001:db8:dead:beef::/64"), 398 dns("2001:db8:dead:beef:f00::02")), 399 invalidConf("v6 dns addr not in any prefix", 400 links("fe80::1/64"), prefixes("fe80::/64"), dns("2001:db8:dead:beef:f00::02")), 401 invalidConf("default ipv6 route and no GUA", 402 links("fd01:1111:2222:3333::a0/128"), prefixes("::/0"), dns()), 403 invalidConf("invalid v6 prefix length", 404 links("2001:db8:dead:beef:f00::a0/128"), prefixes("2001:db8:dead:beef::/32"), 405 dns()), 406 invalidConf("another invalid v6 prefix length", 407 links("2001:db8:dead:beef:f00::a0/128"), prefixes("2001:db8:dead:beef::/72"), 408 dns()) 409 }; 410 411 for (InitialConfigurationTestCase testcase : testcases) { 412 if (testcase.config.isValid() != testcase.isValid) { 413 fail(testcase.errorMessage()); 414 } 415 } 416 } 417 418 static class InitialConfigurationTestCase { 419 String descr; 420 boolean isValid; 421 InitialConfiguration config; errorMessage()422 public String errorMessage() { 423 return String.format("%s: expected configuration %s to be %s, but was %s", 424 descr, config, validString(isValid), validString(!isValid)); 425 } validString(boolean isValid)426 static String validString(boolean isValid) { 427 return isValid ? VALID : INVALID; 428 } 429 } 430 validConf(String descr, Set<LinkAddress> links, Set<IpPrefix> prefixes, Set<InetAddress> dns)431 static InitialConfigurationTestCase validConf(String descr, Set<LinkAddress> links, 432 Set<IpPrefix> prefixes, Set<InetAddress> dns) { 433 return confTestCase(descr, true, conf(links, prefixes, dns)); 434 } 435 invalidConf(String descr, Set<LinkAddress> links, Set<IpPrefix> prefixes, Set<InetAddress> dns)436 static InitialConfigurationTestCase invalidConf(String descr, Set<LinkAddress> links, 437 Set<IpPrefix> prefixes, Set<InetAddress> dns) { 438 return confTestCase(descr, false, conf(links, prefixes, dns)); 439 } 440 confTestCase( String descr, boolean isValid, InitialConfiguration config)441 static InitialConfigurationTestCase confTestCase( 442 String descr, boolean isValid, InitialConfiguration config) { 443 InitialConfigurationTestCase testcase = new InitialConfigurationTestCase(); 444 testcase.descr = descr; 445 testcase.isValid = isValid; 446 testcase.config = config; 447 return testcase; 448 } 449 linkproperties(Set<LinkAddress> addresses, Set<RouteInfo> routes)450 static LinkProperties linkproperties(Set<LinkAddress> addresses, Set<RouteInfo> routes) { 451 LinkProperties lp = new LinkProperties(); 452 lp.setLinkAddresses(addresses); 453 for (RouteInfo route : routes) { 454 lp.addRoute(route); 455 } 456 return lp; 457 } 458 conf(Set<LinkAddress> links, Set<IpPrefix> prefixes)459 static InitialConfiguration conf(Set<LinkAddress> links, Set<IpPrefix> prefixes) { 460 return conf(links, prefixes, new HashSet<>()); 461 } 462 conf( Set<LinkAddress> links, Set<IpPrefix> prefixes, Set<InetAddress> dns)463 static InitialConfiguration conf( 464 Set<LinkAddress> links, Set<IpPrefix> prefixes, Set<InetAddress> dns) { 465 InitialConfiguration conf = new InitialConfiguration(); 466 conf.ipAddresses.addAll(links); 467 conf.directlyConnectedRoutes.addAll(prefixes); 468 conf.dnsServers.addAll(dns); 469 return conf; 470 } 471 routes(String... routes)472 static Set<RouteInfo> routes(String... routes) { 473 return mapIntoSet(routes, (r) -> new RouteInfo(new IpPrefix(r))); 474 } 475 prefixes(String... prefixes)476 static Set<IpPrefix> prefixes(String... prefixes) { 477 return mapIntoSet(prefixes, IpPrefix::new); 478 } 479 links(String... addresses)480 static Set<LinkAddress> links(String... addresses) { 481 return mapIntoSet(addresses, LinkAddress::new); 482 } 483 ips(String... addresses)484 static Set<InetAddress> ips(String... addresses) { 485 return mapIntoSet(addresses, InetAddress::getByName); 486 } 487 dns(String... addresses)488 static Set<InetAddress> dns(String... addresses) { 489 return ips(addresses); 490 } 491 mapIntoSet(A[] in, Fn<A, B> fn)492 static <A, B> Set<B> mapIntoSet(A[] in, Fn<A, B> fn) { 493 Set<B> out = new HashSet<>(in.length); 494 for (A item : in) { 495 try { 496 out.add(fn.call(item)); 497 } catch (Exception e) { 498 throw new RuntimeException(e); 499 } 500 } 501 return out; 502 } 503 504 interface Fn<A,B> { call(A a)505 B call(A a) throws Exception; 506 } 507 508 @Test testAll()509 public void testAll() { 510 List<String> list1 = Arrays.asList(); 511 List<String> list2 = Arrays.asList("foo"); 512 List<String> list3 = Arrays.asList("bar", "baz"); 513 List<String> list4 = Arrays.asList("foo", "bar", "baz"); 514 515 assertTrue(InitialConfiguration.all(list1, (x) -> false)); 516 assertFalse(InitialConfiguration.all(list2, (x) -> false)); 517 assertTrue(InitialConfiguration.all(list3, (x) -> true)); 518 assertTrue(InitialConfiguration.all(list2, (x) -> x.charAt(0) == 'f')); 519 assertFalse(InitialConfiguration.all(list4, (x) -> x.charAt(0) == 'f')); 520 } 521 522 @Test testAny()523 public void testAny() { 524 List<String> list1 = Arrays.asList(); 525 List<String> list2 = Arrays.asList("foo"); 526 List<String> list3 = Arrays.asList("bar", "baz"); 527 List<String> list4 = Arrays.asList("foo", "bar", "baz"); 528 529 assertFalse(InitialConfiguration.any(list1, (x) -> true)); 530 assertTrue(InitialConfiguration.any(list2, (x) -> true)); 531 assertTrue(InitialConfiguration.any(list2, (x) -> x.charAt(0) == 'f')); 532 assertFalse(InitialConfiguration.any(list3, (x) -> x.charAt(0) == 'f')); 533 assertTrue(InitialConfiguration.any(list4, (x) -> x.charAt(0) == 'f')); 534 } 535 536 @Test testFindAll()537 public void testFindAll() { 538 List<String> list1 = Arrays.asList(); 539 List<String> list2 = Arrays.asList("foo"); 540 List<String> list3 = Arrays.asList("foo", "bar", "baz"); 541 542 assertEquals(list1, IpClient.findAll(list1, (x) -> true)); 543 assertEquals(list1, IpClient.findAll(list3, (x) -> false)); 544 assertEquals(list3, IpClient.findAll(list3, (x) -> true)); 545 assertEquals(list2, IpClient.findAll(list3, (x) -> x.charAt(0) == 'f')); 546 } 547 } 548