blob: d0e58b817e9d4c678376fdfb3a6702e840abf451 [file] [log] [blame]
Chalard Jean8c141bd2018-12-04 20:20:56 +09001/*
2 * Copyright (C) 2018 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
Chalard Jean95213512019-01-30 21:04:58 +090017package com.android.server.connectivity.ipmemorystore;
Chalard Jean8c141bd2018-12-04 20:20:56 +090018
Chalard Jeanbf73e662018-12-27 20:59:41 +090019import static org.junit.Assert.assertEquals;
20import static org.junit.Assert.assertFalse;
21import static org.junit.Assert.assertNull;
Chalard Jean91549b62018-12-18 22:05:19 +090022import static org.junit.Assert.assertTrue;
23import static org.junit.Assert.fail;
Chalard Jean61e27ab2018-12-12 17:56:37 +090024import static org.mockito.ArgumentMatchers.anyString;
25import static org.mockito.Mockito.doReturn;
26
Chalard Jean8c141bd2018-12-04 20:20:56 +090027import android.content.Context;
Chalard Jean91549b62018-12-18 22:05:19 +090028import android.net.ipmemorystore.Blob;
Chalard Jeanbf73e662018-12-27 20:59:41 +090029import android.net.ipmemorystore.IOnBlobRetrievedListener;
Chalard Jean8d1a8902019-01-18 20:21:26 +090030import android.net.ipmemorystore.IOnL2KeyResponseListener;
Chalard Jeanbf73e662018-12-27 20:59:41 +090031import android.net.ipmemorystore.IOnNetworkAttributesRetrieved;
Chalard Jeana39756a2019-01-16 18:18:44 +090032import android.net.ipmemorystore.IOnSameNetworkResponseListener;
Chalard Jean91549b62018-12-18 22:05:19 +090033import android.net.ipmemorystore.IOnStatusListener;
34import android.net.ipmemorystore.NetworkAttributes;
Chalard Jeanbf73e662018-12-27 20:59:41 +090035import android.net.ipmemorystore.NetworkAttributesParcelable;
Chalard Jeana39756a2019-01-16 18:18:44 +090036import android.net.ipmemorystore.SameL3NetworkResponse;
37import android.net.ipmemorystore.SameL3NetworkResponseParcelable;
Chalard Jean91549b62018-12-18 22:05:19 +090038import android.net.ipmemorystore.Status;
39import android.net.ipmemorystore.StatusParcelable;
40import android.os.IBinder;
41import android.os.RemoteException;
Brett Chabot1ae2aa62019-03-04 14:14:56 -080042
43import androidx.test.InstrumentationRegistry;
44import androidx.test.filters.SmallTest;
45import androidx.test.runner.AndroidJUnit4;
Chalard Jean8c141bd2018-12-04 20:20:56 +090046
Chalard Jean91549b62018-12-18 22:05:19 +090047import org.junit.After;
Chalard Jean8c141bd2018-12-04 20:20:56 +090048import org.junit.Before;
49import org.junit.Test;
50import org.junit.runner.RunWith;
51import org.mockito.Mock;
52import org.mockito.MockitoAnnotations;
53
Chalard Jean61e27ab2018-12-12 17:56:37 +090054import java.io.File;
Chalard Jeanbf73e662018-12-27 20:59:41 +090055import java.lang.reflect.Modifier;
Chalard Jean91549b62018-12-18 22:05:19 +090056import java.net.Inet4Address;
Chalard Jeanbf73e662018-12-27 20:59:41 +090057import java.net.Inet6Address;
58import java.net.InetAddress;
Chalard Jean91549b62018-12-18 22:05:19 +090059import java.net.UnknownHostException;
Chalard Jeanbf73e662018-12-27 20:59:41 +090060import java.util.Arrays;
Chalard Jean91549b62018-12-18 22:05:19 +090061import java.util.concurrent.CountDownLatch;
62import java.util.concurrent.TimeUnit;
63import java.util.function.Consumer;
Chalard Jean61e27ab2018-12-12 17:56:37 +090064
Chalard Jean91549b62018-12-18 22:05:19 +090065/** Unit tests for {@link IpMemoryStoreService}. */
Chalard Jean8c141bd2018-12-04 20:20:56 +090066@SmallTest
67@RunWith(AndroidJUnit4.class)
68public class IpMemoryStoreServiceTest {
Chalard Jean91549b62018-12-18 22:05:19 +090069 private static final String TEST_CLIENT_ID = "testClientId";
70 private static final String TEST_DATA_NAME = "testData";
71
Chalard Jean8d1a8902019-01-18 20:21:26 +090072 private static final int FAKE_KEY_COUNT = 20;
73 private static final String[] FAKE_KEYS;
74 static {
75 FAKE_KEYS = new String[FAKE_KEY_COUNT];
76 for (int i = 0; i < FAKE_KEYS.length; ++i) {
77 FAKE_KEYS[i] = "fakeKey" + i;
78 }
79 }
Chalard Jeanb67e4932019-01-16 23:05:10 +090080
Chalard Jean8c141bd2018-12-04 20:20:56 +090081 @Mock
Chalard Jean91549b62018-12-18 22:05:19 +090082 private Context mMockContext;
83 private File mDbFile;
84
85 private IpMemoryStoreService mService;
Chalard Jean8c141bd2018-12-04 20:20:56 +090086
87 @Before
88 public void setUp() {
89 MockitoAnnotations.initMocks(this);
Chalard Jean91549b62018-12-18 22:05:19 +090090 final Context context = InstrumentationRegistry.getContext();
91 final File dir = context.getFilesDir();
92 mDbFile = new File(dir, "test.db");
93 doReturn(mDbFile).when(mMockContext).getDatabasePath(anyString());
94 mService = new IpMemoryStoreService(mMockContext);
95 }
96
97 @After
98 public void tearDown() {
99 mService.shutdown();
100 mDbFile.delete();
101 }
102
103 /** Helper method to make a vanilla IOnStatusListener */
104 private IOnStatusListener onStatus(Consumer<Status> functor) {
105 return new IOnStatusListener() {
106 @Override
107 public void onComplete(final StatusParcelable statusParcelable) throws RemoteException {
108 functor.accept(new Status(statusParcelable));
109 }
110
111 @Override
112 public IBinder asBinder() {
113 return null;
114 }
115 };
Chalard Jean8c141bd2018-12-04 20:20:56 +0900116 }
117
Chalard Jeanbf73e662018-12-27 20:59:41 +0900118 /** Helper method to make an IOnBlobRetrievedListener */
119 private interface OnBlobRetrievedListener {
120 void onBlobRetrieved(Status status, String l2Key, String name, byte[] data);
121 }
122 private IOnBlobRetrievedListener onBlobRetrieved(final OnBlobRetrievedListener functor) {
123 return new IOnBlobRetrievedListener() {
124 @Override
125 public void onBlobRetrieved(final StatusParcelable statusParcelable,
126 final String l2Key, final String name, final Blob blob) throws RemoteException {
127 functor.onBlobRetrieved(new Status(statusParcelable), l2Key, name,
128 null == blob ? null : blob.data);
129 }
130
131 @Override
132 public IBinder asBinder() {
133 return null;
134 }
135 };
136 }
137
138 /** Helper method to make an IOnNetworkAttributesRetrievedListener */
139 private interface OnNetworkAttributesRetrievedListener {
140 void onNetworkAttributesRetrieved(Status status, String l2Key, NetworkAttributes attr);
141 }
142 private IOnNetworkAttributesRetrieved onNetworkAttributesRetrieved(
143 final OnNetworkAttributesRetrievedListener functor) {
144 return new IOnNetworkAttributesRetrieved() {
145 @Override
Chalard Jeanb67e4932019-01-16 23:05:10 +0900146 public void onNetworkAttributesRetrieved(final StatusParcelable status,
147 final String l2Key, final NetworkAttributesParcelable attributes)
Chalard Jeanbf73e662018-12-27 20:59:41 +0900148 throws RemoteException {
149 functor.onNetworkAttributesRetrieved(new Status(status), l2Key,
150 null == attributes ? null : new NetworkAttributes(attributes));
151 }
152
153 @Override
154 public IBinder asBinder() {
155 return null;
156 }
157 };
158 }
159
Chalard Jeana39756a2019-01-16 18:18:44 +0900160 /** Helper method to make an IOnSameNetworkResponseListener */
161 private interface OnSameNetworkResponseListener {
162 void onSameNetworkResponse(Status status, SameL3NetworkResponse answer);
163 }
164 private IOnSameNetworkResponseListener onSameResponse(
165 final OnSameNetworkResponseListener functor) {
166 return new IOnSameNetworkResponseListener() {
167 @Override
168 public void onSameNetworkResponse(final StatusParcelable status,
169 final SameL3NetworkResponseParcelable sameL3Network)
170 throws RemoteException {
171 functor.onSameNetworkResponse(new Status(status),
172 null == sameL3Network ? null : new SameL3NetworkResponse(sameL3Network));
173 }
174
175 @Override
176 public IBinder asBinder() {
177 return null;
178 }
179 };
180 }
181
Chalard Jean8d1a8902019-01-18 20:21:26 +0900182 /** Helper method to make an IOnL2KeyResponseListener */
183 private interface OnL2KeyResponseListener {
184 void onL2KeyResponse(Status status, String key);
185 }
186 private IOnL2KeyResponseListener onL2KeyResponse(final OnL2KeyResponseListener functor) {
187 return new IOnL2KeyResponseListener() {
188 @Override
189 public void onL2KeyResponse(final StatusParcelable status, final String key)
190 throws RemoteException {
191 functor.onL2KeyResponse(new Status(status), key);
192 }
193
194 @Override
195 public IBinder asBinder() {
196 return null;
197 }
198 };
199 }
200
Chalard Jeanbf73e662018-12-27 20:59:41 +0900201 // Helper method to factorize some boilerplate
202 private void doLatched(final String timeoutMessage, final Consumer<CountDownLatch> functor) {
203 final CountDownLatch latch = new CountDownLatch(1);
204 functor.accept(latch);
205 try {
Chalard Jeanf735efc2019-01-24 19:34:39 +0900206 if (!latch.await(5000, TimeUnit.MILLISECONDS)) {
207 fail(timeoutMessage);
208 }
Chalard Jeanbf73e662018-12-27 20:59:41 +0900209 } catch (InterruptedException e) {
Chalard Jeanf735efc2019-01-24 19:34:39 +0900210 fail("Thread was interrupted");
Chalard Jeanbf73e662018-12-27 20:59:41 +0900211 }
212 }
213
Chalard Jeana39756a2019-01-16 18:18:44 +0900214 // Helper methods to factorize more boilerplate
215 private void storeAttributes(final String l2Key, final NetworkAttributes na) {
216 storeAttributes("Did not complete storing attributes", l2Key, na);
217 }
218 private void storeAttributes(final String timeoutMessage, final String l2Key,
219 final NetworkAttributes na) {
220 doLatched(timeoutMessage, latch -> mService.storeNetworkAttributes(l2Key, na.toParcelable(),
221 onStatus(status -> {
222 assertTrue("Store not successful : " + status.resultCode, status.isSuccess());
223 latch.countDown();
224 })));
225 }
226
Chalard Jean8c141bd2018-12-04 20:20:56 +0900227 @Test
Chalard Jean8d1a8902019-01-18 20:21:26 +0900228 public void testNetworkAttributes() throws UnknownHostException {
Chalard Jean91549b62018-12-18 22:05:19 +0900229 final NetworkAttributes.Builder na = new NetworkAttributes.Builder();
Chalard Jean8d1a8902019-01-18 20:21:26 +0900230 na.setAssignedV4Address((Inet4Address) Inet4Address.getByName("1.2.3.4"));
Chalard Jean91549b62018-12-18 22:05:19 +0900231 na.setGroupHint("hint1");
232 na.setMtu(219);
Chalard Jeanb67e4932019-01-16 23:05:10 +0900233 final String l2Key = FAKE_KEYS[0];
Chalard Jeanbf73e662018-12-27 20:59:41 +0900234 NetworkAttributes attributes = na.build();
Chalard Jeana39756a2019-01-16 18:18:44 +0900235 storeAttributes(l2Key, attributes);
Chalard Jeanbf73e662018-12-27 20:59:41 +0900236
237 doLatched("Did not complete retrieving attributes", latch ->
238 mService.retrieveNetworkAttributes(l2Key, onNetworkAttributesRetrieved(
239 (status, key, attr) -> {
240 assertTrue("Retrieve network attributes not successful : "
241 + status.resultCode, status.isSuccess());
242 assertEquals(l2Key, key);
243 assertEquals(attributes, attr);
244 latch.countDown();
245 })));
246
247 final NetworkAttributes.Builder na2 = new NetworkAttributes.Builder();
Chalard Jean8d1a8902019-01-18 20:21:26 +0900248 na.setDnsAddresses(Arrays.asList(
249 new InetAddress[] {Inet6Address.getByName("0A1C:2E40:480A::1CA6")}));
Chalard Jeanbf73e662018-12-27 20:59:41 +0900250 final NetworkAttributes attributes2 = na2.build();
Chalard Jeana39756a2019-01-16 18:18:44 +0900251 storeAttributes("Did not complete storing attributes 2", l2Key, attributes2);
Chalard Jeanbf73e662018-12-27 20:59:41 +0900252
253 doLatched("Did not complete retrieving attributes 2", latch ->
254 mService.retrieveNetworkAttributes(l2Key, onNetworkAttributesRetrieved(
255 (status, key, attr) -> {
256 assertTrue("Retrieve network attributes not successful : "
257 + status.resultCode, status.isSuccess());
258 assertEquals(l2Key, key);
259 assertEquals(attributes.assignedV4Address, attr.assignedV4Address);
260 assertEquals(attributes.groupHint, attr.groupHint);
261 assertEquals(attributes.mtu, attr.mtu);
262 assertEquals(attributes2.dnsAddresses, attr.dnsAddresses);
263 latch.countDown();
264 })));
265
266 doLatched("Did not complete retrieving attributes 3", latch ->
267 mService.retrieveNetworkAttributes(l2Key + "nonexistent",
268 onNetworkAttributesRetrieved(
269 (status, key, attr) -> {
270 assertTrue("Retrieve network attributes not successful : "
271 + status.resultCode, status.isSuccess());
272 assertEquals(l2Key + "nonexistent", key);
273 assertNull("Retrieved data not stored", attr);
274 latch.countDown();
275 }
276 )));
277
278 // Verify that this test does not miss any new field added later.
279 // If any field is added to NetworkAttributes it must be tested here for storing
280 // and retrieving.
281 assertEquals(4, Arrays.stream(NetworkAttributes.class.getDeclaredFields())
282 .filter(f -> !Modifier.isStatic(f.getModifiers())).count());
283 }
284
285 @Test
286 public void testInvalidAttributes() {
287 doLatched("Did not complete storing bad attributes", latch ->
288 mService.storeNetworkAttributes("key", null, onStatus(status -> {
289 assertFalse("Success storing on a null key",
290 status.isSuccess());
291 assertEquals(Status.ERROR_ILLEGAL_ARGUMENT, status.resultCode);
292 latch.countDown();
293 })));
294
295 final NetworkAttributes na = new NetworkAttributes.Builder().setMtu(2).build();
296 doLatched("Did not complete storing bad attributes", latch ->
297 mService.storeNetworkAttributes(null, na.toParcelable(), onStatus(status -> {
298 assertFalse("Success storing null attributes on a null key",
299 status.isSuccess());
300 assertEquals(Status.ERROR_ILLEGAL_ARGUMENT, status.resultCode);
301 latch.countDown();
302 })));
303
304 doLatched("Did not complete storing bad attributes", latch ->
305 mService.storeNetworkAttributes(null, null, onStatus(status -> {
306 assertFalse("Success storing null attributes on a null key",
307 status.isSuccess());
308 assertEquals(Status.ERROR_ILLEGAL_ARGUMENT, status.resultCode);
309 latch.countDown();
310 })));
311
312 doLatched("Did not complete retrieving bad attributes", latch ->
313 mService.retrieveNetworkAttributes(null, onNetworkAttributesRetrieved(
314 (status, key, attr) -> {
315 assertFalse("Success retrieving attributes for a null key",
316 status.isSuccess());
317 assertEquals(Status.ERROR_ILLEGAL_ARGUMENT, status.resultCode);
318 assertNull(key);
319 assertNull(attr);
Chalard Jeanf735efc2019-01-24 19:34:39 +0900320 latch.countDown();
Chalard Jeanbf73e662018-12-27 20:59:41 +0900321 })));
Chalard Jeanf89d7be2018-12-07 23:09:02 +0900322 }
323
324 @Test
325 public void testPrivateData() {
Chalard Jean91549b62018-12-18 22:05:19 +0900326 final Blob b = new Blob();
327 b.data = new byte[] { -3, 6, 8, -9, 12, -128, 0, 89, 112, 91, -34 };
Chalard Jeanb67e4932019-01-16 23:05:10 +0900328 final String l2Key = FAKE_KEYS[0];
Chalard Jeanbf73e662018-12-27 20:59:41 +0900329 doLatched("Did not complete storing private data", latch ->
330 mService.storeBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME, b,
331 onStatus(status -> {
332 assertTrue("Store status not successful : " + status.resultCode,
333 status.isSuccess());
334 latch.countDown();
335 })));
336
337 doLatched("Did not complete retrieving private data", latch ->
338 mService.retrieveBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME, onBlobRetrieved(
339 (status, key, name, data) -> {
340 assertTrue("Retrieve blob status not successful : " + status.resultCode,
341 status.isSuccess());
342 assertEquals(l2Key, key);
343 assertEquals(name, TEST_DATA_NAME);
344 Arrays.equals(b.data, data);
345 latch.countDown();
346 })));
347
348 // Most puzzling error message ever
349 doLatched("Did not complete retrieving nothing", latch ->
350 mService.retrieveBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME + "2", onBlobRetrieved(
351 (status, key, name, data) -> {
352 assertTrue("Retrieve blob status not successful : " + status.resultCode,
353 status.isSuccess());
354 assertEquals(l2Key, key);
355 assertEquals(name, TEST_DATA_NAME + "2");
356 assertNull(data);
357 latch.countDown();
358 })));
Chalard Jeanf89d7be2018-12-07 23:09:02 +0900359 }
360
361 @Test
Chalard Jean8d1a8902019-01-18 20:21:26 +0900362 public void testFindL2Key() throws UnknownHostException {
363 final NetworkAttributes.Builder na = new NetworkAttributes.Builder();
364 na.setGroupHint("hint0");
365 storeAttributes(FAKE_KEYS[0], na.build());
366
367 na.setDnsAddresses(Arrays.asList(
368 new InetAddress[] {Inet6Address.getByName("8D56:9AF1::08EE:20F1")}));
369 na.setMtu(219);
370 storeAttributes(FAKE_KEYS[1], na.build());
371 na.setMtu(null);
372 na.setAssignedV4Address((Inet4Address) Inet4Address.getByName("1.2.3.4"));
373 na.setDnsAddresses(Arrays.asList(
374 new InetAddress[] {Inet6Address.getByName("0A1C:2E40:480A::1CA6")}));
375 na.setGroupHint("hint1");
376 storeAttributes(FAKE_KEYS[2], na.build());
377 na.setMtu(219);
378 storeAttributes(FAKE_KEYS[3], na.build());
379 na.setMtu(240);
380 storeAttributes(FAKE_KEYS[4], na.build());
381 na.setAssignedV4Address((Inet4Address) Inet4Address.getByName("5.6.7.8"));
382 storeAttributes(FAKE_KEYS[5], na.build());
383
384 // Matches key 5 exactly
385 doLatched("Did not finish finding L2Key", latch ->
386 mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
387 assertTrue("Retrieve network sameness not successful : " + status.resultCode,
388 status.isSuccess());
389 assertEquals(FAKE_KEYS[5], key);
Chalard Jeanf735efc2019-01-24 19:34:39 +0900390 latch.countDown();
Chalard Jean8d1a8902019-01-18 20:21:26 +0900391 })));
392
393 // MTU matches key 4 but v4 address matches key 5. The latter is stronger.
394 na.setMtu(240);
395 doLatched("Did not finish finding L2Key", latch ->
396 mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
397 assertTrue("Retrieve network sameness not successful : " + status.resultCode,
398 status.isSuccess());
399 assertEquals(FAKE_KEYS[5], key);
Chalard Jeanf735efc2019-01-24 19:34:39 +0900400 latch.countDown();
Chalard Jean8d1a8902019-01-18 20:21:26 +0900401 })));
402
403 // Closest to key 3 (indeed, identical)
404 na.setAssignedV4Address((Inet4Address) Inet4Address.getByName("1.2.3.4"));
405 na.setMtu(219);
406 doLatched("Did not finish finding L2Key", latch ->
407 mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
408 assertTrue("Retrieve network sameness not successful : " + status.resultCode,
409 status.isSuccess());
410 assertEquals(FAKE_KEYS[3], key);
Chalard Jeanf735efc2019-01-24 19:34:39 +0900411 latch.countDown();
Chalard Jean8d1a8902019-01-18 20:21:26 +0900412 })));
413
414 // Group hint alone must not be strong enough to override the rest
415 na.setGroupHint("hint0");
416 doLatched("Did not finish finding L2Key", latch ->
417 mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
418 assertTrue("Retrieve network sameness not successful : " + status.resultCode,
419 status.isSuccess());
420 assertEquals(FAKE_KEYS[3], key);
Chalard Jeanf735efc2019-01-24 19:34:39 +0900421 latch.countDown();
Chalard Jean8d1a8902019-01-18 20:21:26 +0900422 })));
423
424 // Still closest to key 3, though confidence is lower
425 na.setGroupHint("hint1");
426 na.setDnsAddresses(null);
427 doLatched("Did not finish finding L2Key", latch ->
428 mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
429 assertTrue("Retrieve network sameness not successful : " + status.resultCode,
430 status.isSuccess());
431 assertEquals(FAKE_KEYS[3], key);
Chalard Jeanf735efc2019-01-24 19:34:39 +0900432 latch.countDown();
Chalard Jean8d1a8902019-01-18 20:21:26 +0900433 })));
434
435 // But changing the MTU makes this closer to key 4
436 na.setMtu(240);
437 doLatched("Did not finish finding L2Key", latch ->
438 mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
439 assertTrue("Retrieve network sameness not successful : " + status.resultCode,
440 status.isSuccess());
441 assertEquals(FAKE_KEYS[4], key);
Chalard Jeanf735efc2019-01-24 19:34:39 +0900442 latch.countDown();
Chalard Jean8d1a8902019-01-18 20:21:26 +0900443 })));
444
445 // MTU alone not strong enough to make this group-close
446 na.setGroupHint(null);
447 na.setDnsAddresses(null);
448 na.setAssignedV4Address(null);
449 doLatched("Did not finish finding L2Key", latch ->
450 mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
451 assertTrue("Retrieve network sameness not successful : " + status.resultCode,
452 status.isSuccess());
453 assertNull(key);
Chalard Jeanf735efc2019-01-24 19:34:39 +0900454 latch.countDown();
Chalard Jean8d1a8902019-01-18 20:21:26 +0900455 })));
Chalard Jeanf89d7be2018-12-07 23:09:02 +0900456 }
457
Chalard Jeana39756a2019-01-16 18:18:44 +0900458 private void assertNetworksSameness(final String key1, final String key2, final int sameness) {
459 doLatched("Did not finish evaluating sameness", latch ->
460 mService.isSameNetwork(key1, key2, onSameResponse((status, answer) -> {
461 assertTrue("Retrieve network sameness not successful : " + status.resultCode,
462 status.isSuccess());
463 assertEquals(sameness, answer.getNetworkSameness());
Chalard Jeanf735efc2019-01-24 19:34:39 +0900464 latch.countDown();
Chalard Jeana39756a2019-01-16 18:18:44 +0900465 })));
466 }
467
Chalard Jeanf89d7be2018-12-07 23:09:02 +0900468 @Test
Chalard Jeana39756a2019-01-16 18:18:44 +0900469 public void testIsSameNetwork() throws UnknownHostException {
470 final NetworkAttributes.Builder na = new NetworkAttributes.Builder();
Chalard Jean8d1a8902019-01-18 20:21:26 +0900471 na.setAssignedV4Address((Inet4Address) Inet4Address.getByName("1.2.3.4"));
Chalard Jeana39756a2019-01-16 18:18:44 +0900472 na.setGroupHint("hint1");
473 na.setMtu(219);
474 na.setDnsAddresses(Arrays.asList(Inet6Address.getByName("0A1C:2E40:480A::1CA6")));
475
Chalard Jeanb67e4932019-01-16 23:05:10 +0900476 storeAttributes(FAKE_KEYS[0], na.build());
Chalard Jeana39756a2019-01-16 18:18:44 +0900477 // 0 and 1 have identical attributes
Chalard Jeanb67e4932019-01-16 23:05:10 +0900478 storeAttributes(FAKE_KEYS[1], na.build());
Chalard Jeana39756a2019-01-16 18:18:44 +0900479
480 // Hopefully only the MTU being different still means it's the same network
481 na.setMtu(200);
Chalard Jeanb67e4932019-01-16 23:05:10 +0900482 storeAttributes(FAKE_KEYS[2], na.build());
Chalard Jeana39756a2019-01-16 18:18:44 +0900483
484 // Hopefully different MTU, assigned V4 address and grouphint make a different network,
485 // even with identical DNS addresses
486 na.setAssignedV4Address(null);
487 na.setGroupHint("hint2");
Chalard Jeanb67e4932019-01-16 23:05:10 +0900488 storeAttributes(FAKE_KEYS[3], na.build());
Chalard Jeana39756a2019-01-16 18:18:44 +0900489
Chalard Jeanb67e4932019-01-16 23:05:10 +0900490 assertNetworksSameness(FAKE_KEYS[0], FAKE_KEYS[1], SameL3NetworkResponse.NETWORK_SAME);
491 assertNetworksSameness(FAKE_KEYS[0], FAKE_KEYS[2], SameL3NetworkResponse.NETWORK_SAME);
492 assertNetworksSameness(FAKE_KEYS[1], FAKE_KEYS[2], SameL3NetworkResponse.NETWORK_SAME);
493 assertNetworksSameness(FAKE_KEYS[0], FAKE_KEYS[3], SameL3NetworkResponse.NETWORK_DIFFERENT);
494 assertNetworksSameness(FAKE_KEYS[0], "neverInsertedKey",
Chalard Jeana39756a2019-01-16 18:18:44 +0900495 SameL3NetworkResponse.NETWORK_NEVER_CONNECTED);
496
497 doLatched("Did not finish evaluating sameness", latch ->
498 mService.isSameNetwork(null, null, onSameResponse((status, answer) -> {
499 assertFalse("Retrieve network sameness suspiciously successful : "
500 + status.resultCode, status.isSuccess());
501 assertEquals(Status.ERROR_ILLEGAL_ARGUMENT, status.resultCode);
502 assertNull(answer);
Chalard Jeanf735efc2019-01-24 19:34:39 +0900503 latch.countDown();
Chalard Jeana39756a2019-01-16 18:18:44 +0900504 })));
Chalard Jean8c141bd2018-12-04 20:20:56 +0900505 }
506}