package android.core;
import android.test.AndroidTestCase;
import android.os.Bundle;
import android.os.Parcel;
import android.os.StrictMode;
import android.net.nsd.NsdServiceInfo;
import android.util.Log;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class NsdServiceInfoTest extends AndroidTestCase {
public final static InetAddress LOCALHOST;
static {
// Because test.
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
InetAddress _host = null;
try {
_host = InetAddress.getLocalHost();
} catch (UnknownHostException e) { }
LOCALHOST = _host;
}
public void testLimits() throws Exception {
NsdServiceInfo info = new NsdServiceInfo();
// Non-ASCII keys.
boolean exceptionThrown = false;
try {
info.setAttribute("猫", "meow");
} catch (IllegalArgumentException e) {
exceptionThrown = true;
}
assertTrue(exceptionThrown);
assertEmptyServiceInfo(info);
// ASCII keys with '=' character.
exceptionThrown = false;
try {
info.setAttribute("kitten=", "meow");
} catch (IllegalArgumentException e) {
exceptionThrown = true;
}
assertTrue(exceptionThrown);
assertEmptyServiceInfo(info);
// Single key + value length too long.
exceptionThrown = false;
try {
String longValue = "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" +
"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" +
"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" +
"ooooooooooooooooooooooooooooong"; // 248 characters.
info.setAttribute("longcat", longValue); // Key + value == 255 characters.
} catch (IllegalArgumentException e) {
exceptionThrown = true;
}
assertTrue(exceptionThrown);
assertEmptyServiceInfo(info);
// Total TXT record length too long.
exceptionThrown = false;
int recordsAdded = 0;
try {
for (int i = 100; i < 300; ++i) {
// 6 char key + 5 char value + 2 bytes overhead = 13 byte record length.
String key = String.format("key%d", i);
info.setAttribute(key, "12345");
recordsAdded++;
}
} catch (IllegalArgumentException e) {
exceptionThrown = true;
}
assertTrue(exceptionThrown);
assertTrue(100 == recordsAdded);
assertTrue(info.getTxtRecord().length == 1300);
}
public void testParcel() throws Exception {
NsdServiceInfo emptyInfo = new NsdServiceInfo();
checkParcelable(emptyInfo);
NsdServiceInfo fullInfo = new NsdServiceInfo();
fullInfo.setServiceName("kitten");
fullInfo.setServiceType("_kitten._tcp");
fullInfo.setPort(4242);
fullInfo.setHost(LOCALHOST);
checkParcelable(fullInfo);
NsdServiceInfo noHostInfo = new NsdServiceInfo();
noHostInfo.setServiceName("kitten");
noHostInfo.setServiceType("_kitten._tcp");
noHostInfo.setPort(4242);
checkParcelable(noHostInfo);
NsdServiceInfo attributedInfo = new NsdServiceInfo();
attributedInfo.setServiceName("kitten");
attributedInfo.setServiceType("_kitten._tcp");
attributedInfo.setPort(4242);
attributedInfo.setHost(LOCALHOST);
attributedInfo.setAttribute("color", "pink");
attributedInfo.setAttribute("sound", (new String("にゃあ")).getBytes("UTF-8"));
attributedInfo.setAttribute("adorable", (String) null);
attributedInfo.setAttribute("sticky", "yes");
attributedInfo.setAttribute("siblings", new byte[] {});
attributedInfo.setAttribute("edge cases", new byte[] {0, -1, 127, -128});
attributedInfo.removeAttribute("sticky");
checkParcelable(attributedInfo);
// Sanity check that we actually wrote attributes to attributedInfo.
assertTrue(attributedInfo.getAttributes().keySet().contains("adorable"));
String sound = new String(attributedInfo.getAttributes().get("sound"), "UTF-8");
assertTrue(sound.equals("にゃあ"));
byte[] edgeCases = attributedInfo.getAttributes().get("edge cases");
assertTrue(Arrays.equals(edgeCases, new byte[] {0, -1, 127, -128}));
assertFalse(attributedInfo.getAttributes().keySet().contains("sticky"));
}
public void checkParcelable(NsdServiceInfo original) {
// Write to parcel.
Parcel p = Parcel.obtain();
Bundle writer = new Bundle();
writer.putParcelable("test_info", original);
writer.writeToParcel(p, 0);
// Extract from parcel.
p.setDataPosition(0);
Bundle reader = p.readBundle();
reader.setClassLoader(NsdServiceInfo.class.getClassLoader());
NsdServiceInfo result = reader.getParcelable("test_info");
// Assert equality of base fields.
assertEquality(original.getServiceName(), result.getServiceName());
assertEquality(original.getServiceType(), result.getServiceType());
assertEquality(original.getHost(), result.getHost());
assertTrue(original.getPort() == result.getPort());
// Assert equality of attribute map.
Map<String, byte[]> originalMap = original.getAttributes();
Map<String, byte[]> resultMap = result.getAttributes();
assertEquality(originalMap.keySet(), resultMap.keySet());
for (String key : originalMap.keySet()) {
assertTrue(Arrays.equals(originalMap.get(key), resultMap.get(key)));
}
}
public void assertEquality(Object expected, Object result) {
assertTrue(expected == result || expected.equals(result));
}
public void assertEmptyServiceInfo(NsdServiceInfo shouldBeEmpty) {
assertTrue(null == shouldBeEmpty.getTxtRecord());
}
}