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