Home | History | Annotate | Download | only in carrierconfig
      1 package com.android.carrierconfig;
      2 
      3 import android.content.Context;
      4 import android.content.res.AssetManager;
      5 import android.content.res.Resources;
      6 import android.os.PersistableBundle;
      7 import android.service.carrier.CarrierIdentifier;
      8 import android.telephony.CarrierConfigManager;
      9 import android.test.InstrumentationTestCase;
     10 import android.util.Log;
     11 
     12 import java.io.IOException;
     13 import java.io.InputStream;
     14 import java.lang.reflect.Field;
     15 import java.lang.reflect.Modifier;
     16 import java.util.HashSet;
     17 import java.util.Set;
     18 
     19 import junit.framework.AssertionFailedError;
     20 
     21 import org.xmlpull.v1.XmlPullParser;
     22 import org.xmlpull.v1.XmlPullParserException;
     23 import org.xmlpull.v1.XmlPullParserFactory;
     24 
     25 public class CarrierConfigTest extends InstrumentationTestCase {
     26 
     27     /**
     28      * Iterate over all XML files in assets/ and ensure they parse without error.
     29      */
     30     public void testAllFilesParse() {
     31         forEachConfigXml(new ParserChecker() {
     32             public void check(XmlPullParser parser) throws XmlPullParserException, IOException {
     33                 PersistableBundle b = DefaultCarrierConfigService.readConfigFromXml(parser,
     34                         new CarrierIdentifier("001", "001", "Test", "001001123456789", "", ""));
     35                 assertNotNull("got null bundle", b);
     36             }
     37         });
     38     }
     39 
     40     /**
     41      * Check that the config bundles in XML files have valid filter attributes.
     42      * This checks the attribute names only.
     43      */
     44     public void testFilterValidAttributes() {
     45         forEachConfigXml(new ParserChecker() {
     46             public void check(XmlPullParser parser) throws XmlPullParserException, IOException {
     47                 int event;
     48                 while (((event = parser.next()) != XmlPullParser.END_DOCUMENT)) {
     49                     if (event == XmlPullParser.START_TAG
     50                             && "carrier_config".equals(parser.getName())) {
     51                         for (int i = 0; i < parser.getAttributeCount(); ++i) {
     52                             String attribute = parser.getAttributeName(i);
     53                             switch (attribute) {
     54                                 case "mcc":
     55                                 case "mnc":
     56                                 case "gid1":
     57                                 case "gid2":
     58                                 case "spn":
     59                                 case "imsi":
     60                                 case "device":
     61                                     break;
     62                                 default:
     63                                     fail("Unknown attribute '" + attribute
     64                                             + "' at " + parser.getPositionDescription());
     65                                     break;
     66                             }
     67                         }
     68                     }
     69                 }
     70             }
     71         });
     72     }
     73 
     74     /**
     75      * Tests that the variable names in each XML file match actual keys in CarrierConfigManager.
     76      */
     77     public void testVariableNames() {
     78         final Set<String> varXmlNames = getCarrierConfigXmlNames();
     79         // organize them into sets by type or unknown
     80         forEachConfigXml(new ParserChecker() {
     81             public void check(XmlPullParser parser) throws XmlPullParserException, IOException {
     82                 int event;
     83                 while (((event = parser.next()) != XmlPullParser.END_DOCUMENT)) {
     84                     if (event == XmlPullParser.START_TAG) {
     85                         switch (parser.getName()) {
     86                             case "int-array":
     87                             case "string-array":
     88                                 // string-array and int-array require the 'num' attribute
     89                                 final String varNum = parser.getAttributeValue(null, "num");
     90                                 assertNotNull("No 'num' attribute in array: "
     91                                         + parser.getPositionDescription(), varNum);
     92                             case "int":
     93                             case "long":
     94                             case "boolean":
     95                             case "string":
     96                                 // NOTE: This doesn't check for other valid Bundle values, but it
     97                                 // is limited to the key types in CarrierConfigManager.
     98                                 final String varName = parser.getAttributeValue(null, "name");
     99                                 assertNotNull("No 'name' attribute: "
    100                                         + parser.getPositionDescription(), varName);
    101                                 assertTrue("Unknown variable: '" + varName
    102                                         + "' at " + parser.getPositionDescription(),
    103                                         varXmlNames.contains(varName));
    104                                 // TODO: Check that the type is correct.
    105                                 break;
    106                             case "carrier_config_list":
    107                             case "item":
    108                             case "carrier_config":
    109                                 // do nothing
    110                                 break;
    111                             default:
    112                                 fail("unexpected tag: '" + parser.getName()
    113                                         + "' at " + parser.getPositionDescription());
    114                                 break;
    115                         }
    116                     }
    117                 }
    118             }
    119         });
    120     }
    121 
    122     /**
    123      * Utility for iterating over each XML document in the assets folder.
    124      *
    125      * This can be used with {@link #forEachConfigXml} to run checks on each XML document.
    126      * {@link #check} should {@link #fail} if the test does not pass.
    127      */
    128     private interface ParserChecker {
    129         void check(XmlPullParser parser) throws XmlPullParserException, IOException;
    130     }
    131 
    132     /**
    133      * Utility for iterating over each XML document in the assets folder.
    134      */
    135     private void forEachConfigXml(ParserChecker checker) {
    136         AssetManager assetMgr = getInstrumentation().getTargetContext().getAssets();
    137         try {
    138             String[] files = assetMgr.list("");
    139             assertNotNull("failed to list files", files);
    140             assertTrue("no files", files.length > 0);
    141             for (String fileName : files) {
    142                 try {
    143                     if (!fileName.startsWith("carrier_config_")) continue;
    144 
    145                     XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
    146                     XmlPullParser parser = factory.newPullParser();
    147                     parser.setInput(assetMgr.open(fileName), "utf-8");
    148 
    149                     checker.check(parser);
    150 
    151                 } catch (Throwable e) {
    152                     throw new AssertionError("Problem in " + fileName + ": " + e.getMessage(), e);
    153                 }
    154             }
    155             // Check vendor.xml too
    156             try {
    157                 Resources res = getInstrumentation().getTargetContext().getResources();
    158                 checker.check(res.getXml(R.xml.vendor));
    159             } catch (Throwable e) {
    160                 throw new AssertionError("Problem in vendor.xml: " + e.getMessage(), e);
    161             }
    162         } catch (IOException e) {
    163             fail(e.toString());
    164         }
    165     }
    166 
    167     /**
    168      * Get the set of config variable names, as used in XML files.
    169      */
    170     private Set<String> getCarrierConfigXmlNames() {
    171         // get values of all KEY_ members of CarrierConfigManager
    172         Field[] fields = CarrierConfigManager.class.getDeclaredFields();
    173         HashSet<String> varXmlNames = new HashSet<>();
    174         for (Field f : fields) {
    175             if (!f.getName().startsWith("KEY_")) continue;
    176             if ((f.getModifiers() & Modifier.STATIC) == 0) {
    177                 fail("non-static key in CarrierConfigManager: " + f.toString());
    178             }
    179             try {
    180                 String value = (String) f.get(null);
    181                 varXmlNames.add(value);
    182             }
    183             catch (IllegalAccessException e) {
    184                 throw new AssertionError("Failed to get config key: " + e.getMessage(), e);
    185             }
    186         }
    187         assertTrue("Found zero keys", varXmlNames.size() > 0);
    188         return varXmlNames;
    189     }
    190 }
    191