1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.net.nsd; 18 19import static org.junit.Assert.assertEquals; 20import static org.junit.Assert.assertFalse; 21import static org.junit.Assert.assertTrue; 22import static org.junit.Assert.fail; 23 24import android.os.Bundle; 25import android.os.Parcel; 26import android.os.StrictMode; 27import android.net.nsd.NsdServiceInfo; 28import android.support.test.filters.SmallTest; 29import android.support.test.runner.AndroidJUnit4; 30import android.util.Log; 31 32import java.util.Arrays; 33import java.util.HashMap; 34import java.util.Map; 35import java.net.InetAddress; 36import java.net.UnknownHostException; 37 38import org.junit.Test; 39import org.junit.runner.RunWith; 40 41@RunWith(AndroidJUnit4.class) 42@SmallTest 43public class NsdServiceInfoTest { 44 45 public final static InetAddress LOCALHOST; 46 static { 47 // Because test. 48 StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); 49 StrictMode.setThreadPolicy(policy); 50 51 InetAddress _host = null; 52 try { 53 _host = InetAddress.getLocalHost(); 54 } catch (UnknownHostException e) { } 55 LOCALHOST = _host; 56 } 57 58 @Test 59 public void testLimits() throws Exception { 60 NsdServiceInfo info = new NsdServiceInfo(); 61 62 // Non-ASCII keys. 63 boolean exceptionThrown = false; 64 try { 65 info.setAttribute("猫", "meow"); 66 } catch (IllegalArgumentException e) { 67 exceptionThrown = true; 68 } 69 assertTrue(exceptionThrown); 70 assertEmptyServiceInfo(info); 71 72 // ASCII keys with '=' character. 73 exceptionThrown = false; 74 try { 75 info.setAttribute("kitten=", "meow"); 76 } catch (IllegalArgumentException e) { 77 exceptionThrown = true; 78 } 79 assertTrue(exceptionThrown); 80 assertEmptyServiceInfo(info); 81 82 // Single key + value length too long. 83 exceptionThrown = false; 84 try { 85 String longValue = "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" + 86 "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" + 87 "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" + 88 "ooooooooooooooooooooooooooooong"; // 248 characters. 89 info.setAttribute("longcat", longValue); // Key + value == 255 characters. 90 } catch (IllegalArgumentException e) { 91 exceptionThrown = true; 92 } 93 assertTrue(exceptionThrown); 94 assertEmptyServiceInfo(info); 95 96 // Total TXT record length too long. 97 exceptionThrown = false; 98 int recordsAdded = 0; 99 try { 100 for (int i = 100; i < 300; ++i) { 101 // 6 char key + 5 char value + 2 bytes overhead = 13 byte record length. 102 String key = String.format("key%d", i); 103 info.setAttribute(key, "12345"); 104 recordsAdded++; 105 } 106 } catch (IllegalArgumentException e) { 107 exceptionThrown = true; 108 } 109 assertTrue(exceptionThrown); 110 assertTrue(100 == recordsAdded); 111 assertTrue(info.getTxtRecord().length == 1300); 112 } 113 114 @Test 115 public void testParcel() throws Exception { 116 NsdServiceInfo emptyInfo = new NsdServiceInfo(); 117 checkParcelable(emptyInfo); 118 119 NsdServiceInfo fullInfo = new NsdServiceInfo(); 120 fullInfo.setServiceName("kitten"); 121 fullInfo.setServiceType("_kitten._tcp"); 122 fullInfo.setPort(4242); 123 fullInfo.setHost(LOCALHOST); 124 checkParcelable(fullInfo); 125 126 NsdServiceInfo noHostInfo = new NsdServiceInfo(); 127 noHostInfo.setServiceName("kitten"); 128 noHostInfo.setServiceType("_kitten._tcp"); 129 noHostInfo.setPort(4242); 130 checkParcelable(noHostInfo); 131 132 NsdServiceInfo attributedInfo = new NsdServiceInfo(); 133 attributedInfo.setServiceName("kitten"); 134 attributedInfo.setServiceType("_kitten._tcp"); 135 attributedInfo.setPort(4242); 136 attributedInfo.setHost(LOCALHOST); 137 attributedInfo.setAttribute("color", "pink"); 138 attributedInfo.setAttribute("sound", (new String("にゃあ")).getBytes("UTF-8")); 139 attributedInfo.setAttribute("adorable", (String) null); 140 attributedInfo.setAttribute("sticky", "yes"); 141 attributedInfo.setAttribute("siblings", new byte[] {}); 142 attributedInfo.setAttribute("edge cases", new byte[] {0, -1, 127, -128}); 143 attributedInfo.removeAttribute("sticky"); 144 checkParcelable(attributedInfo); 145 146 // Sanity check that we actually wrote attributes to attributedInfo. 147 assertTrue(attributedInfo.getAttributes().keySet().contains("adorable")); 148 String sound = new String(attributedInfo.getAttributes().get("sound"), "UTF-8"); 149 assertTrue(sound.equals("にゃあ")); 150 byte[] edgeCases = attributedInfo.getAttributes().get("edge cases"); 151 assertTrue(Arrays.equals(edgeCases, new byte[] {0, -1, 127, -128})); 152 assertFalse(attributedInfo.getAttributes().keySet().contains("sticky")); 153 } 154 155 public void checkParcelable(NsdServiceInfo original) { 156 // Write to parcel. 157 Parcel p = Parcel.obtain(); 158 Bundle writer = new Bundle(); 159 writer.putParcelable("test_info", original); 160 writer.writeToParcel(p, 0); 161 162 // Extract from parcel. 163 p.setDataPosition(0); 164 Bundle reader = p.readBundle(); 165 reader.setClassLoader(NsdServiceInfo.class.getClassLoader()); 166 NsdServiceInfo result = reader.getParcelable("test_info"); 167 168 // Assert equality of base fields. 169 assertEquals(original.getServiceName(), result.getServiceName()); 170 assertEquals(original.getServiceType(), result.getServiceType()); 171 assertEquals(original.getHost(), result.getHost()); 172 assertTrue(original.getPort() == result.getPort()); 173 174 // Assert equality of attribute map. 175 Map<String, byte[]> originalMap = original.getAttributes(); 176 Map<String, byte[]> resultMap = result.getAttributes(); 177 assertEquals(originalMap.keySet(), resultMap.keySet()); 178 for (String key : originalMap.keySet()) { 179 assertTrue(Arrays.equals(originalMap.get(key), resultMap.get(key))); 180 } 181 } 182 183 public void assertEmptyServiceInfo(NsdServiceInfo shouldBeEmpty) { 184 byte[] txtRecord = shouldBeEmpty.getTxtRecord(); 185 if (txtRecord == null || txtRecord.length == 0) { 186 return; 187 } 188 fail("NsdServiceInfo.getTxtRecord did not return null but " + Arrays.toString(txtRecord)); 189 } 190} 191