From 93ea3ce9b8bd53f97df2171b3e3fbc70fa1b096d Mon Sep 17 00:00:00 2001 From: Robert Quattlebaum Date: Fri, 14 Jul 2017 12:05:29 -0700 Subject: lowpan: Introduce new unit tests for data classes This change introduces new unit tests which confirm that various data classes are being property marshalled between their Java and C++ implementations. Bug: b/63707448 b/63708348 Change-Id: I41d590b1e77dc41873c4b9e9bf1b7f1bf859f74e Test: These tests both compile and pass --- lowpan/tests/Android.mk | 53 +++++- .../android/net/lowpan/LowpanBeaconInfoTest.java | 134 ++++++++++++++ .../android/net/lowpan/LowpanChannelInfoTest.java | 78 ++++++++ .../android/net/lowpan/LowpanCredentialTest.java | 92 ++++++++++ .../android/net/lowpan/LowpanIdentityTest.java | 199 +++++++++++++++++++++ .../android/net/lowpan/LowpanInterfaceTest.java | 89 +++++++++ .../java/android/net/lowpan/LowpanManagerTest.java | 175 ++++++++++++++++++ .../android/net/lowpan/LowpanProvisionTest.java | 128 +++++++++++++ lowpan/tests/jni/LowpanBeaconInfoTest.cpp | 66 +++++++ lowpan/tests/jni/LowpanBeaconInfoTest.h | 27 +++ lowpan/tests/jni/LowpanChannelInfoTest.cpp | 66 +++++++ lowpan/tests/jni/LowpanChannelInfoTest.h | 27 +++ lowpan/tests/jni/LowpanCredentialTest.cpp | 66 +++++++ lowpan/tests/jni/LowpanCredentialTest.h | 27 +++ lowpan/tests/jni/LowpanIdentityTest.cpp | 66 +++++++ lowpan/tests/jni/LowpanIdentityTest.h | 27 +++ lowpan/tests/jni/LowpanProvisionTest.cpp | 66 +++++++ lowpan/tests/jni/LowpanProvisionTest.h | 27 +++ .../android/net/lowpan/LowpanInterfaceTest.java | 97 ---------- .../src/android/net/lowpan/LowpanManagerTest.java | 176 ------------------ 20 files changed, 1411 insertions(+), 275 deletions(-) create mode 100644 lowpan/tests/java/android/net/lowpan/LowpanBeaconInfoTest.java create mode 100644 lowpan/tests/java/android/net/lowpan/LowpanChannelInfoTest.java create mode 100644 lowpan/tests/java/android/net/lowpan/LowpanCredentialTest.java create mode 100644 lowpan/tests/java/android/net/lowpan/LowpanIdentityTest.java create mode 100644 lowpan/tests/java/android/net/lowpan/LowpanInterfaceTest.java create mode 100644 lowpan/tests/java/android/net/lowpan/LowpanManagerTest.java create mode 100644 lowpan/tests/java/android/net/lowpan/LowpanProvisionTest.java create mode 100644 lowpan/tests/jni/LowpanBeaconInfoTest.cpp create mode 100644 lowpan/tests/jni/LowpanBeaconInfoTest.h create mode 100644 lowpan/tests/jni/LowpanChannelInfoTest.cpp create mode 100644 lowpan/tests/jni/LowpanChannelInfoTest.h create mode 100644 lowpan/tests/jni/LowpanCredentialTest.cpp create mode 100644 lowpan/tests/jni/LowpanCredentialTest.h create mode 100644 lowpan/tests/jni/LowpanIdentityTest.cpp create mode 100644 lowpan/tests/jni/LowpanIdentityTest.h create mode 100644 lowpan/tests/jni/LowpanProvisionTest.cpp create mode 100644 lowpan/tests/jni/LowpanProvisionTest.h delete mode 100644 lowpan/tests/src/android/net/lowpan/LowpanInterfaceTest.java delete mode 100644 lowpan/tests/src/android/net/lowpan/LowpanManagerTest.java (limited to 'lowpan') diff --git a/lowpan/tests/Android.mk b/lowpan/tests/Android.mk index bb0a944b5e7d..1ea471a4cc00 100644 --- a/lowpan/tests/Android.mk +++ b/lowpan/tests/Android.mk @@ -54,8 +54,35 @@ LOCAL_STATIC_JAVA_LIBRARIES := \ mockito-target-minus-junit4 \ frameworks-base-testutils \ -LOCAL_JAVA_LIBRARIES := \ - android.test.runner \ +LOCAL_JNI_SHARED_LIBRARIES += libframeworkslowpantestsjni +LOCAL_JNI_SHARED_LIBRARIES += libandroid_net_lowpan +LOCAL_JNI_SHARED_LIBRARIES += \ + libbacktrace \ + libbase \ + libbinder \ + libc++ \ + libcutils \ + liblog \ + liblzma \ + libnativehelper \ + libnetdaidl \ + libui \ + libunwind \ + libutils \ + libvndksupport \ + libcrypto \ + libhidl-gen-utils \ + libhidlbase \ + libhidltransport \ + libpackagelistparser \ + libpcre2 \ + libselinux \ + libtinyxml2 \ + libvintf \ + libhwbinder \ + android.hidl.token@1.0 + +LOCAL_JAVA_LIBRARIES := android.test.runner LOCAL_PACKAGE_NAME := FrameworksLowpanApiTests LOCAL_COMPATIBILITY_SUITE := device-tests @@ -63,3 +90,25 @@ LOCAL_COMPATIBILITY_SUITE := device-tests LOCAL_CERTIFICATE := platform LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk include $(BUILD_PACKAGE) + +######################################################################### +# Build JNI Shared Library +######################################################################### + +LOCAL_PATH:= $(LOCAL_PATH)/jni + +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_CFLAGS := -Wall -Wextra -Werror + +LOCAL_SRC_FILES := $(call all-cpp-files-under) + +LOCAL_SHARED_LIBRARIES += libandroid_net_lowpan +LOCAL_SHARED_LIBRARIES += libbinder +LOCAL_SHARED_LIBRARIES += liblog + +LOCAL_MODULE := libframeworkslowpantestsjni + +include $(BUILD_SHARED_LIBRARY) diff --git a/lowpan/tests/java/android/net/lowpan/LowpanBeaconInfoTest.java b/lowpan/tests/java/android/net/lowpan/LowpanBeaconInfoTest.java new file mode 100644 index 000000000000..6dbb3ed5de65 --- /dev/null +++ b/lowpan/tests/java/android/net/lowpan/LowpanBeaconInfoTest.java @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2017 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 android.net.lowpan; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertArrayEquals; + +import android.os.Parcel; +import android.support.test.runner.AndroidJUnit4; +import android.test.suitebuilder.annotation.SmallTest; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class LowpanBeaconInfoTest { + + static { + System.loadLibrary("frameworkslowpantestsjni"); + } + + private static native byte[] readAndWriteNative(byte[] inParcel); + + public void testNativeParcelUnparcel(LowpanBeaconInfo original) { + byte[] inParcel = marshall(original); + byte[] outParcel = readAndWriteNative(inParcel); + LowpanBeaconInfo roundTrip = unmarshall(outParcel); + + assertEquals(original, roundTrip); + assertArrayEquals(inParcel, outParcel); + } + + @Test + public void testNativeParcelUnparcel() { + testNativeParcelUnparcel( + new LowpanBeaconInfo.Builder() + .setName("TestNet1") + .setPanid(0x1234) + .setXpanid( + new byte[] { + (byte) 0x00, + (byte) 0x11, + (byte) 0x22, + (byte) 0x33, + (byte) 0x44, + (byte) 0x55, + (byte) 0x66, + (byte) 0x77 + }) + .setType(LowpanInterface.NETWORK_TYPE_THREAD_V1) + .setChannel(15) + .setBeaconAddress( + new byte[] { + (byte) 0x88, + (byte) 0x99, + (byte) 0xaa, + (byte) 0xbb, + (byte) 0xcc, + (byte) 0xdd, + (byte) 0xee, + (byte) 0xff + }) + .build()); + + testNativeParcelUnparcel( + new LowpanBeaconInfo.Builder() + .setName("TestNet2") + .setPanid(0x5678) + .setXpanid( + new byte[] { + (byte) 0x88, + (byte) 0x99, + (byte) 0xaa, + (byte) 0xbb, + (byte) 0xcc, + (byte) 0xdd, + (byte) 0xee, + (byte) 0xff + }) + .setType("bork-bork-bork") + .setChannel(16) + .setBeaconAddress( + new byte[] { + (byte) 0x00, + (byte) 0x11, + (byte) 0x22, + (byte) 0x33, + (byte) 0x44, + (byte) 0x55, + (byte) 0x66, + (byte) 0x77 + }) + .setFlag(LowpanBeaconInfo.FLAG_CAN_ASSIST) + .build()); + } + + /** + * Write a {@link LowpanBeaconInfo} into an empty parcel and return the underlying data. + * + * @see unmarshall(byte[]) + */ + private static byte[] marshall(LowpanBeaconInfo addr) { + Parcel p = Parcel.obtain(); + addr.writeToParcel(p, /* flags */ 0); + p.setDataPosition(0); + return p.marshall(); + } + + /** + * Read raw bytes into a parcel, and read a {@link LowpanBeaconInfo} back out of them. + * + * @see marshall(LowpanBeaconInfo) + */ + private static LowpanBeaconInfo unmarshall(byte[] data) { + Parcel p = Parcel.obtain(); + p.unmarshall(data, 0, data.length); + p.setDataPosition(0); + return LowpanBeaconInfo.CREATOR.createFromParcel(p); + } +} diff --git a/lowpan/tests/java/android/net/lowpan/LowpanChannelInfoTest.java b/lowpan/tests/java/android/net/lowpan/LowpanChannelInfoTest.java new file mode 100644 index 000000000000..eac4398088a8 --- /dev/null +++ b/lowpan/tests/java/android/net/lowpan/LowpanChannelInfoTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2017 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 android.net.lowpan; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertArrayEquals; + +import android.os.Parcel; +import android.support.test.runner.AndroidJUnit4; +import android.test.suitebuilder.annotation.SmallTest; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class LowpanChannelInfoTest { + + static { + System.loadLibrary("frameworkslowpantestsjni"); + } + + private static native byte[] readAndWriteNative(byte[] inParcel); + + public void testNativeParcelUnparcel(LowpanChannelInfo original) { + byte[] inParcel = marshall(original); + byte[] outParcel = readAndWriteNative(inParcel); + LowpanChannelInfo roundTrip = unmarshall(outParcel); + + assertEquals(original, roundTrip); + assertArrayEquals(inParcel, outParcel); + } + + @Test + public void testNativeParcelUnparcel() { + int i; + for (i = 1; i < 26; i++) { + testNativeParcelUnparcel(LowpanChannelInfo.getChannelInfoForIeee802154Page0(i)); + } + } + + /** + * Write a {@link LowpanChannelInfo} into an empty parcel and return the underlying data. + * + * @see unmarshall(byte[]) + */ + private static byte[] marshall(LowpanChannelInfo addr) { + Parcel p = Parcel.obtain(); + addr.writeToParcel(p, /* flags */ 0); + p.setDataPosition(0); + return p.marshall(); + } + + /** + * Read raw bytes into a parcel, and read a {@link LowpanChannelInfo} back out of them. + * + * @see marshall(LowpanChannelInfo) + */ + private static LowpanChannelInfo unmarshall(byte[] data) { + Parcel p = Parcel.obtain(); + p.unmarshall(data, 0, data.length); + p.setDataPosition(0); + return LowpanChannelInfo.CREATOR.createFromParcel(p); + } +} diff --git a/lowpan/tests/java/android/net/lowpan/LowpanCredentialTest.java b/lowpan/tests/java/android/net/lowpan/LowpanCredentialTest.java new file mode 100644 index 000000000000..26e33349ddac --- /dev/null +++ b/lowpan/tests/java/android/net/lowpan/LowpanCredentialTest.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2017 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 android.net.lowpan; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertArrayEquals; + +import android.os.Parcel; +import android.support.test.runner.AndroidJUnit4; +import android.test.suitebuilder.annotation.SmallTest; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class LowpanCredentialTest { + + static { + System.loadLibrary("frameworkslowpantestsjni"); + } + + private static native byte[] readAndWriteNative(byte[] inParcel); + + public void testNativeParcelUnparcel(LowpanCredential original) { + byte[] inParcel = marshall(original); + byte[] outParcel = readAndWriteNative(inParcel); + LowpanCredential roundTrip = unmarshall(outParcel); + + assertEquals(original, roundTrip); + assertArrayEquals(inParcel, outParcel); + } + + @Test + public void testNativeParcelUnparcel() { + testNativeParcelUnparcel( + LowpanCredential.createMasterKey( + new byte[] { + (byte) 0x88, + (byte) 0x99, + (byte) 0xaa, + (byte) 0xbb, + (byte) 0xcc, + (byte) 0xdd, + (byte) 0xee, + (byte) 0xff + })); + testNativeParcelUnparcel( + LowpanCredential.createMasterKey( + new byte[] { + (byte) 0x88, (byte) 0x99, (byte) 0xaa, (byte) 0xbb, (byte) 0xcc + }, + 15)); + } + + /** + * Write a {@link LowpanCredential} into an empty parcel and return the underlying data. + * + * @see unmarshall(byte[]) + */ + private static byte[] marshall(LowpanCredential addr) { + Parcel p = Parcel.obtain(); + addr.writeToParcel(p, /* flags */ 0); + p.setDataPosition(0); + return p.marshall(); + } + + /** + * Read raw bytes into a parcel, and read a {@link LowpanCredential} back out of them. + * + * @see marshall(LowpanCredential) + */ + private static LowpanCredential unmarshall(byte[] data) { + Parcel p = Parcel.obtain(); + p.unmarshall(data, 0, data.length); + p.setDataPosition(0); + return LowpanCredential.CREATOR.createFromParcel(p); + } +} diff --git a/lowpan/tests/java/android/net/lowpan/LowpanIdentityTest.java b/lowpan/tests/java/android/net/lowpan/LowpanIdentityTest.java new file mode 100644 index 000000000000..1242e55055f3 --- /dev/null +++ b/lowpan/tests/java/android/net/lowpan/LowpanIdentityTest.java @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2017 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 android.net.lowpan; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import android.os.Parcel; +import android.support.test.runner.AndroidJUnit4; +import android.test.suitebuilder.annotation.SmallTest; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class LowpanIdentityTest { + + static { + System.loadLibrary("frameworkslowpantestsjni"); + } + + private static native byte[] readAndWriteNative(byte[] inParcel); + + public void testNativeParcelUnparcel(LowpanIdentity original) { + byte[] inParcel = marshall(original); + byte[] outParcel = readAndWriteNative(inParcel); + LowpanIdentity roundTrip = unmarshall(outParcel); + + assertEquals(original, roundTrip); + assertEquals(original.hashCode(), roundTrip.hashCode()); + assertEquals(original.getName(), roundTrip.getName()); + assertArrayEquals(inParcel, outParcel); + } + + @Test + public void testNativeParcelUnparcel1() { + testNativeParcelUnparcel( + new LowpanIdentity.Builder() + .setName("TestNet1") + .setPanid(0x1234) + .setXpanid( + new byte[] { + (byte) 0x00, + (byte) 0x11, + (byte) 0x22, + (byte) 0x33, + (byte) 0x44, + (byte) 0x55, + (byte) 0x66, + (byte) 0x77 + }) + .setType(LowpanInterface.NETWORK_TYPE_THREAD_V1) + .setChannel(15) + .build()); + } + + @Test + public void testNativeParcelUnparcel2() { + testNativeParcelUnparcel( + new LowpanIdentity.Builder() + .setName("TestNet2") + .setPanid(0x5678) + .setXpanid( + new byte[] { + (byte) 0x88, + (byte) 0x99, + (byte) 0xaa, + (byte) 0xbb, + (byte) 0xcc, + (byte) 0xdd, + (byte) 0xee, + (byte) 0xff + }) + .setType("bork-bork-bork") + .setChannel(16) + .build()); + } + + @Test + public void testNativeParcelUnparcel3() { + testNativeParcelUnparcel(new LowpanIdentity.Builder().setName("TestNet3").build()); + } + + @Test + public void testNativeParcelUnparcel4() { + testNativeParcelUnparcel(new LowpanIdentity.Builder().build()); + } + + @Test + public void testNativeParcelUnparcel5() { + testNativeParcelUnparcel( + new LowpanIdentity.Builder() + .setRawName( + new byte[] { + (byte) 0x66, + (byte) 0x6F, + (byte) 0x6F, + (byte) 0xC2, + (byte) 0xAD, + (byte) 0xCD, + (byte) 0x8F, + (byte) 0xE1, + (byte) 0xA0, + (byte) 0x86, + (byte) 0xE1, + (byte) 0xA0, + (byte) 0x8B + }) + .build()); + } + + @Test + public void testStringPrep1() { + LowpanIdentity identity = + new LowpanIdentity.Builder() + .setRawName( + new byte[] { + (byte) 0x66, + (byte) 0x6F, + (byte) 0x6F, + (byte) 0x20, + (byte) 0xC2, + (byte) 0xAD, + (byte) 0xCD, + (byte) 0x8F, + (byte) 0xE1, + (byte) 0xA0, + (byte) 0x86, + (byte) 0xE1, + (byte) 0xA0, + (byte) 0x8B + }) + .build(); + + assertFalse(identity.isNameValid()); + } + + @Test + public void testStringPrep2() { + LowpanIdentity identity = + new LowpanIdentity.Builder() + .setRawName( + new byte[] { + (byte) 0x66, (byte) 0x6F, (byte) 0x6F, (byte) 0x20, (byte) 0x6F + }) + .build(); + + assertEquals("foo o", identity.getName()); + assertTrue(identity.isNameValid()); + } + + @Test + public void testStringPrep3() { + LowpanIdentity identity = new LowpanIdentity.Builder().setName("foo o").build(); + + assertTrue(identity.isNameValid()); + assertEquals("foo o", identity.getName()); + } + + /** + * Write a {@link LowpanIdentity} into an empty parcel and return the underlying data. + * + * @see unmarshall(byte[]) + */ + private static byte[] marshall(LowpanIdentity addr) { + Parcel p = Parcel.obtain(); + addr.writeToParcel(p, /* flags */ 0); + p.setDataPosition(0); + return p.marshall(); + } + + /** + * Read raw bytes into a parcel, and read a {@link LowpanIdentity} back out of them. + * + * @see marshall(LowpanIdentity) + */ + private static LowpanIdentity unmarshall(byte[] data) { + Parcel p = Parcel.obtain(); + p.unmarshall(data, 0, data.length); + p.setDataPosition(0); + return LowpanIdentity.CREATOR.createFromParcel(p); + } +} diff --git a/lowpan/tests/java/android/net/lowpan/LowpanInterfaceTest.java b/lowpan/tests/java/android/net/lowpan/LowpanInterfaceTest.java new file mode 100644 index 000000000000..a495d3d7a784 --- /dev/null +++ b/lowpan/tests/java/android/net/lowpan/LowpanInterfaceTest.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2017 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 android.net.lowpan; + +import static org.mockito.Mockito.*; + +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.os.Handler; +import android.os.IBinder; +import android.os.test.TestLooper; +import android.support.test.runner.AndroidJUnit4; +import android.test.suitebuilder.annotation.SmallTest; +import java.util.Map; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** Unit tests for android.net.lowpan.LowpanInterface. */ +@RunWith(AndroidJUnit4.class) +@SmallTest +public class LowpanInterfaceTest { + private static final String TEST_PACKAGE_NAME = "TestPackage"; + + @Mock Context mContext; + @Mock ILowpanInterface mLowpanInterfaceService; + @Mock IBinder mLowpanInterfaceBinder; + @Mock ApplicationInfo mApplicationInfo; + @Mock IBinder mAppBinder; + @Mock LowpanInterface.Callback mLowpanInterfaceCallback; + + private Handler mHandler; + private final TestLooper mTestLooper = new TestLooper(); + private ILowpanInterfaceListener mInterfaceListener; + private LowpanInterface mLowpanInterface; + private Map mPropertyMap; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + when(mContext.getApplicationInfo()).thenReturn(mApplicationInfo); + when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME); + when(mLowpanInterfaceService.getName()).thenReturn("wpan0"); + when(mLowpanInterfaceService.asBinder()).thenReturn(mLowpanInterfaceBinder); + + mLowpanInterface = + new LowpanInterface(mContext, mLowpanInterfaceService, mTestLooper.getLooper()); + } + + @Test + public void testStateChangedCallback() throws Exception { + // Register our callback + mLowpanInterface.registerCallback(mLowpanInterfaceCallback); + + // Verify a listener was added + verify(mLowpanInterfaceService) + .addListener( + argThat( + listener -> { + mInterfaceListener = listener; + return listener instanceof ILowpanInterfaceListener; + })); + + // Change some properties + mInterfaceListener.onStateChanged(LowpanInterface.STATE_OFFLINE); + mTestLooper.dispatchAll(); + + // Verify that the property was changed + verify(mLowpanInterfaceCallback) + .onStateChanged( + argThat(stateString -> stateString.equals(LowpanInterface.STATE_OFFLINE))); + } +} diff --git a/lowpan/tests/java/android/net/lowpan/LowpanManagerTest.java b/lowpan/tests/java/android/net/lowpan/LowpanManagerTest.java new file mode 100644 index 000000000000..3dd7504d8332 --- /dev/null +++ b/lowpan/tests/java/android/net/lowpan/LowpanManagerTest.java @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2017 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 android.net.lowpan; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.*; + +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.os.Handler; +import android.os.IBinder; +import android.os.test.TestLooper; +import android.support.test.runner.AndroidJUnit4; +import android.test.suitebuilder.annotation.SmallTest; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** Unit tests for android.net.lowpan.LowpanManager. */ +@RunWith(AndroidJUnit4.class) +@SmallTest +public class LowpanManagerTest { + private static final String TEST_PACKAGE_NAME = "TestPackage"; + + @Mock Context mContext; + @Mock ILowpanManager mLowpanService; + @Mock ILowpanInterface mLowpanInterfaceService; + @Mock IBinder mLowpanInterfaceBinder; + @Mock ApplicationInfo mApplicationInfo; + @Mock IBinder mAppBinder; + @Mock LowpanManager.Callback mLowpanManagerCallback; + + private Handler mHandler; + private final TestLooper mTestLooper = new TestLooper(); + private LowpanManager mLowpanManager; + + private ILowpanManagerListener mManagerListener; + private LowpanInterface mLowpanInterface; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + when(mContext.getApplicationInfo()).thenReturn(mApplicationInfo); + when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME); + + mLowpanManager = new LowpanManager(mContext, mLowpanService, mTestLooper.getLooper()); + } + + @Test + public void testGetEmptyInterfaceList() throws Exception { + when(mLowpanService.getInterfaceList()).thenReturn(new String[0]); + assertTrue(mLowpanManager.getInterfaceList().length == 0); + assertTrue(mLowpanManager.getInterface() == null); + } + + @Test + public void testGetInterfaceList() throws Exception { + when(mLowpanService.getInterfaceList()).thenReturn(new String[] {"wpan0"}); + when(mLowpanService.getInterface("wpan0")).thenReturn(mLowpanInterfaceService); + when(mLowpanInterfaceService.getName()).thenReturn("wpan0"); + when(mLowpanInterfaceService.asBinder()).thenReturn(mLowpanInterfaceBinder); + assertEquals(mLowpanManager.getInterfaceList().length, 1); + + LowpanInterface iface = mLowpanManager.getInterface(); + assertNotNull(iface); + assertEquals(iface.getName(), "wpan0"); + } + + @Test + public void testRegisterCallback() throws Exception { + when(mLowpanInterfaceService.getName()).thenReturn("wpan0"); + when(mLowpanInterfaceService.asBinder()).thenReturn(mLowpanInterfaceBinder); + + // Register our callback + mLowpanManager.registerCallback(mLowpanManagerCallback); + + // Verify a listener was added + verify(mLowpanService) + .addListener( + argThat( + listener -> { + mManagerListener = listener; + return listener instanceof ILowpanManagerListener; + })); + + // Add an interface + mManagerListener.onInterfaceAdded(mLowpanInterfaceService); + mTestLooper.dispatchAll(); + + // Verify that the interface was added + verify(mLowpanManagerCallback) + .onInterfaceAdded( + argThat( + iface -> { + mLowpanInterface = iface; + return iface instanceof LowpanInterface; + })); + verifyNoMoreInteractions(mLowpanManagerCallback); + + // This check causes the test to fail with a weird error, but I'm not sure why. + assertEquals(mLowpanInterface.getService(), mLowpanInterfaceService); + + // Verify that calling getInterface on the LowpanManager object will yield the same + // LowpanInterface object. + when(mLowpanService.getInterfaceList()).thenReturn(new String[] {"wpan0"}); + when(mLowpanService.getInterface("wpan0")).thenReturn(mLowpanInterfaceService); + assertEquals(mLowpanManager.getInterface(), mLowpanInterface); + + // Remove the service + mManagerListener.onInterfaceRemoved(mLowpanInterfaceService); + mTestLooper.dispatchAll(); + + // Verify that the interface was removed + verify(mLowpanManagerCallback).onInterfaceRemoved(mLowpanInterface); + } + + @Test + public void testUnregisterCallback() throws Exception { + when(mLowpanInterfaceService.getName()).thenReturn("wpan0"); + when(mLowpanInterfaceService.asBinder()).thenReturn(mLowpanInterfaceBinder); + + // Register our callback + mLowpanManager.registerCallback(mLowpanManagerCallback); + + // Verify a listener was added + verify(mLowpanService) + .addListener( + argThat( + listener -> { + mManagerListener = listener; + return listener instanceof ILowpanManagerListener; + })); + + // Add an interface + mManagerListener.onInterfaceAdded(mLowpanInterfaceService); + mTestLooper.dispatchAll(); + + // Verify that the interface was added + verify(mLowpanManagerCallback) + .onInterfaceAdded( + argThat( + iface -> { + mLowpanInterface = iface; + return iface instanceof LowpanInterface; + })); + verifyNoMoreInteractions(mLowpanManagerCallback); + + // Unregister our callback + mLowpanManager.unregisterCallback(mLowpanManagerCallback); + + // Verify the listener was removed + verify(mLowpanService).removeListener(mManagerListener); + + // Verify that the callback wasn't invoked. + verifyNoMoreInteractions(mLowpanManagerCallback); + } +} diff --git a/lowpan/tests/java/android/net/lowpan/LowpanProvisionTest.java b/lowpan/tests/java/android/net/lowpan/LowpanProvisionTest.java new file mode 100644 index 000000000000..3be2f26e93ab --- /dev/null +++ b/lowpan/tests/java/android/net/lowpan/LowpanProvisionTest.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2017 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 android.net.lowpan; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertArrayEquals; + +import android.os.Parcel; +import android.support.test.runner.AndroidJUnit4; +import android.test.suitebuilder.annotation.SmallTest; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class LowpanProvisionTest { + + static { + System.loadLibrary("frameworkslowpantestsjni"); + } + + private static native byte[] readAndWriteNative(byte[] inParcel); + + public void testNativeParcelUnparcel(LowpanProvision original) { + byte[] inParcel = marshall(original); + byte[] outParcel = readAndWriteNative(inParcel); + LowpanProvision roundTrip = unmarshall(outParcel); + + assertEquals(original, roundTrip); + assertArrayEquals(inParcel, outParcel); + } + + @Test + public void testNativeParcelUnparcel() { + testNativeParcelUnparcel( + new LowpanProvision.Builder() + .setLowpanIdentity( + new LowpanIdentity.Builder() + .setName("TestNet1") + .setPanid(0x1234) + .setXpanid( + new byte[] { + (byte) 0x00, + (byte) 0x11, + (byte) 0x22, + (byte) 0x33, + (byte) 0x44, + (byte) 0x55, + (byte) 0x66, + (byte) 0x77 + }) + .setType(LowpanInterface.NETWORK_TYPE_THREAD_V1) + .setChannel(15) + .build()) + .build()); + testNativeParcelUnparcel( + new LowpanProvision.Builder() + .setLowpanIdentity( + new LowpanIdentity.Builder() + .setName("TestNet2") + .setPanid(0x5678) + .setXpanid( + new byte[] { + (byte) 0x88, + (byte) 0x99, + (byte) 0xaa, + (byte) 0xbb, + (byte) 0xcc, + (byte) 0xdd, + (byte) 0xee, + (byte) 0xff + }) + .setType("bork-bork-bork") + .setChannel(16) + .build()) + .setLowpanCredential( + LowpanCredential.createMasterKey( + new byte[] { + (byte) 0x88, + (byte) 0x99, + (byte) 0xaa, + (byte) 0xbb, + (byte) 0xcc, + (byte) 0xdd, + (byte) 0xee, + (byte) 0xff + })) + .build()); + } + + /** + * Write a {@link LowpanProvision} into an empty parcel and return the underlying data. + * + * @see unmarshall(byte[]) + */ + private static byte[] marshall(LowpanProvision addr) { + Parcel p = Parcel.obtain(); + addr.writeToParcel(p, /* flags */ 0); + p.setDataPosition(0); + return p.marshall(); + } + + /** + * Read raw bytes into a parcel, and read a {@link LowpanProvision} back out of them. + * + * @see marshall(LowpanProvision) + */ + private static LowpanProvision unmarshall(byte[] data) { + Parcel p = Parcel.obtain(); + p.unmarshall(data, 0, data.length); + p.setDataPosition(0); + return LowpanProvision.CREATOR.createFromParcel(p); + } +} diff --git a/lowpan/tests/jni/LowpanBeaconInfoTest.cpp b/lowpan/tests/jni/LowpanBeaconInfoTest.cpp new file mode 100644 index 000000000000..efc5f1835497 --- /dev/null +++ b/lowpan/tests/jni/LowpanBeaconInfoTest.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2017 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. + */ + +#include + +#include + +#include "LowpanBeaconInfoTest.h" + +using android::net::lowpan::LowpanBeaconInfo; + +/** + * Reads exactly one LowpanBeaconInfo from 'parcelData' assuming that it is a Parcel. Any bytes afterward + * are ignored. + */ +static LowpanBeaconInfo unmarshall(JNIEnv* env, jbyteArray parcelData) { + const int length = env->GetArrayLength(parcelData); + + std::unique_ptr bytes(new uint8_t[length]); + env->GetByteArrayRegion(parcelData, 0, length, reinterpret_cast(bytes.get())); + + android::Parcel p; + p.setData(bytes.get(), length); + + LowpanBeaconInfo value; + value.readFromParcel(&p); + return value; +} + +/** + * Creates a Java byte[] array and writes the contents of 'addr' to it as a Parcel containing + * exactly one object. + * + * Every LowpanBeaconInfo maps to a unique parcel object, so both 'marshall(e, unmarshall(e, x))' and + * 'unmarshall(e, marshall(e, x))' should be fixed points. + */ +static jbyteArray marshall(JNIEnv* env, const LowpanBeaconInfo& addr) { + android::Parcel p; + addr.writeToParcel(&p); + const int length = p.dataSize(); + + jbyteArray parcelData = env->NewByteArray(length); + env->SetByteArrayRegion(parcelData, 0, length, reinterpret_cast(p.data())); + + return parcelData; +} + +extern "C" +JNIEXPORT jbyteArray Java_android_net_lowpan_LowpanBeaconInfoTest_readAndWriteNative(JNIEnv* env, jclass, + jbyteArray inParcel) { + const LowpanBeaconInfo value = unmarshall(env, inParcel); + return marshall(env, value); +} diff --git a/lowpan/tests/jni/LowpanBeaconInfoTest.h b/lowpan/tests/jni/LowpanBeaconInfoTest.h new file mode 100644 index 000000000000..1ba8eafc0802 --- /dev/null +++ b/lowpan/tests/jni/LowpanBeaconInfoTest.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2017 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. + */ + +#ifndef _ANDROID_NET_LOWPANBEACONINFOTEST_H_ +#define _ANDROID_NET_LOWPANBEACONINFOTEST_H_ + +#include +#include + +extern "C" +JNIEXPORT jbyteArray Java_android_net_lowpan_LowpanBeaconInfoTest_readAndWriteNative(JNIEnv* env, jclass, + jbyteArray inParcel); + +#endif // _ANDROID_NET_LOWPANBEACONINFOTEST_H_ diff --git a/lowpan/tests/jni/LowpanChannelInfoTest.cpp b/lowpan/tests/jni/LowpanChannelInfoTest.cpp new file mode 100644 index 000000000000..03bb72a6f95b --- /dev/null +++ b/lowpan/tests/jni/LowpanChannelInfoTest.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2017 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. + */ + +#include + +#include + +#include "LowpanChannelInfoTest.h" + +using android::net::lowpan::LowpanChannelInfo; + +/** + * Reads exactly one LowpanChannelInfo from 'parcelData' assuming that it is a Parcel. Any bytes afterward + * are ignored. + */ +static LowpanChannelInfo unmarshall(JNIEnv* env, jbyteArray parcelData) { + const int length = env->GetArrayLength(parcelData); + + std::unique_ptr bytes(new uint8_t[length]); + env->GetByteArrayRegion(parcelData, 0, length, reinterpret_cast(bytes.get())); + + android::Parcel p; + p.setData(bytes.get(), length); + + LowpanChannelInfo value; + value.readFromParcel(&p); + return value; +} + +/** + * Creates a Java byte[] array and writes the contents of 'addr' to it as a Parcel containing + * exactly one object. + * + * Every LowpanChannelInfo maps to a unique parcel object, so both 'marshall(e, unmarshall(e, x))' and + * 'unmarshall(e, marshall(e, x))' should be fixed points. + */ +static jbyteArray marshall(JNIEnv* env, const LowpanChannelInfo& addr) { + android::Parcel p; + addr.writeToParcel(&p); + const int length = p.dataSize(); + + jbyteArray parcelData = env->NewByteArray(length); + env->SetByteArrayRegion(parcelData, 0, length, reinterpret_cast(p.data())); + + return parcelData; +} + +extern "C" +JNIEXPORT jbyteArray Java_android_net_lowpan_LowpanChannelInfoTest_readAndWriteNative(JNIEnv* env, jclass, + jbyteArray inParcel) { + const LowpanChannelInfo value = unmarshall(env, inParcel); + return marshall(env, value); +} diff --git a/lowpan/tests/jni/LowpanChannelInfoTest.h b/lowpan/tests/jni/LowpanChannelInfoTest.h new file mode 100644 index 000000000000..3b29a90c3cdf --- /dev/null +++ b/lowpan/tests/jni/LowpanChannelInfoTest.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2017 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. + */ + +#ifndef _ANDROID_NET_LOWPANCHANNELINFOTEST_H_ +#define _ANDROID_NET_LOWPANCHANNELINFOTEST_H_ + +#include +#include + +extern "C" +JNIEXPORT jbyteArray Java_android_net_lowpan_LowpanChannelInfoTest_readAndWriteNative(JNIEnv* env, jclass, + jbyteArray inParcel); + +#endif // _ANDROID_NET_LOWPANCHANNELINFOTEST_H_ diff --git a/lowpan/tests/jni/LowpanCredentialTest.cpp b/lowpan/tests/jni/LowpanCredentialTest.cpp new file mode 100644 index 000000000000..fc860b29661e --- /dev/null +++ b/lowpan/tests/jni/LowpanCredentialTest.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2017 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. + */ + +#include + +#include + +#include "LowpanCredentialTest.h" + +using android::net::lowpan::LowpanCredential; + +/** + * Reads exactly one LowpanCredential from 'parcelData' assuming that it is a Parcel. Any bytes afterward + * are ignored. + */ +static LowpanCredential unmarshall(JNIEnv* env, jbyteArray parcelData) { + const int length = env->GetArrayLength(parcelData); + + std::unique_ptr bytes(new uint8_t[length]); + env->GetByteArrayRegion(parcelData, 0, length, reinterpret_cast(bytes.get())); + + android::Parcel p; + p.setData(bytes.get(), length); + + LowpanCredential value; + value.readFromParcel(&p); + return value; +} + +/** + * Creates a Java byte[] array and writes the contents of 'addr' to it as a Parcel containing + * exactly one object. + * + * Every LowpanCredential maps to a unique parcel object, so both 'marshall(e, unmarshall(e, x))' and + * 'unmarshall(e, marshall(e, x))' should be fixed points. + */ +static jbyteArray marshall(JNIEnv* env, const LowpanCredential& addr) { + android::Parcel p; + addr.writeToParcel(&p); + const int length = p.dataSize(); + + jbyteArray parcelData = env->NewByteArray(length); + env->SetByteArrayRegion(parcelData, 0, length, reinterpret_cast(p.data())); + + return parcelData; +} + +extern "C" +JNIEXPORT jbyteArray Java_android_net_lowpan_LowpanCredentialTest_readAndWriteNative(JNIEnv* env, jclass, + jbyteArray inParcel) { + const LowpanCredential value = unmarshall(env, inParcel); + return marshall(env, value); +} diff --git a/lowpan/tests/jni/LowpanCredentialTest.h b/lowpan/tests/jni/LowpanCredentialTest.h new file mode 100644 index 000000000000..9dd988938675 --- /dev/null +++ b/lowpan/tests/jni/LowpanCredentialTest.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2017 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. + */ + +#ifndef _ANDROID_NET_LOWPANCREDENTIALTEST_H_ +#define _ANDROID_NET_LOWPANCREDENTIALTEST_H_ + +#include +#include + +extern "C" +JNIEXPORT jbyteArray Java_android_net_lowpan_LowpanCredentialTest_readAndWriteNative(JNIEnv* env, jclass, + jbyteArray inParcel); + +#endif // _ANDROID_NET_LOWPANCREDENTIALTEST_H_ diff --git a/lowpan/tests/jni/LowpanIdentityTest.cpp b/lowpan/tests/jni/LowpanIdentityTest.cpp new file mode 100644 index 000000000000..1a9ad3338b04 --- /dev/null +++ b/lowpan/tests/jni/LowpanIdentityTest.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2017 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. + */ + +#include + +#include + +#include "LowpanIdentityTest.h" + +using android::net::lowpan::LowpanIdentity; + +/** + * Reads exactly one LowpanIdentity from 'parcelData' assuming that it is a Parcel. Any bytes afterward + * are ignored. + */ +static LowpanIdentity unmarshall(JNIEnv* env, jbyteArray parcelData) { + const int length = env->GetArrayLength(parcelData); + + std::unique_ptr bytes(new uint8_t[length]); + env->GetByteArrayRegion(parcelData, 0, length, reinterpret_cast(bytes.get())); + + android::Parcel p; + p.setData(bytes.get(), length); + + LowpanIdentity value; + value.readFromParcel(&p); + return value; +} + +/** + * Creates a Java byte[] array and writes the contents of 'addr' to it as a Parcel containing + * exactly one object. + * + * Every LowpanIdentity maps to a unique parcel object, so both 'marshall(e, unmarshall(e, x))' and + * 'unmarshall(e, marshall(e, x))' should be fixed points. + */ +static jbyteArray marshall(JNIEnv* env, const LowpanIdentity& addr) { + android::Parcel p; + addr.writeToParcel(&p); + const int length = p.dataSize(); + + jbyteArray parcelData = env->NewByteArray(length); + env->SetByteArrayRegion(parcelData, 0, length, reinterpret_cast(p.data())); + + return parcelData; +} + +extern "C" +JNIEXPORT jbyteArray Java_android_net_lowpan_LowpanIdentityTest_readAndWriteNative(JNIEnv* env, jclass, + jbyteArray inParcel) { + const LowpanIdentity value = unmarshall(env, inParcel); + return marshall(env, value); +} diff --git a/lowpan/tests/jni/LowpanIdentityTest.h b/lowpan/tests/jni/LowpanIdentityTest.h new file mode 100644 index 000000000000..1d2c4659108d --- /dev/null +++ b/lowpan/tests/jni/LowpanIdentityTest.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2017 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. + */ + +#ifndef _ANDROID_NET_LOWPANIDENTITYTEST_H_ +#define _ANDROID_NET_LOWPANIDENTITYTEST_H_ + +#include +#include + +extern "C" +JNIEXPORT jbyteArray Java_android_net_lowpan_LowpanIdentityTest_readAndWriteNative(JNIEnv* env, jclass, + jbyteArray inParcel); + +#endif // _ANDROID_NET_LOWPANIDENTITYTEST_H_ diff --git a/lowpan/tests/jni/LowpanProvisionTest.cpp b/lowpan/tests/jni/LowpanProvisionTest.cpp new file mode 100644 index 000000000000..95f64b6bd15a --- /dev/null +++ b/lowpan/tests/jni/LowpanProvisionTest.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2017 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. + */ + +#include + +#include + +#include "LowpanProvisionTest.h" + +using android::net::lowpan::LowpanProvision; + +/** + * Reads exactly one LowpanProvision from 'parcelData' assuming that it is a Parcel. Any bytes afterward + * are ignored. + */ +static LowpanProvision unmarshall(JNIEnv* env, jbyteArray parcelData) { + const int length = env->GetArrayLength(parcelData); + + std::unique_ptr bytes(new uint8_t[length]); + env->GetByteArrayRegion(parcelData, 0, length, reinterpret_cast(bytes.get())); + + android::Parcel p; + p.setData(bytes.get(), length); + + LowpanProvision value; + value.readFromParcel(&p); + return value; +} + +/** + * Creates a Java byte[] array and writes the contents of 'addr' to it as a Parcel containing + * exactly one object. + * + * Every LowpanProvision maps to a unique parcel object, so both 'marshall(e, unmarshall(e, x))' and + * 'unmarshall(e, marshall(e, x))' should be fixed points. + */ +static jbyteArray marshall(JNIEnv* env, const LowpanProvision& addr) { + android::Parcel p; + addr.writeToParcel(&p); + const int length = p.dataSize(); + + jbyteArray parcelData = env->NewByteArray(length); + env->SetByteArrayRegion(parcelData, 0, length, reinterpret_cast(p.data())); + + return parcelData; +} + +extern "C" +JNIEXPORT jbyteArray Java_android_net_lowpan_LowpanProvisionTest_readAndWriteNative(JNIEnv* env, jclass, + jbyteArray inParcel) { + const LowpanProvision value = unmarshall(env, inParcel); + return marshall(env, value); +} diff --git a/lowpan/tests/jni/LowpanProvisionTest.h b/lowpan/tests/jni/LowpanProvisionTest.h new file mode 100644 index 000000000000..49211b5ee45c --- /dev/null +++ b/lowpan/tests/jni/LowpanProvisionTest.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2017 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. + */ + +#ifndef _ANDROID_NET_LOWPANPROVISIONTEST_H_ +#define _ANDROID_NET_LOWPANPROVISIONTEST_H_ + +#include +#include + +extern "C" +JNIEXPORT jbyteArray Java_android_net_lowpan_LowpanProvisionTest_readAndWriteNative(JNIEnv* env, jclass, + jbyteArray inParcel); + +#endif // _ANDROID_NET_LOWPANPROVISIONTEST_H_ diff --git a/lowpan/tests/src/android/net/lowpan/LowpanInterfaceTest.java b/lowpan/tests/src/android/net/lowpan/LowpanInterfaceTest.java deleted file mode 100644 index 455ee08547bf..000000000000 --- a/lowpan/tests/src/android/net/lowpan/LowpanInterfaceTest.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2017 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 android.net.lowpan; - -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertNotNull; -import static org.mockito.Mockito.*; - -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.os.Handler; -import android.os.IBinder; -import android.os.test.TestLooper; -import android.support.test.runner.AndroidJUnit4; -import android.test.suitebuilder.annotation.SmallTest; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import java.util.Map; -import java.util.HashMap; - -/** Unit tests for android.net.lowpan.LowpanInterface. */ -@RunWith(AndroidJUnit4.class) -@SmallTest -public class LowpanInterfaceTest { - private static final String TEST_PACKAGE_NAME = "TestPackage"; - - @Mock Context mContext; - @Mock ILowpanInterface mLowpanInterfaceService; - @Mock IBinder mLowpanInterfaceBinder; - @Mock ApplicationInfo mApplicationInfo; - @Mock IBinder mAppBinder; - @Mock LowpanInterface.Callback mLowpanInterfaceCallback; - - private Handler mHandler; - private final TestLooper mTestLooper = new TestLooper(); - private ILowpanInterfaceListener mInterfaceListener; - private LowpanInterface mLowpanInterface; - private Map mPropertyMap; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - when(mContext.getApplicationInfo()).thenReturn(mApplicationInfo); - when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME); - when(mLowpanInterfaceService.getName()).thenReturn("wpan0"); - when(mLowpanInterfaceService.asBinder()).thenReturn(mLowpanInterfaceBinder); - - mLowpanInterface = new LowpanInterface(mContext, mLowpanInterfaceService, mTestLooper.getLooper()); - } - - @Test - public void testStateChangedCallback() throws Exception { - // Register our callback - mLowpanInterface.registerCallback(mLowpanInterfaceCallback); - - // Verify a listener was added - verify(mLowpanInterfaceService) - .addListener( - argThat( - listener -> { - mInterfaceListener = listener; - return listener instanceof ILowpanInterfaceListener; - })); - - // Build a changed property map - Map changedProperties = new HashMap<>(); - LowpanProperties.KEY_INTERFACE_STATE.putInMap(changedProperties, LowpanInterface.STATE_OFFLINE); - - // Change some properties - mInterfaceListener.onPropertiesChanged(changedProperties); - mTestLooper.dispatchAll(); - - // Verify that the property was changed - verify(mLowpanInterfaceCallback) - .onStateChanged( - argThat(stateString -> stateString.equals(LowpanInterface.STATE_OFFLINE))); - } -} diff --git a/lowpan/tests/src/android/net/lowpan/LowpanManagerTest.java b/lowpan/tests/src/android/net/lowpan/LowpanManagerTest.java deleted file mode 100644 index 481ad76e6790..000000000000 --- a/lowpan/tests/src/android/net/lowpan/LowpanManagerTest.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (C) 2017 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 android.net.lowpan; - -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertNotNull; -import static org.mockito.Mockito.*; - -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.os.Handler; -import android.os.IBinder; -import android.os.test.TestLooper; -import android.support.test.runner.AndroidJUnit4; -import android.test.suitebuilder.annotation.SmallTest; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -/** Unit tests for android.net.lowpan.LowpanManager. */ -@RunWith(AndroidJUnit4.class) -@SmallTest -public class LowpanManagerTest { - private static final String TEST_PACKAGE_NAME = "TestPackage"; - - @Mock Context mContext; - @Mock ILowpanManager mLowpanService; - @Mock ILowpanInterface mLowpanInterfaceService; - @Mock IBinder mLowpanInterfaceBinder; - @Mock ApplicationInfo mApplicationInfo; - @Mock IBinder mAppBinder; - @Mock LowpanManager.Callback mLowpanManagerCallback; - - private Handler mHandler; - private final TestLooper mTestLooper = new TestLooper(); - private LowpanManager mLowpanManager; - - private ILowpanManagerListener mManagerListener; - private LowpanInterface mLowpanInterface; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - when(mContext.getApplicationInfo()).thenReturn(mApplicationInfo); - when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME); - - mLowpanManager = new LowpanManager(mContext, mLowpanService, mTestLooper.getLooper()); - } - - @Test - public void testGetEmptyInterfaceList() throws Exception { - when(mLowpanService.getInterfaceList()).thenReturn(new String[0]); - assertTrue(mLowpanManager.getInterfaceList().length == 0); - assertTrue(mLowpanManager.getInterface() == null); - } - - @Test - public void testGetInterfaceList() throws Exception { - when(mLowpanService.getInterfaceList()).thenReturn(new String[] {"wpan0"}); - when(mLowpanService.getInterface("wpan0")).thenReturn(mLowpanInterfaceService); - when(mLowpanInterfaceService.getName()).thenReturn("wpan0"); - when(mLowpanInterfaceService.asBinder()).thenReturn(mLowpanInterfaceBinder); - assertEquals(mLowpanManager.getInterfaceList().length, 1); - - LowpanInterface iface = mLowpanManager.getInterface(); - assertNotNull(iface); - assertEquals(iface.getName(), "wpan0"); - } - - @Test - public void testRegisterCallback() throws Exception { - when(mLowpanInterfaceService.getName()).thenReturn("wpan0"); - when(mLowpanInterfaceService.asBinder()).thenReturn(mLowpanInterfaceBinder); - - // Register our callback - mLowpanManager.registerCallback(mLowpanManagerCallback); - - // Verify a listener was added - verify(mLowpanService) - .addListener( - argThat( - listener -> { - mManagerListener = listener; - return listener instanceof ILowpanManagerListener; - })); - - // Add an interface - mManagerListener.onInterfaceAdded(mLowpanInterfaceService); - mTestLooper.dispatchAll(); - - // Verify that the interface was added - verify(mLowpanManagerCallback) - .onInterfaceAdded( - argThat( - iface -> { - mLowpanInterface = iface; - return iface instanceof LowpanInterface; - })); - verifyNoMoreInteractions(mLowpanManagerCallback); - - // This check causes the test to fail with a weird error, but I'm not sure why. - assertEquals(mLowpanInterface.getService(), mLowpanInterfaceService); - - // Verify that calling getInterface on the LowpanManager object will yield the same - // LowpanInterface object. - when(mLowpanService.getInterfaceList()).thenReturn(new String[] {"wpan0"}); - when(mLowpanService.getInterface("wpan0")).thenReturn(mLowpanInterfaceService); - assertEquals(mLowpanManager.getInterface(), mLowpanInterface); - - // Remove the service - mManagerListener.onInterfaceRemoved(mLowpanInterfaceService); - mTestLooper.dispatchAll(); - - // Verify that the interface was removed - verify(mLowpanManagerCallback).onInterfaceRemoved(mLowpanInterface); - } - - @Test - public void testUnregisterCallback() throws Exception { - when(mLowpanInterfaceService.getName()).thenReturn("wpan0"); - when(mLowpanInterfaceService.asBinder()).thenReturn(mLowpanInterfaceBinder); - - // Register our callback - mLowpanManager.registerCallback(mLowpanManagerCallback); - - // Verify a listener was added - verify(mLowpanService) - .addListener( - argThat( - listener -> { - mManagerListener = listener; - return listener instanceof ILowpanManagerListener; - })); - - // Add an interface - mManagerListener.onInterfaceAdded(mLowpanInterfaceService); - mTestLooper.dispatchAll(); - - // Verify that the interface was added - verify(mLowpanManagerCallback) - .onInterfaceAdded( - argThat( - iface -> { - mLowpanInterface = iface; - return iface instanceof LowpanInterface; - })); - verifyNoMoreInteractions(mLowpanManagerCallback); - - // Unregister our callback - mLowpanManager.unregisterCallback(mLowpanManagerCallback); - - // Verify the listener was removed - verify(mLowpanService).removeListener(mManagerListener); - - // Verify that the callback wasn't invoked. - verifyNoMoreInteractions(mLowpanManagerCallback); - } -} -- cgit v1.2.3