Merge "adopt non-blocking method to obtain the IpMemoryStore service."
This commit is contained in:
@@ -19,6 +19,9 @@ package android.net;
|
||||
import android.annotation.NonNull;
|
||||
import android.content.Context;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* service used to communicate with the ip memory store service in network stack,
|
||||
* which is running in the same module.
|
||||
@@ -35,8 +38,7 @@ public class NetworkStackIpMemoryStore extends IpMemoryStoreClient {
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
protected IIpMemoryStore getService() {
|
||||
return mService;
|
||||
protected void runWhenServiceReady(Consumer<IIpMemoryStore> cb) throws ExecutionException {
|
||||
cb.accept(mService);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,11 +18,14 @@ package android.net;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Manager class used to communicate with the ip memory store service in the network stack,
|
||||
@@ -30,15 +33,18 @@ import java.util.concurrent.ExecutionException;
|
||||
* @hide
|
||||
*/
|
||||
public class IpMemoryStore extends IpMemoryStoreClient {
|
||||
private final CompletableFuture<IIpMemoryStore> mService;
|
||||
private static final String TAG = IpMemoryStore.class.getSimpleName();
|
||||
@NonNull private final CompletableFuture<IIpMemoryStore> mService;
|
||||
@NonNull private final AtomicReference<CompletableFuture<IIpMemoryStore>> mTailNode;
|
||||
|
||||
public IpMemoryStore(@NonNull final Context context) {
|
||||
super(context);
|
||||
mService = new CompletableFuture<>();
|
||||
mTailNode = new AtomicReference<CompletableFuture<IIpMemoryStore>>(mService);
|
||||
getNetworkStackClient().fetchIpMemoryStore(
|
||||
new IIpMemoryStoreCallbacks.Stub() {
|
||||
@Override
|
||||
public void onIpMemoryStoreFetched(final IIpMemoryStore memoryStore) {
|
||||
public void onIpMemoryStoreFetched(@NonNull final IIpMemoryStore memoryStore) {
|
||||
mService.complete(memoryStore);
|
||||
}
|
||||
|
||||
@@ -49,9 +55,28 @@ public class IpMemoryStore extends IpMemoryStoreClient {
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* If the IpMemoryStore is ready, this function will run the request synchronously.
|
||||
* Otherwise, it will enqueue the requests for execution immediately after the
|
||||
* service becomes ready. The requests are guaranteed to be executed in the order
|
||||
* they are sumbitted.
|
||||
*/
|
||||
@Override
|
||||
protected IIpMemoryStore getService() throws InterruptedException, ExecutionException {
|
||||
return mService.get();
|
||||
protected void runWhenServiceReady(Consumer<IIpMemoryStore> cb) throws ExecutionException {
|
||||
mTailNode.getAndUpdate(future -> future.handle((store, exception) -> {
|
||||
if (exception != null) {
|
||||
// this should never happens since we also catch the exception below
|
||||
Log.wtf(TAG, "Error fetching IpMemoryStore", exception);
|
||||
return store;
|
||||
}
|
||||
|
||||
try {
|
||||
cb.accept(store);
|
||||
} catch (Exception e) {
|
||||
Log.wtf(TAG, "Exception occured: " + e.getMessage());
|
||||
}
|
||||
return store;
|
||||
}));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
||||
@@ -31,6 +31,7 @@ import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* service used to communicate with the ip memory store service in network stack,
|
||||
@@ -46,8 +47,25 @@ public abstract class IpMemoryStoreClient {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
protected abstract IIpMemoryStore getService() throws InterruptedException, ExecutionException;
|
||||
protected abstract void runWhenServiceReady(Consumer<IIpMemoryStore> cb)
|
||||
throws ExecutionException;
|
||||
|
||||
@FunctionalInterface
|
||||
private interface ThrowingRunnable {
|
||||
void run() throws RemoteException;
|
||||
}
|
||||
|
||||
private void ignoringRemoteException(ThrowingRunnable r) {
|
||||
ignoringRemoteException("Failed to execute remote procedure call", r);
|
||||
}
|
||||
|
||||
private void ignoringRemoteException(String message, ThrowingRunnable r) {
|
||||
try {
|
||||
r.run();
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, message, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store network attributes for a given L2 key.
|
||||
@@ -69,14 +87,12 @@ public abstract class IpMemoryStoreClient {
|
||||
@NonNull final NetworkAttributes attributes,
|
||||
@Nullable final OnStatusListener listener) {
|
||||
try {
|
||||
try {
|
||||
getService().storeNetworkAttributes(l2Key, attributes.toParcelable(),
|
||||
OnStatusListener.toAIDL(listener));
|
||||
} catch (InterruptedException | ExecutionException m) {
|
||||
listener.onComplete(new Status(Status.ERROR_UNKNOWN));
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error storing network attributes", e);
|
||||
runWhenServiceReady(service -> ignoringRemoteException(
|
||||
() -> service.storeNetworkAttributes(l2Key, attributes.toParcelable(),
|
||||
OnStatusListener.toAIDL(listener))));
|
||||
} catch (ExecutionException m) {
|
||||
ignoringRemoteException("Error storing network attributes",
|
||||
() -> listener.onComplete(new Status(Status.ERROR_UNKNOWN)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,14 +111,12 @@ public abstract class IpMemoryStoreClient {
|
||||
@NonNull final String name, @NonNull final Blob data,
|
||||
@Nullable final OnStatusListener listener) {
|
||||
try {
|
||||
try {
|
||||
getService().storeBlob(l2Key, clientId, name, data,
|
||||
OnStatusListener.toAIDL(listener));
|
||||
} catch (InterruptedException | ExecutionException m) {
|
||||
listener.onComplete(new Status(Status.ERROR_UNKNOWN));
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error storing blob", e);
|
||||
runWhenServiceReady(service -> ignoringRemoteException(
|
||||
() -> service.storeBlob(l2Key, clientId, name, data,
|
||||
OnStatusListener.toAIDL(listener))));
|
||||
} catch (ExecutionException m) {
|
||||
ignoringRemoteException("Error storing blob",
|
||||
() -> listener.onComplete(new Status(Status.ERROR_UNKNOWN)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,14 +137,12 @@ public abstract class IpMemoryStoreClient {
|
||||
public void findL2Key(@NonNull final NetworkAttributes attributes,
|
||||
@NonNull final OnL2KeyResponseListener listener) {
|
||||
try {
|
||||
try {
|
||||
getService().findL2Key(attributes.toParcelable(),
|
||||
OnL2KeyResponseListener.toAIDL(listener));
|
||||
} catch (InterruptedException | ExecutionException m) {
|
||||
listener.onL2KeyResponse(new Status(Status.ERROR_UNKNOWN), null);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error finding L2 Key", e);
|
||||
runWhenServiceReady(service -> ignoringRemoteException(
|
||||
() -> service.findL2Key(attributes.toParcelable(),
|
||||
OnL2KeyResponseListener.toAIDL(listener))));
|
||||
} catch (ExecutionException m) {
|
||||
ignoringRemoteException("Error finding L2 Key",
|
||||
() -> listener.onL2KeyResponse(new Status(Status.ERROR_UNKNOWN), null));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,14 +158,12 @@ public abstract class IpMemoryStoreClient {
|
||||
public void isSameNetwork(@NonNull final String l2Key1, @NonNull final String l2Key2,
|
||||
@NonNull final OnSameL3NetworkResponseListener listener) {
|
||||
try {
|
||||
try {
|
||||
getService().isSameNetwork(l2Key1, l2Key2,
|
||||
OnSameL3NetworkResponseListener.toAIDL(listener));
|
||||
} catch (InterruptedException | ExecutionException m) {
|
||||
listener.onSameL3NetworkResponse(new Status(Status.ERROR_UNKNOWN), null);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error checking for network sameness", e);
|
||||
runWhenServiceReady(service -> ignoringRemoteException(
|
||||
() -> service.isSameNetwork(l2Key1, l2Key2,
|
||||
OnSameL3NetworkResponseListener.toAIDL(listener))));
|
||||
} catch (ExecutionException m) {
|
||||
ignoringRemoteException("Error checking for network sameness",
|
||||
() -> listener.onSameL3NetworkResponse(new Status(Status.ERROR_UNKNOWN), null));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,14 +179,13 @@ public abstract class IpMemoryStoreClient {
|
||||
public void retrieveNetworkAttributes(@NonNull final String l2Key,
|
||||
@NonNull final OnNetworkAttributesRetrievedListener listener) {
|
||||
try {
|
||||
try {
|
||||
getService().retrieveNetworkAttributes(l2Key,
|
||||
OnNetworkAttributesRetrievedListener.toAIDL(listener));
|
||||
} catch (InterruptedException | ExecutionException m) {
|
||||
listener.onNetworkAttributesRetrieved(new Status(Status.ERROR_UNKNOWN), null, null);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error retrieving network attributes", e);
|
||||
runWhenServiceReady(service -> ignoringRemoteException(
|
||||
() -> service.retrieveNetworkAttributes(l2Key,
|
||||
OnNetworkAttributesRetrievedListener.toAIDL(listener))));
|
||||
} catch (ExecutionException m) {
|
||||
ignoringRemoteException("Error retrieving network attributes",
|
||||
() -> listener.onNetworkAttributesRetrieved(new Status(Status.ERROR_UNKNOWN),
|
||||
null, null));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,14 +203,13 @@ public abstract class IpMemoryStoreClient {
|
||||
public void retrieveBlob(@NonNull final String l2Key, @NonNull final String clientId,
|
||||
@NonNull final String name, @NonNull final OnBlobRetrievedListener listener) {
|
||||
try {
|
||||
try {
|
||||
getService().retrieveBlob(l2Key, clientId, name,
|
||||
OnBlobRetrievedListener.toAIDL(listener));
|
||||
} catch (InterruptedException | ExecutionException m) {
|
||||
listener.onBlobRetrieved(new Status(Status.ERROR_UNKNOWN), null, null, null);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error retrieving blob", e);
|
||||
runWhenServiceReady(service -> ignoringRemoteException(
|
||||
() -> service.retrieveBlob(l2Key, clientId, name,
|
||||
OnBlobRetrievedListener.toAIDL(listener))));
|
||||
} catch (ExecutionException m) {
|
||||
ignoringRemoteException("Error retrieving blob",
|
||||
() -> listener.onBlobRetrieved(new Status(Status.ERROR_UNKNOWN),
|
||||
null, null, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,26 @@
|
||||
|
||||
package android.net;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ipmemorystore.Blob;
|
||||
import android.net.ipmemorystore.IOnStatusListener;
|
||||
import android.net.ipmemorystore.NetworkAttributes;
|
||||
import android.net.ipmemorystore.NetworkAttributesParcelable;
|
||||
import android.net.ipmemorystore.Status;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
@@ -27,28 +43,57 @@ import androidx.test.runner.AndroidJUnit4;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Arrays;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class IpMemoryStoreTest {
|
||||
private static final String TAG = IpMemoryStoreTest.class.getSimpleName();
|
||||
private static final String TEST_CLIENT_ID = "testClientId";
|
||||
private static final String TEST_DATA_NAME = "testData";
|
||||
private static final String TEST_OTHER_DATA_NAME = TEST_DATA_NAME + "Other";
|
||||
private static final byte[] TEST_BLOB_DATA = new byte[] { -3, 6, 8, -9, 12,
|
||||
-128, 0, 89, 112, 91, -34 };
|
||||
private static final NetworkAttributes TEST_NETWORK_ATTRIBUTES = buildTestNetworkAttributes(
|
||||
"hint", 219);
|
||||
|
||||
@Mock
|
||||
Context mMockContext;
|
||||
@Mock
|
||||
NetworkStackClient mNetworkStackClient;
|
||||
@Mock
|
||||
IIpMemoryStore mMockService;
|
||||
@Mock
|
||||
IOnStatusListener mIOnStatusListener;
|
||||
IpMemoryStore mStore;
|
||||
|
||||
@Captor
|
||||
ArgumentCaptor<IIpMemoryStoreCallbacks> mCbCaptor;
|
||||
@Captor
|
||||
ArgumentCaptor<NetworkAttributesParcelable> mNapCaptor;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
doAnswer(invocation -> {
|
||||
((IIpMemoryStoreCallbacks) invocation.getArgument(0))
|
||||
.onIpMemoryStoreFetched(mMockService);
|
||||
return null;
|
||||
}).when(mNetworkStackClient).fetchIpMemoryStore(any());
|
||||
}
|
||||
|
||||
private void startIpMemoryStore(boolean supplyService) {
|
||||
if (supplyService) {
|
||||
doAnswer(invocation -> {
|
||||
((IIpMemoryStoreCallbacks) invocation.getArgument(0))
|
||||
.onIpMemoryStoreFetched(mMockService);
|
||||
return null;
|
||||
}).when(mNetworkStackClient).fetchIpMemoryStore(any());
|
||||
} else {
|
||||
doNothing().when(mNetworkStackClient).fetchIpMemoryStore(mCbCaptor.capture());
|
||||
}
|
||||
mStore = new IpMemoryStore(mMockContext) {
|
||||
@Override
|
||||
protected NetworkStackClient getNetworkStackClient() {
|
||||
@@ -57,24 +102,228 @@ public class IpMemoryStoreTest {
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNetworkAttributes() {
|
||||
// TODO : implement this
|
||||
private static NetworkAttributes buildTestNetworkAttributes(String hint, int mtu) {
|
||||
return new NetworkAttributes.Builder()
|
||||
.setGroupHint(hint)
|
||||
.setMtu(mtu)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrivateData() {
|
||||
// TODO : implement this
|
||||
public void testNetworkAttributes() throws Exception {
|
||||
startIpMemoryStore(true);
|
||||
final String l2Key = "fakeKey";
|
||||
|
||||
mStore.storeNetworkAttributes(l2Key, TEST_NETWORK_ATTRIBUTES,
|
||||
status -> {
|
||||
assertTrue("Store not successful : " + status.resultCode, status.isSuccess());
|
||||
});
|
||||
verify(mMockService, times(1)).storeNetworkAttributes(eq(l2Key),
|
||||
mNapCaptor.capture(), any());
|
||||
assertEquals(TEST_NETWORK_ATTRIBUTES, new NetworkAttributes(mNapCaptor.getValue()));
|
||||
|
||||
mStore.retrieveNetworkAttributes(l2Key,
|
||||
(status, key, attr) -> {
|
||||
assertTrue("Retrieve network attributes not successful : "
|
||||
+ status.resultCode, status.isSuccess());
|
||||
assertEquals(l2Key, key);
|
||||
assertEquals(TEST_NETWORK_ATTRIBUTES, attr);
|
||||
});
|
||||
|
||||
verify(mMockService, times(1)).retrieveNetworkAttributes(eq(l2Key), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindL2Key() {
|
||||
// TODO : implement this
|
||||
public void testPrivateData() throws RemoteException {
|
||||
startIpMemoryStore(true);
|
||||
final Blob b = new Blob();
|
||||
b.data = TEST_BLOB_DATA;
|
||||
final String l2Key = "fakeKey";
|
||||
|
||||
mStore.storeBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME, b,
|
||||
status -> {
|
||||
assertTrue("Store not successful : " + status.resultCode, status.isSuccess());
|
||||
});
|
||||
verify(mMockService, times(1)).storeBlob(eq(l2Key), eq(TEST_CLIENT_ID), eq(TEST_DATA_NAME),
|
||||
eq(b), any());
|
||||
|
||||
mStore.retrieveBlob(l2Key, TEST_CLIENT_ID, TEST_OTHER_DATA_NAME,
|
||||
(status, key, name, data) -> {
|
||||
assertTrue("Retrieve blob status not successful : " + status.resultCode,
|
||||
status.isSuccess());
|
||||
assertEquals(l2Key, key);
|
||||
assertEquals(name, TEST_DATA_NAME);
|
||||
assertTrue(Arrays.equals(b.data, data.data));
|
||||
});
|
||||
verify(mMockService, times(1)).retrieveBlob(eq(l2Key), eq(TEST_CLIENT_ID),
|
||||
eq(TEST_OTHER_DATA_NAME), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsSameNetwork() {
|
||||
// TODO : implement this
|
||||
public void testFindL2Key()
|
||||
throws UnknownHostException, RemoteException, Exception {
|
||||
startIpMemoryStore(true);
|
||||
final String l2Key = "fakeKey";
|
||||
|
||||
mStore.findL2Key(TEST_NETWORK_ATTRIBUTES,
|
||||
(status, key) -> {
|
||||
assertTrue("Retrieve network sameness not successful : " + status.resultCode,
|
||||
status.isSuccess());
|
||||
assertEquals(l2Key, key);
|
||||
});
|
||||
verify(mMockService, times(1)).findL2Key(mNapCaptor.capture(), any());
|
||||
assertEquals(TEST_NETWORK_ATTRIBUTES, new NetworkAttributes(mNapCaptor.getValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsSameNetwork() throws UnknownHostException, RemoteException {
|
||||
startIpMemoryStore(true);
|
||||
final String l2Key1 = "fakeKey1";
|
||||
final String l2Key2 = "fakeKey2";
|
||||
|
||||
mStore.isSameNetwork(l2Key1, l2Key2,
|
||||
(status, answer) -> {
|
||||
assertFalse("Retrieve network sameness suspiciously successful : "
|
||||
+ status.resultCode, status.isSuccess());
|
||||
assertEquals(Status.ERROR_ILLEGAL_ARGUMENT, status.resultCode);
|
||||
assertNull(answer);
|
||||
});
|
||||
verify(mMockService, times(1)).isSameNetwork(eq(l2Key1), eq(l2Key2), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnqueuedIpMsRequests() throws Exception {
|
||||
startIpMemoryStore(false);
|
||||
|
||||
final Blob b = new Blob();
|
||||
b.data = TEST_BLOB_DATA;
|
||||
final String l2Key = "fakeKey";
|
||||
|
||||
// enqueue multiple ipms requests
|
||||
mStore.storeNetworkAttributes(l2Key, TEST_NETWORK_ATTRIBUTES,
|
||||
status -> {
|
||||
assertTrue("Store not successful : " + status.resultCode, status.isSuccess());
|
||||
});
|
||||
mStore.retrieveNetworkAttributes(l2Key,
|
||||
(status, key, attr) -> {
|
||||
assertTrue("Retrieve network attributes not successful : "
|
||||
+ status.resultCode, status.isSuccess());
|
||||
assertEquals(l2Key, key);
|
||||
assertEquals(TEST_NETWORK_ATTRIBUTES, attr);
|
||||
});
|
||||
mStore.storeBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME, b,
|
||||
status -> {
|
||||
assertTrue("Store not successful : " + status.resultCode, status.isSuccess());
|
||||
});
|
||||
mStore.retrieveBlob(l2Key, TEST_CLIENT_ID, TEST_OTHER_DATA_NAME,
|
||||
(status, key, name, data) -> {
|
||||
assertTrue("Retrieve blob status not successful : " + status.resultCode,
|
||||
status.isSuccess());
|
||||
assertEquals(l2Key, key);
|
||||
assertEquals(name, TEST_DATA_NAME);
|
||||
assertTrue(Arrays.equals(b.data, data.data));
|
||||
});
|
||||
|
||||
// get ipms service ready
|
||||
mCbCaptor.getValue().onIpMemoryStoreFetched(mMockService);
|
||||
|
||||
InOrder inOrder = inOrder(mMockService);
|
||||
|
||||
inOrder.verify(mMockService).storeNetworkAttributes(eq(l2Key), mNapCaptor.capture(), any());
|
||||
inOrder.verify(mMockService).retrieveNetworkAttributes(eq(l2Key), any());
|
||||
inOrder.verify(mMockService).storeBlob(eq(l2Key), eq(TEST_CLIENT_ID), eq(TEST_DATA_NAME),
|
||||
eq(b), any());
|
||||
inOrder.verify(mMockService).retrieveBlob(eq(l2Key), eq(TEST_CLIENT_ID),
|
||||
eq(TEST_OTHER_DATA_NAME), any());
|
||||
assertEquals(TEST_NETWORK_ATTRIBUTES, new NetworkAttributes(mNapCaptor.getValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnqueuedIpMsRequestsWithException() throws Exception {
|
||||
startIpMemoryStore(true);
|
||||
doThrow(RemoteException.class).when(mMockService).retrieveNetworkAttributes(any(), any());
|
||||
|
||||
final Blob b = new Blob();
|
||||
b.data = TEST_BLOB_DATA;
|
||||
final String l2Key = "fakeKey";
|
||||
|
||||
// enqueue multiple ipms requests
|
||||
mStore.storeNetworkAttributes(l2Key, TEST_NETWORK_ATTRIBUTES,
|
||||
status -> {
|
||||
assertTrue("Store not successful : " + status.resultCode, status.isSuccess());
|
||||
});
|
||||
mStore.retrieveNetworkAttributes(l2Key,
|
||||
(status, key, attr) -> {
|
||||
assertTrue("Retrieve network attributes not successful : "
|
||||
+ status.resultCode, status.isSuccess());
|
||||
assertEquals(l2Key, key);
|
||||
assertEquals(TEST_NETWORK_ATTRIBUTES, attr);
|
||||
});
|
||||
mStore.storeBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME, b,
|
||||
status -> {
|
||||
assertTrue("Store not successful : " + status.resultCode, status.isSuccess());
|
||||
});
|
||||
mStore.retrieveBlob(l2Key, TEST_CLIENT_ID, TEST_OTHER_DATA_NAME,
|
||||
(status, key, name, data) -> {
|
||||
assertTrue("Retrieve blob status not successful : " + status.resultCode,
|
||||
status.isSuccess());
|
||||
assertEquals(l2Key, key);
|
||||
assertEquals(name, TEST_DATA_NAME);
|
||||
assertTrue(Arrays.equals(b.data, data.data));
|
||||
});
|
||||
|
||||
// verify the rest of the queue is still processed in order even if the remote exception
|
||||
// occurs when calling one or more requests
|
||||
InOrder inOrder = inOrder(mMockService);
|
||||
|
||||
inOrder.verify(mMockService).storeNetworkAttributes(eq(l2Key), mNapCaptor.capture(), any());
|
||||
inOrder.verify(mMockService).storeBlob(eq(l2Key), eq(TEST_CLIENT_ID), eq(TEST_DATA_NAME),
|
||||
eq(b), any());
|
||||
inOrder.verify(mMockService).retrieveBlob(eq(l2Key), eq(TEST_CLIENT_ID),
|
||||
eq(TEST_OTHER_DATA_NAME), any());
|
||||
assertEquals(TEST_NETWORK_ATTRIBUTES, new NetworkAttributes(mNapCaptor.getValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnqueuedIpMsRequestsCallbackFunctionWithException() throws Exception {
|
||||
startIpMemoryStore(true);
|
||||
|
||||
final Blob b = new Blob();
|
||||
b.data = TEST_BLOB_DATA;
|
||||
final String l2Key = "fakeKey";
|
||||
|
||||
// enqueue multiple ipms requests
|
||||
mStore.storeNetworkAttributes(l2Key, TEST_NETWORK_ATTRIBUTES,
|
||||
status -> {
|
||||
assertTrue("Store not successful : " + status.resultCode, status.isSuccess());
|
||||
});
|
||||
mStore.retrieveNetworkAttributes(l2Key,
|
||||
(status, key, attr) -> {
|
||||
throw new RuntimeException("retrieveNetworkAttributes test");
|
||||
});
|
||||
mStore.storeBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME, b,
|
||||
status -> {
|
||||
throw new RuntimeException("storeBlob test");
|
||||
});
|
||||
mStore.retrieveBlob(l2Key, TEST_CLIENT_ID, TEST_OTHER_DATA_NAME,
|
||||
(status, key, name, data) -> {
|
||||
assertTrue("Retrieve blob status not successful : " + status.resultCode,
|
||||
status.isSuccess());
|
||||
assertEquals(l2Key, key);
|
||||
assertEquals(name, TEST_DATA_NAME);
|
||||
assertTrue(Arrays.equals(b.data, data.data));
|
||||
});
|
||||
|
||||
// verify the rest of the queue is still processed in order even if when one or more
|
||||
// callback throw the remote exception
|
||||
InOrder inOrder = inOrder(mMockService);
|
||||
|
||||
inOrder.verify(mMockService).storeNetworkAttributes(eq(l2Key), mNapCaptor.capture(),
|
||||
any());
|
||||
inOrder.verify(mMockService).storeBlob(eq(l2Key), eq(TEST_CLIENT_ID), eq(TEST_DATA_NAME),
|
||||
eq(b), any());
|
||||
inOrder.verify(mMockService).retrieveBlob(eq(l2Key), eq(TEST_CLIENT_ID),
|
||||
eq(TEST_OTHER_DATA_NAME), any());
|
||||
assertEquals(TEST_NETWORK_ATTRIBUTES, new NetworkAttributes(mNapCaptor.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.connectivity.ipmemorystore;
|
||||
package com.android.server.net.ipmemorystore;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user