Home | History | Annotate | Download | only in nsd
      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.Bundle;
     25 import android.os.Parcel;
     26 import android.os.StrictMode;
     27 import android.net.nsd.NsdServiceInfo;
     28 import android.support.test.filters.SmallTest;
     29 import android.support.test.runner.AndroidJUnit4;
     30 import android.util.Log;
     31 
     32 import java.util.Arrays;
     33 import java.util.HashMap;
     34 import java.util.Map;
     35 import java.net.InetAddress;
     36 import java.net.UnknownHostException;
     37 
     38 import org.junit.Test;
     39 import org.junit.runner.RunWith;
     40 
     41 @RunWith(AndroidJUnit4.class)
     42 @SmallTest
     43 public 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