From a39756a58a906f99204d967dee5aa1ca51744b4d Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Wed, 16 Jan 2019 18:18:44 +0900 Subject: [MS09] Implement isSameNetwork. Test: Old tests pass, new tests pass too. Bug: 113554482 Change-Id: I420471853f3fab7725cba7ae500cebdce1912e43 --- .../ipmemorystore/IpMemoryStoreServiceTest.java | 100 ++++++++++++++++++--- .../net/ipmemorystore/NetworkAttributesTest.java | 65 ++++++++++++++ 2 files changed, 153 insertions(+), 12 deletions(-) create mode 100644 tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java (limited to 'tests') diff --git a/tests/net/java/com/android/server/net/ipmemorystore/IpMemoryStoreServiceTest.java b/tests/net/java/com/android/server/net/ipmemorystore/IpMemoryStoreServiceTest.java index 94bcd28bf009..c58941a5719b 100644 --- a/tests/net/java/com/android/server/net/ipmemorystore/IpMemoryStoreServiceTest.java +++ b/tests/net/java/com/android/server/net/ipmemorystore/IpMemoryStoreServiceTest.java @@ -28,9 +28,12 @@ import android.content.Context; import android.net.ipmemorystore.Blob; import android.net.ipmemorystore.IOnBlobRetrievedListener; import android.net.ipmemorystore.IOnNetworkAttributesRetrieved; +import android.net.ipmemorystore.IOnSameNetworkResponseListener; import android.net.ipmemorystore.IOnStatusListener; import android.net.ipmemorystore.NetworkAttributes; import android.net.ipmemorystore.NetworkAttributesParcelable; +import android.net.ipmemorystore.SameL3NetworkResponse; +import android.net.ipmemorystore.SameL3NetworkResponseParcelable; import android.net.ipmemorystore.Status; import android.net.ipmemorystore.StatusParcelable; import android.os.IBinder; @@ -144,6 +147,28 @@ public class IpMemoryStoreServiceTest { }; } + /** Helper method to make an IOnSameNetworkResponseListener */ + private interface OnSameNetworkResponseListener { + void onSameNetworkResponse(Status status, SameL3NetworkResponse answer); + } + private IOnSameNetworkResponseListener onSameResponse( + final OnSameNetworkResponseListener functor) { + return new IOnSameNetworkResponseListener() { + @Override + public void onSameNetworkResponse(final StatusParcelable status, + final SameL3NetworkResponseParcelable sameL3Network) + throws RemoteException { + functor.onSameNetworkResponse(new Status(status), + null == sameL3Network ? null : new SameL3NetworkResponse(sameL3Network)); + } + + @Override + public IBinder asBinder() { + return null; + } + }; + } + // Helper method to factorize some boilerplate private void doLatched(final String timeoutMessage, final Consumer functor) { final CountDownLatch latch = new CountDownLatch(1); @@ -155,6 +180,19 @@ public class IpMemoryStoreServiceTest { } } + // Helper methods to factorize more boilerplate + private void storeAttributes(final String l2Key, final NetworkAttributes na) { + storeAttributes("Did not complete storing attributes", l2Key, na); + } + private void storeAttributes(final String timeoutMessage, final String l2Key, + final NetworkAttributes na) { + doLatched(timeoutMessage, latch -> mService.storeNetworkAttributes(l2Key, na.toParcelable(), + onStatus(status -> { + assertTrue("Store not successful : " + status.resultCode, status.isSuccess()); + latch.countDown(); + }))); + } + @Test public void testNetworkAttributes() { final NetworkAttributes.Builder na = new NetworkAttributes.Builder(); @@ -166,13 +204,7 @@ public class IpMemoryStoreServiceTest { na.setMtu(219); final String l2Key = UUID.randomUUID().toString(); NetworkAttributes attributes = na.build(); - doLatched("Did not complete storing attributes", latch -> - mService.storeNetworkAttributes(l2Key, attributes.toParcelable(), - onStatus(status -> { - assertTrue("Store status not successful : " + status.resultCode, - status.isSuccess()); - latch.countDown(); - }))); + storeAttributes(l2Key, attributes); doLatched("Did not complete retrieving attributes", latch -> mService.retrieveNetworkAttributes(l2Key, onNetworkAttributesRetrieved( @@ -190,9 +222,7 @@ public class IpMemoryStoreServiceTest { new InetAddress[] {Inet6Address.getByName("0A1C:2E40:480A::1CA6")})); } catch (UnknownHostException e) { /* Still can't happen */ } final NetworkAttributes attributes2 = na2.build(); - doLatched("Did not complete storing attributes 2", latch -> - mService.storeNetworkAttributes(l2Key, attributes2.toParcelable(), - onStatus(status -> latch.countDown()))); + storeAttributes("Did not complete storing attributes 2", l2Key, attributes2); doLatched("Did not complete retrieving attributes 2", latch -> mService.retrieveNetworkAttributes(l2Key, onNetworkAttributesRetrieved( @@ -306,8 +336,54 @@ public class IpMemoryStoreServiceTest { // TODO : implement this } + private void assertNetworksSameness(final String key1, final String key2, final int sameness) { + doLatched("Did not finish evaluating sameness", latch -> + mService.isSameNetwork(key1, key2, onSameResponse((status, answer) -> { + assertTrue("Retrieve network sameness not successful : " + status.resultCode, + status.isSuccess()); + assertEquals(sameness, answer.getNetworkSameness()); + }))); + } + @Test - public void testIsSameNetwork() { - // TODO : implement this + public void testIsSameNetwork() throws UnknownHostException { + final NetworkAttributes.Builder na = new NetworkAttributes.Builder(); + na.setAssignedV4Address((Inet4Address) Inet4Address.getByAddress(new byte[]{1, 2, 3, 4})); + na.setGroupHint("hint1"); + na.setMtu(219); + na.setDnsAddresses(Arrays.asList(Inet6Address.getByName("0A1C:2E40:480A::1CA6"))); + + final String[] keys = new String[4]; + for (int i = 0; i < keys.length; ++i) { + keys[i] = UUID.randomUUID().toString(); + } + storeAttributes(keys[0], na.build()); + // 0 and 1 have identical attributes + storeAttributes(keys[1], na.build()); + + // Hopefully only the MTU being different still means it's the same network + na.setMtu(200); + storeAttributes(keys[2], na.build()); + + // Hopefully different MTU, assigned V4 address and grouphint make a different network, + // even with identical DNS addresses + na.setAssignedV4Address(null); + na.setGroupHint("hint2"); + storeAttributes(keys[3], na.build()); + + assertNetworksSameness(keys[0], keys[1], SameL3NetworkResponse.NETWORK_SAME); + assertNetworksSameness(keys[0], keys[2], SameL3NetworkResponse.NETWORK_SAME); + assertNetworksSameness(keys[1], keys[2], SameL3NetworkResponse.NETWORK_SAME); + assertNetworksSameness(keys[0], keys[3], SameL3NetworkResponse.NETWORK_DIFFERENT); + assertNetworksSameness(keys[0], UUID.randomUUID().toString(), + SameL3NetworkResponse.NETWORK_NEVER_CONNECTED); + + doLatched("Did not finish evaluating sameness", latch -> + mService.isSameNetwork(null, null, onSameResponse((status, answer) -> { + assertFalse("Retrieve network sameness suspiciously successful : " + + status.resultCode, status.isSuccess()); + assertEquals(Status.ERROR_ILLEGAL_ARGUMENT, status.resultCode); + assertNull(answer); + }))); } } diff --git a/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java b/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java new file mode 100644 index 000000000000..fe19eee4594c --- /dev/null +++ b/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.net.ipmemorystore; + +import static org.junit.Assert.assertEquals; + +import android.net.ipmemorystore.NetworkAttributes; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.lang.reflect.Field; +import java.net.Inet4Address; +import java.net.UnknownHostException; +import java.util.Arrays; + +/** Unit tests for {@link NetworkAttributes}. */ +@SmallTest +@RunWith(AndroidJUnit4.class) +public class NetworkAttributesTest { + private static final String WEIGHT_FIELD_NAME_PREFIX = "WEIGHT_"; + private static final float EPSILON = 0.0001f; + + // This is running two tests to make sure the total weight is the sum of all weights. To be + // sure this is not fireproof, but you'd kind of need to do it on purpose to pass. + @Test + public void testTotalWeight() throws IllegalAccessException, UnknownHostException { + // Make sure that TOTAL_WEIGHT is equal to the sum of the fields starting with WEIGHT_ + float sum = 0f; + final Field[] fieldList = NetworkAttributes.class.getDeclaredFields(); + for (final Field field : fieldList) { + if (!field.getName().startsWith(WEIGHT_FIELD_NAME_PREFIX)) continue; + field.setAccessible(true); + sum += (float) field.get(null); + } + assertEquals(sum, NetworkAttributes.TOTAL_WEIGHT, EPSILON); + + // Use directly the constructor with all attributes, and make sure that when compared + // to itself the score is a clean 1.0f. + final NetworkAttributes na = + new NetworkAttributes( + (Inet4Address) Inet4Address.getByAddress(new byte[] {1, 2, 3, 4}), + "some hint", + Arrays.asList(Inet4Address.getByAddress(new byte[] {5, 6, 7, 8}), + Inet4Address.getByAddress(new byte[] {9, 0, 1, 2})), + 98); + assertEquals(1.0f, na.getNetworkGroupSamenessConfidence(na), EPSILON); + } +} -- cgit v1.2.3-59-g8ed1b From b67e4936533e91e999673f5c46585a95ee211ac2 Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Wed, 16 Jan 2019 23:05:10 +0900 Subject: [MS10] Address leftover comments on MS03 and MS07 - Fix the copyright year in IPMSDatabase.java. - Add missing Override annotations. - Remove random l2keys, use fixed strings. - Rename the method in OnNetworkAttributesRetrieved that puzzlingly nobody noticed was wrong. Test: atest IpMemoryStoreServiceTest Bug: 113554482 Change-Id: If71fadd23e158a4be299d112bfce75690b1ed8e8 --- .../IOnNetworkAttributesRetrieved.aidl | 2 +- .../net/ipmemorystore/IpMemoryStoreDatabase.java | 15 ++++++++-- .../net/ipmemorystore/IpMemoryStoreService.java | 11 ++++---- .../ipmemorystore/IpMemoryStoreServiceTest.java | 33 ++++++++++------------ 4 files changed, 34 insertions(+), 27 deletions(-) (limited to 'tests') diff --git a/core/java/android/net/ipmemorystore/IOnNetworkAttributesRetrieved.aidl b/core/java/android/net/ipmemorystore/IOnNetworkAttributesRetrieved.aidl index 57f59a17cfe7..fb4ca3b97895 100644 --- a/core/java/android/net/ipmemorystore/IOnNetworkAttributesRetrieved.aidl +++ b/core/java/android/net/ipmemorystore/IOnNetworkAttributesRetrieved.aidl @@ -25,6 +25,6 @@ oneway interface IOnNetworkAttributesRetrieved { * Network attributes were fetched for the specified L2 key. While the L2 key will never * be null, the attributes may be if no data is stored about this L2 key. */ - void onL2KeyResponse(in StatusParcelable status, in String l2Key, + void onNetworkAttributesRetrieved(in StatusParcelable status, in String l2Key, in NetworkAttributesParcelable attributes); } diff --git a/services/ipmemorystore/java/com/android/server/net/ipmemorystore/IpMemoryStoreDatabase.java b/services/ipmemorystore/java/com/android/server/net/ipmemorystore/IpMemoryStoreDatabase.java index 238f07715ce3..32513c1332bc 100644 --- a/services/ipmemorystore/java/com/android/server/net/ipmemorystore/IpMemoryStoreDatabase.java +++ b/services/ipmemorystore/java/com/android/server/net/ipmemorystore/IpMemoryStoreDatabase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -134,12 +134,14 @@ public class IpMemoryStoreDatabase { } /** Called when the database is created */ + @Override public void onCreate(@NonNull final SQLiteDatabase db) { db.execSQL(NetworkAttributesContract.CREATE_TABLE); db.execSQL(PrivateDataContract.CREATE_TABLE); } /** Called when the database is upgraded */ + @Override public void onUpgrade(@NonNull final SQLiteDatabase db, final int oldVersion, final int newVersion) { // No upgrade supported yet. @@ -149,6 +151,7 @@ public class IpMemoryStoreDatabase { } /** Called when the database is downgraded */ + @Override public void onDowngrade(@NonNull final SQLiteDatabase db, final int oldVersion, final int newVersion) { // Downgrades always nuke all data and recreate an empty table. @@ -247,7 +250,9 @@ public class IpMemoryStoreDatabase { // result here. 0 results means the key was not found. if (cursor.getCount() != 1) return EXPIRY_ERROR; cursor.moveToFirst(); - return cursor.getLong(0); // index in the EXPIRY_COLUMN array + final long result = cursor.getLong(0); // index in the EXPIRY_COLUMN array + cursor.close(); + return result; } static final int RELEVANCE_ERROR = -1; // Legal values for relevance are positive @@ -321,6 +326,8 @@ public class IpMemoryStoreDatabase { final byte[] dnsAddressesBlob = getBlob(cursor, NetworkAttributesContract.COLNAME_DNSADDRESSES); final int mtu = getInt(cursor, NetworkAttributesContract.COLNAME_MTU, -1); + cursor.close(); + if (0 != assignedV4AddressInt) { builder.setAssignedV4Address(NetworkUtils.intToInet4AddressHTH(assignedV4AddressInt)); } @@ -353,7 +360,9 @@ public class IpMemoryStoreDatabase { // get more than one result here. 0 results means the key was not found. if (cursor.getCount() != 1) return null; cursor.moveToFirst(); - return cursor.getBlob(0); // index in the DATA_COLUMN array + final byte[] result = cursor.getBlob(0); // index in the DATA_COLUMN array + cursor.close(); + return result; } // Helper methods diff --git a/services/ipmemorystore/java/com/android/server/net/ipmemorystore/IpMemoryStoreService.java b/services/ipmemorystore/java/com/android/server/net/ipmemorystore/IpMemoryStoreService.java index c4d1657aff17..8b521f415925 100644 --- a/services/ipmemorystore/java/com/android/server/net/ipmemorystore/IpMemoryStoreService.java +++ b/services/ipmemorystore/java/com/android/server/net/ipmemorystore/IpMemoryStoreService.java @@ -317,21 +317,22 @@ public class IpMemoryStoreService extends IIpMemoryStore.Stub { mExecutor.execute(() -> { try { if (null == l2Key) { - listener.onL2KeyResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), l2Key, null); + listener.onNetworkAttributesRetrieved( + makeStatus(ERROR_ILLEGAL_ARGUMENT), l2Key, null); return; } if (null == mDb) { - listener.onL2KeyResponse(makeStatus(ERROR_DATABASE_CANNOT_BE_OPENED), l2Key, - null); + listener.onNetworkAttributesRetrieved( + makeStatus(ERROR_DATABASE_CANNOT_BE_OPENED), l2Key, null); return; } try { final NetworkAttributes attributes = IpMemoryStoreDatabase.retrieveNetworkAttributes(mDb, l2Key); - listener.onL2KeyResponse(makeStatus(SUCCESS), l2Key, + listener.onNetworkAttributesRetrieved(makeStatus(SUCCESS), l2Key, null == attributes ? null : attributes.toParcelable()); } catch (final Exception e) { - listener.onL2KeyResponse(makeStatus(ERROR_GENERIC), l2Key, null); + listener.onNetworkAttributesRetrieved(makeStatus(ERROR_GENERIC), l2Key, null); } } catch (final RemoteException e) { // Client at the other end died diff --git a/tests/net/java/com/android/server/net/ipmemorystore/IpMemoryStoreServiceTest.java b/tests/net/java/com/android/server/net/ipmemorystore/IpMemoryStoreServiceTest.java index c58941a5719b..c748d0f5f743 100644 --- a/tests/net/java/com/android/server/net/ipmemorystore/IpMemoryStoreServiceTest.java +++ b/tests/net/java/com/android/server/net/ipmemorystore/IpMemoryStoreServiceTest.java @@ -56,7 +56,6 @@ import java.net.Inet6Address; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Arrays; -import java.util.UUID; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; @@ -68,6 +67,8 @@ public class IpMemoryStoreServiceTest { private static final String TEST_CLIENT_ID = "testClientId"; private static final String TEST_DATA_NAME = "testData"; + private static final String[] FAKE_KEYS = { "fakeKey1", "fakeKey2", "fakeKey3", "fakeKey4" }; + @Mock private Context mMockContext; private File mDbFile; @@ -133,8 +134,8 @@ public class IpMemoryStoreServiceTest { final OnNetworkAttributesRetrievedListener functor) { return new IOnNetworkAttributesRetrieved() { @Override - public void onL2KeyResponse(final StatusParcelable status, final String l2Key, - final NetworkAttributesParcelable attributes) + public void onNetworkAttributesRetrieved(final StatusParcelable status, + final String l2Key, final NetworkAttributesParcelable attributes) throws RemoteException { functor.onNetworkAttributesRetrieved(new Status(status), l2Key, null == attributes ? null : new NetworkAttributes(attributes)); @@ -202,7 +203,7 @@ public class IpMemoryStoreServiceTest { } catch (UnknownHostException e) { /* Can't happen */ } na.setGroupHint("hint1"); na.setMtu(219); - final String l2Key = UUID.randomUUID().toString(); + final String l2Key = FAKE_KEYS[0]; NetworkAttributes attributes = na.build(); storeAttributes(l2Key, attributes); @@ -298,7 +299,7 @@ public class IpMemoryStoreServiceTest { public void testPrivateData() { final Blob b = new Blob(); b.data = new byte[] { -3, 6, 8, -9, 12, -128, 0, 89, 112, 91, -34 }; - final String l2Key = UUID.randomUUID().toString(); + final String l2Key = FAKE_KEYS[0]; doLatched("Did not complete storing private data", latch -> mService.storeBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME, b, onStatus(status -> { @@ -353,29 +354,25 @@ public class IpMemoryStoreServiceTest { na.setMtu(219); na.setDnsAddresses(Arrays.asList(Inet6Address.getByName("0A1C:2E40:480A::1CA6"))); - final String[] keys = new String[4]; - for (int i = 0; i < keys.length; ++i) { - keys[i] = UUID.randomUUID().toString(); - } - storeAttributes(keys[0], na.build()); + storeAttributes(FAKE_KEYS[0], na.build()); // 0 and 1 have identical attributes - storeAttributes(keys[1], na.build()); + storeAttributes(FAKE_KEYS[1], na.build()); // Hopefully only the MTU being different still means it's the same network na.setMtu(200); - storeAttributes(keys[2], na.build()); + storeAttributes(FAKE_KEYS[2], na.build()); // Hopefully different MTU, assigned V4 address and grouphint make a different network, // even with identical DNS addresses na.setAssignedV4Address(null); na.setGroupHint("hint2"); - storeAttributes(keys[3], na.build()); + storeAttributes(FAKE_KEYS[3], na.build()); - assertNetworksSameness(keys[0], keys[1], SameL3NetworkResponse.NETWORK_SAME); - assertNetworksSameness(keys[0], keys[2], SameL3NetworkResponse.NETWORK_SAME); - assertNetworksSameness(keys[1], keys[2], SameL3NetworkResponse.NETWORK_SAME); - assertNetworksSameness(keys[0], keys[3], SameL3NetworkResponse.NETWORK_DIFFERENT); - assertNetworksSameness(keys[0], UUID.randomUUID().toString(), + assertNetworksSameness(FAKE_KEYS[0], FAKE_KEYS[1], SameL3NetworkResponse.NETWORK_SAME); + assertNetworksSameness(FAKE_KEYS[0], FAKE_KEYS[2], SameL3NetworkResponse.NETWORK_SAME); + assertNetworksSameness(FAKE_KEYS[1], FAKE_KEYS[2], SameL3NetworkResponse.NETWORK_SAME); + assertNetworksSameness(FAKE_KEYS[0], FAKE_KEYS[3], SameL3NetworkResponse.NETWORK_DIFFERENT); + assertNetworksSameness(FAKE_KEYS[0], "neverInsertedKey", SameL3NetworkResponse.NETWORK_NEVER_CONNECTED); doLatched("Did not finish evaluating sameness", latch -> -- cgit v1.2.3-59-g8ed1b