• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package android.net.nsd;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertTrue;
22 import static org.junit.Assert.fail;
23 
24 import android.net.InetAddresses;
25 import android.net.Network;
26 import android.os.Build;
27 import android.os.Bundle;
28 import android.os.Parcel;
29 import android.os.StrictMode;
30 
31 import androidx.test.filters.SmallTest;
32 
33 import com.android.testutils.DevSdkIgnoreRule;
34 import com.android.testutils.DevSdkIgnoreRunner;
35 
36 import org.junit.Test;
37 import org.junit.runner.RunWith;
38 
39 import java.net.InetAddress;
40 import java.net.UnknownHostException;
41 import java.util.Arrays;
42 import java.util.List;
43 import java.util.Map;
44 
45 @RunWith(DevSdkIgnoreRunner.class)
46 @SmallTest
47 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S_V2)
48 public class NsdServiceInfoTest {
49 
50     private static final InetAddress IPV4_ADDRESS = InetAddresses.parseNumericAddress("192.0.2.1");
51     private static final InetAddress IPV6_ADDRESS = InetAddresses.parseNumericAddress("2001:db8::");
52     public final static InetAddress LOCALHOST;
53     static {
54         // Because test.
55         StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
56         StrictMode.setThreadPolicy(policy);
57 
58         InetAddress _host = null;
59         try {
60             _host = InetAddress.getLocalHost();
61         } catch (UnknownHostException e) { }
62         LOCALHOST = _host;
63     }
64 
65     @Test
testLimits()66     public void testLimits() throws Exception {
67         NsdServiceInfo info = new NsdServiceInfo();
68 
69         // Non-ASCII keys.
70         boolean exceptionThrown = false;
71         try {
72             info.setAttribute("猫", "meow");
73         } catch (IllegalArgumentException e) {
74             exceptionThrown = true;
75         }
76         assertTrue(exceptionThrown);
77         assertEmptyServiceInfo(info);
78 
79         // ASCII keys with '=' character.
80         exceptionThrown = false;
81         try {
82             info.setAttribute("kitten=", "meow");
83         } catch (IllegalArgumentException e) {
84             exceptionThrown = true;
85         }
86         assertTrue(exceptionThrown);
87         assertEmptyServiceInfo(info);
88 
89         // Single key + value length too long.
90         exceptionThrown = false;
91         try {
92             String longValue = "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" +
93                     "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" +
94                     "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" +
95                     "ooooooooooooooooooooooooooooong";  // 248 characters.
96             info.setAttribute("longcat", longValue);  // Key + value == 255 characters.
97         } catch (IllegalArgumentException e) {
98             exceptionThrown = true;
99         }
100         assertTrue(exceptionThrown);
101         assertEmptyServiceInfo(info);
102 
103         // Total TXT record length too long.
104         exceptionThrown = false;
105         int recordsAdded = 0;
106         try {
107             for (int i = 100; i < 300; ++i) {
108                 // 6 char key + 5 char value + 2 bytes overhead = 13 byte record length.
109                 String key = String.format("key%d", i);
110                 info.setAttribute(key, "12345");
111                 recordsAdded++;
112             }
113         } catch (IllegalArgumentException e) {
114             exceptionThrown = true;
115         }
116         assertTrue(exceptionThrown);
117         assertTrue(100 == recordsAdded);
118         assertTrue(info.getTxtRecord().length == 1300);
119     }
120 
121     @Test
testParcel()122     public void testParcel() throws Exception {
123         NsdServiceInfo emptyInfo = new NsdServiceInfo();
124         checkParcelable(emptyInfo);
125 
126         NsdServiceInfo fullInfo = new NsdServiceInfo();
127         fullInfo.setServiceName("kitten");
128         fullInfo.setServiceType("_kitten._tcp");
129         fullInfo.setPort(4242);
130         fullInfo.setHost(LOCALHOST);
131         fullInfo.setHostAddresses(List.of(IPV4_ADDRESS));
132         fullInfo.setNetwork(new Network(123));
133         fullInfo.setInterfaceIndex(456);
134         checkParcelable(fullInfo);
135 
136         NsdServiceInfo noHostInfo = new NsdServiceInfo();
137         noHostInfo.setServiceName("kitten");
138         noHostInfo.setServiceType("_kitten._tcp");
139         noHostInfo.setPort(4242);
140         checkParcelable(noHostInfo);
141 
142         NsdServiceInfo attributedInfo = new NsdServiceInfo();
143         attributedInfo.setServiceName("kitten");
144         attributedInfo.setServiceType("_kitten._tcp");
145         attributedInfo.setPort(4242);
146         attributedInfo.setHost(LOCALHOST);
147         fullInfo.setHostAddresses(List.of(IPV6_ADDRESS, IPV4_ADDRESS));
148         attributedInfo.setAttribute("color", "pink");
149         attributedInfo.setAttribute("sound", (new String("にゃあ")).getBytes("UTF-8"));
150         attributedInfo.setAttribute("adorable", (String) null);
151         attributedInfo.setAttribute("sticky", "yes");
152         attributedInfo.setAttribute("siblings", new byte[] {});
153         attributedInfo.setAttribute("edge cases", new byte[] {0, -1, 127, -128});
154         attributedInfo.removeAttribute("sticky");
155         checkParcelable(attributedInfo);
156 
157         // Sanity check that we actually wrote attributes to attributedInfo.
158         assertTrue(attributedInfo.getAttributes().keySet().contains("adorable"));
159         String sound = new String(attributedInfo.getAttributes().get("sound"), "UTF-8");
160         assertTrue(sound.equals("にゃあ"));
161         byte[] edgeCases = attributedInfo.getAttributes().get("edge cases");
162         assertTrue(Arrays.equals(edgeCases, new byte[] {0, -1, 127, -128}));
163         assertFalse(attributedInfo.getAttributes().keySet().contains("sticky"));
164     }
165 
checkParcelable(NsdServiceInfo original)166     public void checkParcelable(NsdServiceInfo original) {
167         // Write to parcel.
168         Parcel p = Parcel.obtain();
169         Bundle writer = new Bundle();
170         writer.putParcelable("test_info", original);
171         writer.writeToParcel(p, 0);
172 
173         // Extract from parcel.
174         p.setDataPosition(0);
175         Bundle reader = p.readBundle();
176         reader.setClassLoader(NsdServiceInfo.class.getClassLoader());
177         NsdServiceInfo result = reader.getParcelable("test_info");
178 
179         // Assert equality of base fields.
180         assertEquals(original.getServiceName(), result.getServiceName());
181         assertEquals(original.getServiceType(), result.getServiceType());
182         assertEquals(original.getHost(), result.getHost());
183         assertTrue(original.getPort() == result.getPort());
184         assertEquals(original.getNetwork(), result.getNetwork());
185         assertEquals(original.getInterfaceIndex(), result.getInterfaceIndex());
186 
187         // Assert equality of attribute map.
188         Map<String, byte[]> originalMap = original.getAttributes();
189         Map<String, byte[]> resultMap = result.getAttributes();
190         assertEquals(originalMap.keySet(), resultMap.keySet());
191         for (String key : originalMap.keySet()) {
192             assertTrue(Arrays.equals(originalMap.get(key), resultMap.get(key)));
193         }
194     }
195 
assertEmptyServiceInfo(NsdServiceInfo shouldBeEmpty)196     public void assertEmptyServiceInfo(NsdServiceInfo shouldBeEmpty) {
197         byte[] txtRecord = shouldBeEmpty.getTxtRecord();
198         if (txtRecord == null || txtRecord.length == 0) {
199             return;
200         }
201         fail("NsdServiceInfo.getTxtRecord did not return null but " + Arrays.toString(txtRecord));
202     }
203 }
204