diff options
author | Ben Dodson <bjdodson@google.com> | 2011-06-14 15:33:54 -0700 |
---|---|---|
committer | Ben Dodson <bjdodson@google.com> | 2011-06-15 15:13:03 -0700 |
commit | 2ef360deaff9f17aa72d5749ceee283cc80897af (patch) | |
tree | 57bf1d81193b58b7fa955b2e4fbe9e95229dddca /tests | |
parent | f6c56a2191d58e3f9f68e3e7d94908b04b9b66ff (diff) | |
download | android_packages_apps_Nfc-2ef360deaff9f17aa72d5749ceee283cc80897af.tar.gz android_packages_apps_Nfc-2ef360deaff9f17aa72d5749ceee283cc80897af.tar.bz2 android_packages_apps_Nfc-2ef360deaff9f17aa72d5749ceee283cc80897af.zip |
Merge snep p2p to master
Change-Id: Ic629c9a2ad348c1f352f39d7fc2be04edcf627e7
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Android.mk | 31 | ||||
-rw-r--r-- | tests/AndroidManifest.xml | 37 | ||||
-rw-r--r-- | tests/src/com/android/nfc/MockLlcpSocket.java | 83 | ||||
-rw-r--r-- | tests/src/com/android/nfc/snep/SnepBasicTests.java | 299 | ||||
-rw-r--r-- | tests/src/com/android/nfc/snep/SnepCustomClientTests.java | 95 | ||||
-rw-r--r-- | tests/src/com/android/nfc/snep/SnepDefaultClientTests.java | 91 | ||||
-rw-r--r-- | tests/src/com/android/nfc/snep/SnepValidationClientTests.java | 201 | ||||
-rw-r--r-- | tests/src/com/android/nfc/snep/SnepValidationServerTests.java | 135 |
8 files changed, 972 insertions, 0 deletions
diff --git a/tests/Android.mk b/tests/Android.mk new file mode 100644 index 00000000..3ba329b8 --- /dev/null +++ b/tests/Android.mk @@ -0,0 +1,31 @@ +# Copyright 2008, 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. + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +# We only want this apk build for tests. +LOCAL_MODULE_TAGS := tests + +LOCAL_JAVA_LIBRARIES := android.test.runner + +# Include all test java files. +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_PACKAGE_NAME := NfcTests +LOCAL_CERTIFICATE := platform + +LOCAL_INSTRUMENTATION_FOR := Nfc + +include $(BUILD_PACKAGE) diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml new file mode 100644 index 00000000..035bb4c2 --- /dev/null +++ b/tests/AndroidManifest.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2011 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 name must be unique so suffix with "tests" so package loader doesn't ignore us --> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.nfc.tests"> + + <!-- We add an application tag here just so that we can indicate that + this package needs to link against the android.test library, + which is needed when building test cases. --> + <application> + <uses-library android:name="android.test.runner" /> + </application> + + <!-- + This declares that this app uses the instrumentation test runner targeting + the package of com.android.email. To run the tests use the command: + "adb shell am instrument -w com.android.email.tests/android.test.InstrumentationTestRunner" + --> + <instrumentation android:name="android.test.InstrumentationTestRunner" + android:targetPackage="com.android.nfc3" + android:label="Tests for Nfc."/> + +</manifest> diff --git a/tests/src/com/android/nfc/MockLlcpSocket.java b/tests/src/com/android/nfc/MockLlcpSocket.java new file mode 100644 index 00000000..4265111a --- /dev/null +++ b/tests/src/com/android/nfc/MockLlcpSocket.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2011 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.nfc; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.LinkedList; +import java.util.List; + +import android.util.Log; + +import com.android.internal.nfc.LlcpException; +import com.android.internal.nfc.LlcpSocket; + +public class MockLlcpSocket extends LlcpSocket { + private static final String TAG = "mockLlcpSocket"; + private MockLlcpSocket mPairedSocket; + private List<byte[]> mReceivedPackets = new LinkedList<byte[]>(); + private boolean mClosed = false; + + public MockLlcpSocket() { + super(null, -1); + } + + @Override + public void close() throws IOException { + mClosed = true; + mPairedSocket.mClosed = true; + } + + @Override + public void connect(int sap) throws IOException, LlcpException { + throw new UnsupportedOperationException("Use MockLlcpSocket.bind(client, server)"); + } + + @Override + public void send(byte[] data) throws IOException { + if (mClosed || mPairedSocket == null) { + throw new IOException("Socket not connected"); + } + synchronized (mPairedSocket.mReceivedPackets) { + Log.d(TAG, "sending packet"); + mPairedSocket.mReceivedPackets.add(data); + mPairedSocket.mReceivedPackets.notify(); + } + } + + @Override + public int receive(byte[] receiveBuffer) throws IOException { + synchronized (mReceivedPackets) { + while (!mClosed && mReceivedPackets.size() == 0) { + try { + mReceivedPackets.wait(1000); + } catch (InterruptedException e) {} + } + if (mClosed) { + throw new IOException("Socket closed."); + } + byte[] arr = mReceivedPackets.remove(0); + System.arraycopy(arr, 0, receiveBuffer, 0, arr.length); + return arr.length; + } + } + + public static void bind(MockLlcpSocket client, MockLlcpSocket server) { + client.mPairedSocket = server; + server.mPairedSocket = client; + } +}
\ No newline at end of file diff --git a/tests/src/com/android/nfc/snep/SnepBasicTests.java b/tests/src/com/android/nfc/snep/SnepBasicTests.java new file mode 100644 index 00000000..bec570df --- /dev/null +++ b/tests/src/com/android/nfc/snep/SnepBasicTests.java @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2011 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.nfc.snep; + +import java.io.IOException; + +import com.android.nfc.MockLlcpSocket; +import com.android.nfc.snep.SnepMessage; + +import android.nfc.NdefMessage; +import android.nfc.NdefRecord; +import android.test.AndroidTestCase; +import android.util.Log; + +import com.android.internal.nfc.LlcpSocket; + +/** + * Tests the SNEP cleint/server interfaces using a mock LLCP socket. + */ +public class SnepBasicTests extends AndroidTestCase { + private static final String TAG = "snepBasicTests"; + private static final int MIU = 250; + private static final int ACCEPTABLE_LENGTH = 2*1024; + + public void testGetSmallNdef() throws IOException { + MockLlcpSocket clientSocket = new MockLlcpSocket(); + MockLlcpSocket serverSocket = new MockLlcpSocket(); + MockLlcpSocket.bind(clientSocket, serverSocket); + + final SnepMessenger client = new SnepMessenger(true, clientSocket, MIU); + final SnepMessenger server = new SnepMessenger(false, serverSocket, MIU); + + new Thread() { + public void run() { + try { + SnepServer.handleRequest(server, mCallback); + } catch (Exception e) { + Log.e(TAG, "error getting message", e); + } + }; + }.start(); + + SnepMessage response = null; + try { + client.sendMessage(SnepMessage.getGetRequest(ACCEPTABLE_LENGTH, getSmallNdef())); + response = client.getMessage(); + } catch (SnepException e) { + throw new IOException("Failed to retrieve SNEP message", e); + } + + assertNotNull(response); + assertEquals(SnepMessage.RESPONSE_SUCCESS, response.getField()); + } + + public void testGetLargeNdef() throws IOException { + MockLlcpSocket clientSocket = new MockLlcpSocket(); + MockLlcpSocket serverSocket = new MockLlcpSocket(); + MockLlcpSocket.bind(clientSocket, serverSocket); + + final SnepMessenger client = new SnepMessenger(true, clientSocket, MIU); + final SnepMessenger server = new SnepMessenger(false, serverSocket, MIU); + + new Thread() { + public void run() { + try { + SnepServer.handleRequest(server, mCallback); + } catch (Exception e) { + Log.e(TAG, "error getting message", e); + } + }; + }.start(); + + SnepMessage response = null; + try { + client.sendMessage(SnepMessage.getGetRequest(ACCEPTABLE_LENGTH, getNdef(900))); + response = client.getMessage(); + } catch (SnepException e) { + throw new IOException("Failed to retrieve SNEP message", e); + } + + assertNotNull(response); + assertEquals(SnepMessage.RESPONSE_SUCCESS, response.getField()); + } + + public void testGetExcessiveNdef() throws IOException { + MockLlcpSocket clientSocket = new MockLlcpSocket(); + MockLlcpSocket serverSocket = new MockLlcpSocket(); + MockLlcpSocket.bind(clientSocket, serverSocket); + + final SnepMessenger client = new SnepMessenger(true, clientSocket, MIU); + final SnepMessenger server = new SnepMessenger(false, serverSocket, MIU); + + new Thread() { + public void run() { + try { + SnepServer.handleRequest(server, mCallback); + } catch (Exception e) { + Log.e(TAG, "error getting message", e); + } + }; + }.start(); + + SnepMessage response = null; + try { + client.sendMessage(SnepMessage.getGetRequest(10, getSmallNdef())); + response = client.getMessage(); + } catch (SnepException e) { + throw new IOException("Failed to retrieve SNEP message", e); + } + + assertNotNull(response); + assertEquals(SnepMessage.RESPONSE_EXCESS_DATA, response.getField()); + } + + public void testPutSmallNdef() throws IOException { + MockLlcpSocket clientSocket = new MockLlcpSocket(); + MockLlcpSocket serverSocket = new MockLlcpSocket(); + MockLlcpSocket.bind(clientSocket, serverSocket); + + final SnepMessenger client = new SnepMessenger(true, clientSocket, MIU); + final SnepMessenger server = new SnepMessenger(false, serverSocket, MIU); + + new Thread() { + public void run() { + try { + SnepServer.handleRequest(server, mCallback); + } catch (Exception e) { + Log.e(TAG, "error getting message", e); + } + }; + }.start(); + + SnepMessage response = null; + try { + client.sendMessage(SnepMessage.getPutRequest(getSmallNdef())); + response = client.getMessage(); + } catch (SnepException e) { + throw new IOException("Failed to retrieve SNEP message", e); + } + + assertNotNull(response); + assertEquals(SnepMessage.RESPONSE_SUCCESS, response.getField()); + } + + public void testPutLargeNdef() throws IOException { + MockLlcpSocket clientSocket = new MockLlcpSocket(); + MockLlcpSocket serverSocket = new MockLlcpSocket(); + MockLlcpSocket.bind(clientSocket, serverSocket); + + final SnepMessenger client = new SnepMessenger(true, clientSocket, MIU); + final SnepMessenger server = new SnepMessenger(false, serverSocket, MIU); + + new Thread() { + public void run() { + try { + SnepServer.handleRequest(server, mCallback); + } catch (Exception e) { + Log.e(TAG, "error getting message", e); + } + }; + }.start(); + + SnepMessage response = null; + try { + client.sendMessage(SnepMessage.getPutRequest(getNdef(900))); + response = client.getMessage(); + } catch (SnepException e) { + throw new IOException("Failed to retrieve SNEP message", e); + } + + assertNotNull(response); + assertEquals(SnepMessage.RESPONSE_SUCCESS, response.getField()); + } + + public void testUnsupportedVersion() throws IOException { + MockLlcpSocket clientSocket = new MockLlcpSocket(); + MockLlcpSocket serverSocket = new MockLlcpSocket(); + MockLlcpSocket.bind(clientSocket, serverSocket); + + final SnepMessenger client = new SnepMessenger(true, clientSocket, MIU); + final SnepMessenger server = new SnepMessenger(false, serverSocket, MIU); + + new Thread() { + public void run() { + try { + SnepServer.handleRequest(server, mCallback); + } catch (Exception e) { + Log.e(TAG, "error getting message", e); + } + }; + }.start(); + + SnepMessage response = null; + try { + NdefMessage ndef = getSmallNdef(); + SnepMessage request = new SnepMessage( + (byte)2, SnepMessage.REQUEST_PUT, ndef.toByteArray().length, 0, ndef); + client.sendMessage(request); + response = client.getMessage(); + } catch (SnepException e) { + throw new IOException("Failed to retrieve SNEP message", e); + } + + assertNotNull(response); + assertEquals(SnepMessage.RESPONSE_UNSUPPORTED_VERSION, response.getField()); + } + + public void testDifferentMinorVersion() throws IOException { + MockLlcpSocket clientSocket = new MockLlcpSocket(); + MockLlcpSocket serverSocket = new MockLlcpSocket(); + MockLlcpSocket.bind(clientSocket, serverSocket); + + final SnepMessenger client = new SnepMessenger(true, clientSocket, MIU); + final SnepMessenger server = new SnepMessenger(false, serverSocket, MIU); + + new Thread() { + public void run() { + try { + SnepServer.handleRequest(server, mCallback); + } catch (Exception e) { + Log.e(TAG, "error getting message", e); + } + }; + }.start(); + + byte version = (0xF0 & (SnepMessage.VERSION_MAJOR << 4)) | + (0x0F & (SnepMessage.VERSION_MINOR + 1)); + SnepMessage response = null; + try { + NdefMessage ndef = getSmallNdef(); + SnepMessage request = new SnepMessage( + version, SnepMessage.REQUEST_PUT, ndef.toByteArray().length, 0, ndef); + client.sendMessage(request); + response = client.getMessage(); + } catch (SnepException e) { + throw new IOException("Failed to retrieve SNEP message", e); + } + + assertNotNull(response); + assertEquals(SnepMessage.RESPONSE_SUCCESS, response.getField()); + } + + private NdefMessage getSmallNdef() { + NdefRecord rec = new NdefRecord(NdefRecord.TNF_ABSOLUTE_URI, NdefRecord.RTD_URI, + new byte[0], "http://android.com".getBytes()); + return new NdefMessage(new NdefRecord[] { rec }); + } + + private NdefMessage getNdef(int size) { + StringBuffer string = new StringBuffer(size); + for (int i = 0; i < size; i++) { + string.append('A' + (i % 26)); + } + NdefRecord rec = new NdefRecord(NdefRecord.TNF_MIME_MEDIA, "text/plain".getBytes(), + new byte[0], string.toString().getBytes()); + return new NdefMessage(new NdefRecord[] { rec }); + } + + private class SnepMessageContainer { + SnepMessage message; + } + + /** + * A SNEP Server implementation that accepts PUT requests for all ndef + * messages and responds to GET requests with acceptable length greater + * than or equal to 1024. + */ + final SnepServer.Callback mCallback = new SnepServer.Callback() { + private static final int GET_LENGTH = 1024; + + @Override + public SnepMessage doPut(NdefMessage msg) { + return SnepMessage.getSuccessResponse(null); + } + + @Override + public SnepMessage doGet(int acceptableLength, NdefMessage msg) { + if (GET_LENGTH <= acceptableLength) { + return SnepMessage.getSuccessResponse(getSmallNdef()); + } else { + return SnepMessage.getMessage(SnepMessage.RESPONSE_EXCESS_DATA); + } + } + }; +}
\ No newline at end of file diff --git a/tests/src/com/android/nfc/snep/SnepCustomClientTests.java b/tests/src/com/android/nfc/snep/SnepCustomClientTests.java new file mode 100644 index 00000000..4f96aef2 --- /dev/null +++ b/tests/src/com/android/nfc/snep/SnepCustomClientTests.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2011 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.nfc.snep; + +import java.io.IOException; + +import com.android.nfc.snep.SnepClient; +import com.android.nfc.snep.SnepMessage; +import com.android.nfc.snep.SnepServer; + +import android.nfc.NdefMessage; +import android.nfc.NdefRecord; +import android.test.AndroidTestCase; +import android.util.Log; + +import java.lang.StringBuffer; + +/** + * Tests connectivity to a custom SNEP server, using a physical NFC device. + */ +public class SnepCustomClientTests extends AndroidTestCase { + private static final String TAG = "nfcTest"; + + public void setUp() { + Log.d(TAG, "Waiting for service to restart..."); + try { + Thread.sleep(6000); + } catch (InterruptedException e) {} + Log.d(TAG, "Running test."); + } + + public void testPutSmall() throws IOException { + SnepClient client = getSnepClient(); + client.connect(); + client.put(getSmallNdef()); + client.close(); + } + + public void testPutLarge() throws IOException { + SnepClient client = getSnepClient(); + client.connect(); + client.put(getLargeNdef()); + client.close(); + } + + public void testPutTwice() throws IOException { + SnepClient client = getSnepClient(); + client.connect(); + client.put(getSmallNdef()); + client.put(getSmallNdef()); + client.close(); + } + + public void testGetSmall() throws IOException { + SnepClient client = getSnepClient(); + client.connect(); + SnepMessage response = client.get(getSmallNdef()); + assertEquals(SnepMessage.RESPONSE_SUCCESS, response.getField()); + } + + private NdefMessage getSmallNdef() { + NdefRecord rec = new NdefRecord(NdefRecord.TNF_ABSOLUTE_URI, NdefRecord.RTD_URI, + new byte[0], "http://android.com".getBytes()); + return new NdefMessage(new NdefRecord[] { rec }); + } + + private NdefMessage getLargeNdef() { + int size = 3000; + StringBuffer string = new StringBuffer(size); + for (int i = 0; i < size; i++) { + string.append('A' + (i % 26)); + } + NdefRecord rec = new NdefRecord(NdefRecord.TNF_MIME_MEDIA, "text/plain".getBytes(), + new byte[0], string.toString().getBytes()); + return new NdefMessage(new NdefRecord[] { rec }); + } + + private SnepClient getSnepClient() { + return new SnepClient(SnepValidationServerTests.SERVICE_NAME); + } +} diff --git a/tests/src/com/android/nfc/snep/SnepDefaultClientTests.java b/tests/src/com/android/nfc/snep/SnepDefaultClientTests.java new file mode 100644 index 00000000..b8849435 --- /dev/null +++ b/tests/src/com/android/nfc/snep/SnepDefaultClientTests.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2011 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.nfc.snep; + +import java.io.IOException; + +import com.android.nfc.snep.SnepClient; +import com.android.nfc.snep.SnepMessage; +import com.android.nfc.snep.SnepServer; + +import android.nfc.NdefMessage; +import android.nfc.NdefRecord; +import android.test.AndroidTestCase; +import android.util.Log; + +import java.lang.StringBuffer; + +/** + * Tests connectivity to a default SNEP server, using a physical NFC device. + */ +public class SnepDefaultClientTests extends AndroidTestCase { + private static final String TAG = "nfcTest"; + + public void setUp() { + Log.d(TAG, "Waiting for service to restart..."); + try { + Thread.sleep(6000); + } catch (InterruptedException e) {} + Log.d(TAG, "Running test."); + } + + public void testPutSmallToDefaultServer() throws IOException { + SnepClient client = new SnepClient(); + client.connect(); + client.put(getSmallNdef()); + client.close(); + } + + public void testPutLargeToDefaultServer() throws IOException { + SnepClient client = new SnepClient(); + client.connect(); + client.put(getLargeNdef()); + client.close(); + } + + public void testPutTwiceToDefaultServer() throws IOException { + SnepClient client = new SnepClient(); + client.connect(); + client.put(getSmallNdef()); + client.put(getSmallNdef()); + client.close(); + } + + public void testGetFail() throws IOException { + SnepClient client = new SnepClient(); + client.connect(); + SnepMessage response = client.get(getSmallNdef()); + assertEquals(SnepMessage.RESPONSE_NOT_IMPLEMENTED, response.getField()); + } + + private NdefMessage getSmallNdef() { + NdefRecord rec = new NdefRecord(NdefRecord.TNF_ABSOLUTE_URI, NdefRecord.RTD_URI, + new byte[0], "http://android.com".getBytes()); + return new NdefMessage(new NdefRecord[] { rec }); + } + + private NdefMessage getLargeNdef() { + int size = 3000; + StringBuffer string = new StringBuffer(size); + for (int i = 0; i < size; i++) { + string.append('A' + (i % 26)); + } + NdefRecord rec = new NdefRecord(NdefRecord.TNF_MIME_MEDIA, "text/plain".getBytes(), + new byte[0], string.toString().getBytes()); + return new NdefMessage(new NdefRecord[] { rec }); + } +} diff --git a/tests/src/com/android/nfc/snep/SnepValidationClientTests.java b/tests/src/com/android/nfc/snep/SnepValidationClientTests.java new file mode 100644 index 00000000..1b0cedf0 --- /dev/null +++ b/tests/src/com/android/nfc/snep/SnepValidationClientTests.java @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2011 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.nfc.snep; + +import java.io.IOException; + +import com.android.nfc.snep.SnepClient; +import com.android.nfc.snep.SnepMessage; +import com.android.nfc.snep.SnepServer; + +import android.nfc.NdefMessage; +import android.nfc.NdefRecord; +import android.test.AndroidTestCase; +import android.util.Log; + +import java.lang.StringBuffer; + +/** + * Tests connectivity to a custom SNEP server, using a physical NFC device. + */ +public class SnepValidationClientTests extends AndroidTestCase { + private static final String TAG = "nfcTest"; + + private static final int FRAGMENT_LENGTH = 50; + + public static final String SERVICE_NAME = SnepValidationServerTests.SERVICE_NAME; + + public void setUp() { + Log.d(TAG, "Waiting for service to restart..."); + try { + Thread.sleep(8000); + } catch (InterruptedException e) { + } + Log.d(TAG, "Running test."); + } + + public void testNonFragmented() throws IOException { + try { + SnepClient client = getSnepClient(); + NdefMessage msg = getSmallNdef(); + Log.d(TAG, "Connecting to service " + SERVICE_NAME + "..."); + client.connect(); + Log.d(TAG, "Putting ndef message..."); + client.put(msg); + + Log.d(TAG, "Getting ndef message..."); + byte[] responseBytes = client.get(msg).getNdefMessage().toByteArray(); + int i = 0; + byte[] msgBytes = msg.toByteArray(); + Log.d(TAG, "Done. Checking " + msgBytes.length + " bytes."); + for (byte b : msgBytes) { + assertEquals(b, responseBytes[i++]); + } + Log.d(TAG, "Closing client."); + client.close(); + } catch (IOException e) { + Log.d(TAG, "Test failed.", e); + throw e; + } + } + + public void testFragmented() throws IOException { + try { + SnepClient client = getSnepClient(); + NdefMessage msg = getLargeNdef(); + Log.d(TAG, "Connecting to service " + SERVICE_NAME + "..."); + client.connect(); + Log.d(TAG, "Putting ndef message of size " + msg.toByteArray().length + "..."); + client.put(msg); + + Log.d(TAG, "Getting ndef message..."); + byte[] responseBytes = client.get(msg).getNdefMessage().toByteArray(); + int i = 0; + byte[] msgBytes = msg.toByteArray(); + Log.d(TAG, "Done. Checking " + msgBytes.length + " bytes."); + for (byte b : msgBytes) { + assertEquals(b, responseBytes[i++]); + } + client.close(); + } catch (IOException e) { + Log.d(TAG, "Error running fragmented", e); + throw e; + } + } + + public void testMultipleNdef() throws IOException { + try { + SnepClient client = getSnepClient(); + Log.d(TAG, "Connecting to service " + SERVICE_NAME + "..."); + client.connect(); + + NdefMessage msgA = getSmallNdef(); + NdefMessage msgB = getLargeNdef(); + + Log.d(TAG, "Putting ndef message A..."); + client.put(msgA); + Log.d(TAG, "Putting ndef message B..."); + client.put(msgB); + + byte[] responseBytes; + byte[] msgBytes; + int i; + + Log.d(TAG, "Getting ndef message A..."); + responseBytes = client.get(msgA).getNdefMessage().toByteArray(); + i = 0; + msgBytes = msgA.toByteArray(); + Log.d(TAG, "Done. Checking " + msgBytes.length + " bytes."); + for (byte b : msgBytes) { + assertEquals(b, responseBytes[i++]); + } + + Log.d(TAG, "Getting ndef message B..."); + responseBytes = client.get(msgB).getNdefMessage().toByteArray(); + i = 0; + msgBytes = msgB.toByteArray(); + Log.d(TAG, "Done. Checking " + msgBytes.length + " bytes."); + for (byte b : msgBytes) { + assertEquals(b, responseBytes[i++]); + } + + Log.d(TAG, "Closing client."); + client.close(); + } catch (IOException e) { + Log.d(TAG, "Test failed.", e); + throw e; + } + } + + public void testUnavailable() throws IOException { + try { + SnepClient client = getSnepClient(); + NdefMessage msg = getSmallNdef(); + Log.d(TAG, "Connecting to service " + SERVICE_NAME + "..."); + client.connect(); + + Log.d(TAG, "Getting ndef message..."); + SnepMessage response = client.get(msg); + assertEquals(SnepMessage.RESPONSE_NOT_FOUND, response.getField()); + Log.d(TAG, "Closing client."); + client.close(); + } catch (IOException e) { + Log.d(TAG, "Test failed.", e); + throw e; + } + } + + public void testUndeliverable() throws IOException { + try { + SnepClient client = new SnepClient(SERVICE_NAME, 100, FRAGMENT_LENGTH); + NdefMessage msg = getLargeNdef(); + Log.d(TAG, "Connecting to service " + SERVICE_NAME + "..."); + client.connect(); + Log.d(TAG, "Putting ndef message of size " + msg.toByteArray().length + "..."); + client.put(msg); + + Log.d(TAG, "Getting ndef message..."); + SnepMessage response = client.get(msg); + assertEquals(SnepMessage.RESPONSE_EXCESS_DATA, response.getField()); + client.close(); + } catch (IOException e) { + Log.d(TAG, "Error running fragmented", e); + throw e; + } + } + + private NdefMessage getSmallNdef() { + NdefRecord rec = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, + new byte[] { 'A' }, "http://android.com".getBytes()); + return new NdefMessage(new NdefRecord[] { rec }); + } + + private NdefMessage getLargeNdef() { + int size = 500; + StringBuffer string = new StringBuffer(size); + for (int i = 0; i < size; i++) { + string.append('A' + (i % 26)); + } + NdefRecord rec = new NdefRecord(NdefRecord.TNF_MIME_MEDIA, "text/plain".getBytes(), + new byte[] { 'B' }, string.toString().getBytes()); + return new NdefMessage(new NdefRecord[] { rec }); + } + + private SnepClient getSnepClient() { + return new SnepClient(SERVICE_NAME, FRAGMENT_LENGTH); + } +} diff --git a/tests/src/com/android/nfc/snep/SnepValidationServerTests.java b/tests/src/com/android/nfc/snep/SnepValidationServerTests.java new file mode 100644 index 00000000..1a35764b --- /dev/null +++ b/tests/src/com/android/nfc/snep/SnepValidationServerTests.java @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2011 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.nfc.snep; + +import java.io.IOException; + +import com.android.nfc.snep.SnepClient; +import com.android.nfc.snep.SnepMessage; +import com.android.nfc.snep.SnepServer; + +import android.nfc.NdefMessage; +import android.nfc.NdefRecord; +import android.test.AndroidTestCase; +import android.util.Log; + +import java.lang.StringBuffer; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * Uses the Android testing instrumentation framework to run a listening SNEP + * server. + */ +public class SnepValidationServerTests extends AndroidTestCase implements SnepServer.Callback { + static final int SERVICE_SAP = 0x11; + static final String SERVICE_NAME = "urn:nfc:xsn:nfc-forum.org:snep-validation"; + private static final String TAG = "nfcTest"; + + private Map<ByteArrayWrapper, NdefMessage> mStoredNdef = + new HashMap<ByteArrayWrapper, NdefMessage>(); + private static final ByteArrayWrapper DEFAULT_NDEF = new ByteArrayWrapper(new byte[] {}); + + public void setUp() { + Log.d(TAG, "Waiting for service to restart..."); + try { + Thread.sleep(6000); + } catch (InterruptedException e) { + } + Log.d(TAG, "Running test."); + } + + public void testStartSnepServer() throws IOException { + SnepServer server = new SnepServer(SERVICE_NAME, SERVICE_SAP, this); + server.start(); + + try { + Thread.sleep(24 * 60 * 60 * 1000); + } catch (InterruptedException e) { + + } + } + + private NdefMessage getSmallNdef() { + NdefRecord rec = new NdefRecord(NdefRecord.TNF_ABSOLUTE_URI, NdefRecord.RTD_URI, + new byte[0], "http://android.com".getBytes()); + return new NdefMessage(new NdefRecord[] { rec }); + } + + private NdefMessage getLargeNdef() { + int size = 3000; + StringBuffer string = new StringBuffer(size); + for (int i = 0; i < size; i++) { + string.append('A' + (i % 26)); + } + NdefRecord rec = new NdefRecord(NdefRecord.TNF_MIME_MEDIA, "text/plain".getBytes(), + new byte[0], string.toString().getBytes()); + return new NdefMessage(new NdefRecord[] { rec }); + } + + static class ByteArrayWrapper { + private final byte[] data; + + public ByteArrayWrapper(byte[] data) { + if (data == null) { + throw new NullPointerException(); + } + this.data = data; + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof ByteArrayWrapper)) { + return false; + } + return Arrays.equals(data, ((ByteArrayWrapper) other).data); + } + + @Override + public int hashCode() { + return Arrays.hashCode(data); + } + } + + @Override + public SnepMessage doPut(NdefMessage msg) { + Log.d(TAG, "doPut()"); + NdefRecord record = msg.getRecords()[0]; + ByteArrayWrapper id = (record.getId().length > 0) ? + new ByteArrayWrapper(record.getId()) : DEFAULT_NDEF; + mStoredNdef.put(id, msg); + return SnepMessage.getMessage(SnepMessage.RESPONSE_SUCCESS); + } + + @Override + public SnepMessage doGet(int acceptableLength, NdefMessage msg) { + Log.d(TAG, "doGet()"); + NdefRecord record = msg.getRecords()[0]; + ByteArrayWrapper id = (record.getId().length > 0) ? + new ByteArrayWrapper(record.getId()) : DEFAULT_NDEF; + NdefMessage result = mStoredNdef.get(id); + + if (result == null) { + return SnepMessage.getMessage(SnepMessage.RESPONSE_NOT_FOUND); + } + if (acceptableLength < result.toByteArray().length) { + return SnepMessage.getMessage(SnepMessage.RESPONSE_EXCESS_DATA); + } + return SnepMessage.getSuccessResponse(result); + } +} |