1 package android.core; 2 3 import android.test.AndroidTestCase; 4 5 import android.os.Bundle; 6 import android.os.Parcel; 7 import android.os.StrictMode; 8 import android.net.nsd.NsdServiceInfo; 9 import android.util.Log; 10 11 import java.util.Arrays; 12 import java.util.HashMap; 13 import java.util.Map; 14 import java.net.InetAddress; 15 import java.net.UnknownHostException; 16 17 18 public class NsdServiceInfoTest extends AndroidTestCase { 19 20 public final static InetAddress LOCALHOST; 21 static { 22 // Because test. 23 StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); 24 StrictMode.setThreadPolicy(policy); 25 26 InetAddress _host = null; 27 try { 28 _host = InetAddress.getLocalHost(); 29 } catch (UnknownHostException e) { } 30 LOCALHOST = _host; 31 } 32 33 public void testLimits() throws Exception { 34 NsdServiceInfo info = new NsdServiceInfo(); 35 36 // Non-ASCII keys. 37 boolean exceptionThrown = false; 38 try { 39 info.setAttribute("", "meow"); 40 } catch (IllegalArgumentException e) { 41 exceptionThrown = true; 42 } 43 assertTrue(exceptionThrown); 44 assertEmptyServiceInfo(info); 45 46 // ASCII keys with '=' character. 47 exceptionThrown = false; 48 try { 49 info.setAttribute("kitten=", "meow"); 50 } catch (IllegalArgumentException e) { 51 exceptionThrown = true; 52 } 53 assertTrue(exceptionThrown); 54 assertEmptyServiceInfo(info); 55 56 // Single key + value length too long. 57 exceptionThrown = false; 58 try { 59 String longValue = "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" + 60 "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" + 61 "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" + 62 "ooooooooooooooooooooooooooooong"; // 248 characters. 63 info.setAttribute("longcat", longValue); // Key + value == 255 characters. 64 } catch (IllegalArgumentException e) { 65 exceptionThrown = true; 66 } 67 assertTrue(exceptionThrown); 68 assertEmptyServiceInfo(info); 69 70 // Total TXT record length too long. 71 exceptionThrown = false; 72 int recordsAdded = 0; 73 try { 74 for (int i = 100; i < 300; ++i) { 75 // 6 char key + 5 char value + 2 bytes overhead = 13 byte record length. 76 String key = String.format("key%d", i); 77 info.setAttribute(key, "12345"); 78 recordsAdded++; 79 } 80 } catch (IllegalArgumentException e) { 81 exceptionThrown = true; 82 } 83 assertTrue(exceptionThrown); 84 assertTrue(100 == recordsAdded); 85 assertTrue(info.getTxtRecord().length == 1300); 86 } 87 88 public void testParcel() throws Exception { 89 NsdServiceInfo emptyInfo = new NsdServiceInfo(); 90 checkParcelable(emptyInfo); 91 92 NsdServiceInfo fullInfo = new NsdServiceInfo(); 93 fullInfo.setServiceName("kitten"); 94 fullInfo.setServiceType("_kitten._tcp"); 95 fullInfo.setPort(4242); 96 fullInfo.setHost(LOCALHOST); 97 checkParcelable(fullInfo); 98 99 NsdServiceInfo noHostInfo = new NsdServiceInfo(); 100 noHostInfo.setServiceName("kitten"); 101 noHostInfo.setServiceType("_kitten._tcp"); 102 noHostInfo.setPort(4242); 103 checkParcelable(noHostInfo); 104 105 NsdServiceInfo attributedInfo = new NsdServiceInfo(); 106 attributedInfo.setServiceName("kitten"); 107 attributedInfo.setServiceType("_kitten._tcp"); 108 attributedInfo.setPort(4242); 109 attributedInfo.setHost(LOCALHOST); 110 attributedInfo.setAttribute("color", "pink"); 111 attributedInfo.setAttribute("sound", (new String("")).getBytes("UTF-8")); 112 attributedInfo.setAttribute("adorable", (String) null); 113 attributedInfo.setAttribute("sticky", "yes"); 114 attributedInfo.setAttribute("siblings", new byte[] {}); 115 attributedInfo.setAttribute("edge cases", new byte[] {0, -1, 127, -128}); 116 attributedInfo.removeAttribute("sticky"); 117 checkParcelable(attributedInfo); 118 119 // Sanity check that we actually wrote attributes to attributedInfo. 120 assertTrue(attributedInfo.getAttributes().keySet().contains("adorable")); 121 String sound = new String(attributedInfo.getAttributes().get("sound"), "UTF-8"); 122 assertTrue(sound.equals("")); 123 byte[] edgeCases = attributedInfo.getAttributes().get("edge cases"); 124 assertTrue(Arrays.equals(edgeCases, new byte[] {0, -1, 127, -128})); 125 assertFalse(attributedInfo.getAttributes().keySet().contains("sticky")); 126 } 127 128 public void checkParcelable(NsdServiceInfo original) { 129 // Write to parcel. 130 Parcel p = Parcel.obtain(); 131 Bundle writer = new Bundle(); 132 writer.putParcelable("test_info", original); 133 writer.writeToParcel(p, 0); 134 135 // Extract from parcel. 136 p.setDataPosition(0); 137 Bundle reader = p.readBundle(); 138 reader.setClassLoader(NsdServiceInfo.class.getClassLoader()); 139 NsdServiceInfo result = reader.getParcelable("test_info"); 140 141 // Assert equality of base fields. 142 assertEquality(original.getServiceName(), result.getServiceName()); 143 assertEquality(original.getServiceType(), result.getServiceType()); 144 assertEquality(original.getHost(), result.getHost()); 145 assertTrue(original.getPort() == result.getPort()); 146 147 // Assert equality of attribute map. 148 Map<String, byte[]> originalMap = original.getAttributes(); 149 Map<String, byte[]> resultMap = result.getAttributes(); 150 assertEquality(originalMap.keySet(), resultMap.keySet()); 151 for (String key : originalMap.keySet()) { 152 assertTrue(Arrays.equals(originalMap.get(key), resultMap.get(key))); 153 } 154 } 155 156 public void assertEquality(Object expected, Object result) { 157 assertTrue(expected == result || expected.equals(result)); 158 } 159 160 public void assertEmptyServiceInfo(NsdServiceInfo shouldBeEmpty) { 161 assertTrue(null == shouldBeEmpty.getTxtRecord()); 162 } 163 } 164