Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2013 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 package android.os.cts;
     17 
     18 import java.lang.reflect.Constructor;
     19 import java.lang.reflect.InvocationTargetException;
     20 import java.lang.reflect.Method;
     21 
     22 import java.util.Arrays;
     23 
     24 import android.os.WorkSource;
     25 import android.test.AndroidTestCase;
     26 
     27 public class WorkSourceTest extends AndroidTestCase {
     28     private Constructor<WorkSource> mConstructWS;
     29     private Object[] mConstructWSArgs = new Object[1];
     30     private Method mAddUid;
     31     private Object[] mAddUidArgs = new Object[1];
     32     private Method mAddUidName;
     33     private Object[] mAddUidNameArgs = new Object[2];
     34     private Method mAddReturningNewbs;
     35     private Object[] mAddReturningNewbsArgs = new Object[1];
     36     private Method mSetReturningDiffs;
     37     private Object[] mSetReturningDiffsArgs = new Object[1];
     38 
     39     @Override
     40     protected void setUp() throws Exception {
     41         super.setUp();
     42         mConstructWS = WorkSource.class.getConstructor(new Class[] { int.class });
     43         mAddUid = WorkSource.class.getMethod("add", new Class[] { int.class });
     44         mAddUidName = WorkSource.class.getMethod("add", new Class[] { int.class, String.class });
     45         mAddReturningNewbs = WorkSource.class.getMethod("addReturningNewbs", new Class[] { WorkSource.class });
     46         mSetReturningDiffs = WorkSource.class.getMethod("setReturningDiffs", new Class[] { WorkSource.class });
     47     }
     48 
     49     private WorkSource wsNew(int uid) throws IllegalArgumentException,
     50             InstantiationException, IllegalAccessException, InvocationTargetException {
     51         mConstructWSArgs[0] = uid;
     52         return mConstructWS.newInstance(mConstructWSArgs);
     53     }
     54 
     55     private WorkSource wsNew(int[] uids) throws IllegalArgumentException,
     56             InstantiationException, IllegalAccessException, InvocationTargetException {
     57         WorkSource ws = new WorkSource();
     58         for (int i=0; i<uids.length; i++) {
     59             wsAdd(ws, uids[i]);
     60         }
     61         checkWorkSource("Constructed", ws, uids);
     62         return ws;
     63     }
     64 
     65     private WorkSource wsNew(int[] uids, String[] names) throws IllegalArgumentException,
     66             InstantiationException, IllegalAccessException, InvocationTargetException {
     67         WorkSource ws = new WorkSource();
     68         for (int i=0; i<uids.length; i++) {
     69             wsAdd(ws, uids[i], names[i]);
     70         }
     71         checkWorkSource("Constructed", ws, uids, names);
     72         return ws;
     73     }
     74 
     75     private boolean wsAdd(WorkSource ws, int uid) throws IllegalArgumentException,
     76             InstantiationException, IllegalAccessException, InvocationTargetException {
     77         mAddUidArgs[0] = uid;
     78         return (Boolean)mAddUid.invoke(ws, mAddUidArgs);
     79     }
     80 
     81     private boolean wsAdd(WorkSource ws, int uid, String name) throws IllegalArgumentException,
     82             InstantiationException, IllegalAccessException, InvocationTargetException {
     83         mAddUidNameArgs[0] = uid;
     84         mAddUidNameArgs[1] = name;
     85         return (Boolean)mAddUidName.invoke(ws, mAddUidNameArgs);
     86     }
     87 
     88     private WorkSource wsAddReturningNewbs(WorkSource ws, WorkSource other) throws IllegalArgumentException,
     89             InstantiationException, IllegalAccessException, InvocationTargetException {
     90         mAddReturningNewbsArgs[0] = other;
     91         return (WorkSource)mAddReturningNewbs.invoke(ws, mAddReturningNewbsArgs);
     92     }
     93 
     94     private WorkSource[] wsSetReturningDiffs(WorkSource ws, WorkSource other) throws IllegalArgumentException,
     95             InstantiationException, IllegalAccessException, InvocationTargetException {
     96         mSetReturningDiffsArgs[0] = other;
     97         return (WorkSource[])mSetReturningDiffs.invoke(ws, mSetReturningDiffsArgs);
     98     }
     99 
    100     private void printArrays(StringBuilder sb, int[] uids, String[] names) {
    101         sb.append("{ ");
    102         for (int i=0; i<uids.length; i++) {
    103             if (i > 0) sb.append(", ");
    104             sb.append(uids[i]);
    105             if (names != null) {
    106                 sb.append(" ");
    107                 sb.append(names[i]);
    108             }
    109         }
    110         sb.append(" }");
    111     }
    112 
    113     private void failWorkSource(String op, WorkSource ws, int[] uids) {
    114         StringBuilder sb = new StringBuilder();
    115         sb.append(op);
    116         sb.append(": Expected: ");
    117         printArrays(sb, uids, null);
    118         sb.append(", got: ");
    119         sb.append(ws);
    120         fail(sb.toString());
    121     }
    122 
    123     private void failWorkSource(String op, WorkSource ws, int[] uids, String[] names) {
    124         StringBuilder sb = new StringBuilder();
    125         sb.append(op);
    126         sb.append(": Expected: ");
    127         printArrays(sb, uids, names);
    128         sb.append(", got: ");
    129         sb.append(ws);
    130         fail(sb.toString());
    131     }
    132 
    133     private void checkWorkSource(String op, WorkSource ws, int[] uids) {
    134         if (ws == null || uids == null) {
    135             if (ws != null) {
    136                 fail(op + ": WorkSource is not null " + ws +", but expected null");
    137             }
    138             if (uids != null) {
    139                 fail(op + "WorkSource is null, but expected non-null: " + Arrays.toString(uids));
    140             }
    141             return;
    142         }
    143         if (ws.size() != uids.length) {
    144             failWorkSource(op, ws, uids);
    145         }
    146         for (int i=0; i<uids.length; i++) {
    147             if (uids[i] != ws.get(i)) {
    148                 failWorkSource(op, ws, uids);
    149             }
    150         }
    151     }
    152 
    153     private void checkWorkSource(String op, WorkSource ws, int[] uids, String[] names) {
    154         if (ws == null || uids == null) {
    155             if (ws != null) {
    156                 fail(op + ": WorkSource is not null " + ws +", but expected null");
    157             }
    158             if (uids != null) {
    159                 fail(op + "WorkSource is null, but expected non-null: " + Arrays.toString(uids));
    160             }
    161             return;
    162         }
    163         if (ws.size() != uids.length) {
    164             failWorkSource(op, ws, uids, names);
    165         }
    166         for (int i=0; i<uids.length; i++) {
    167             if (uids[i] != ws.get(i) || !names[i].equals(ws.getName(i))) {
    168                 failWorkSource(op, ws, uids, names);
    169             }
    170         }
    171     }
    172 
    173     public void testConstructEmpty() {
    174         checkWorkSource("Empty", new WorkSource(), new int[] { });
    175     }
    176 
    177     public void testConstructSingle() throws Exception {
    178         checkWorkSource("Single 1", wsNew(1), new int[] { 1 });
    179     }
    180 
    181     public void testAddRawOrdered() throws Exception {
    182         WorkSource ws = wsNew(1);
    183         wsAdd(ws, 2);
    184         checkWorkSource("First", ws, new int[] { 1 , 2 });
    185         wsAdd(ws, 20);
    186         checkWorkSource("Second", ws, new int[] { 1 , 2, 20 });
    187         wsAdd(ws, 100);
    188         checkWorkSource("Third", ws, new int[] { 1, 2, 20, 100 });
    189     }
    190 
    191     public void testAddRawRevOrdered() throws Exception {
    192         WorkSource ws = wsNew(100);
    193         wsAdd(ws, 20);
    194         checkWorkSource("First", ws, new int[] { 20, 100 });
    195         wsAdd(ws, 2);
    196         checkWorkSource("Second", ws, new int[] { 2, 20, 100 });
    197         wsAdd(ws, 1);
    198         checkWorkSource("Third", ws, new int[] { 1, 2, 20, 100 });
    199     }
    200 
    201     public void testAddRawUnordered() throws Exception {
    202         WorkSource ws = wsNew(10);
    203         wsAdd(ws, 2);
    204         checkWorkSource("First", ws, new int[] { 2, 10 });
    205         wsAdd(ws, 5);
    206         checkWorkSource("Second", ws, new int[] { 2, 5, 10 });
    207         wsAdd(ws, 1);
    208         checkWorkSource("Third", ws, new int[] { 1, 2, 5, 10 });
    209         wsAdd(ws, 100);
    210         checkWorkSource("Fourth", ws, new int[] { 1, 2, 5, 10, 100 });
    211     }
    212 
    213     public void testAddWsOrdered() throws Exception {
    214         WorkSource ws = wsNew(1);
    215         ws.add(wsNew(2));
    216         checkWorkSource("First", ws, new int[] { 1 , 2 });
    217         ws.add(wsNew(20));
    218         checkWorkSource("Second", ws, new int[] { 1 , 2, 20 });
    219         ws.add(wsNew(100));
    220         checkWorkSource("Third", ws, new int[] { 1 , 2, 20, 100 });
    221     }
    222 
    223     public void testAddWsRevOrdered() throws Exception {
    224         WorkSource ws = wsNew(100);
    225         ws.add(wsNew(20));
    226         checkWorkSource("First", ws, new int[] { 20, 100 });
    227         ws.add(wsNew(2));
    228         checkWorkSource("Second", ws, new int[] { 2, 20, 100 });
    229         ws.add(wsNew(1));
    230         checkWorkSource("Third", ws, new int[] { 1, 2, 20, 100 });
    231     }
    232 
    233     public void testAddWsUnordered() throws Exception {
    234         WorkSource ws = wsNew(10);
    235         ws.add(wsNew(2));
    236         checkWorkSource("First", ws, new int[] { 2, 10 });
    237         ws.add(wsNew(5));
    238         checkWorkSource("Second", ws, new int[] { 2, 5, 10 });
    239         ws.add(wsNew(1));
    240         checkWorkSource("Third", ws, new int[] { 1, 2, 5, 10 });
    241         ws.add(wsNew(100));
    242         checkWorkSource("Fourth", ws, new int[] { 1, 2, 5, 10, 100 });
    243     }
    244 
    245     private void doTestCombineTwoUids(int[] lhs, int[] rhs, int[] expected, int[] newbs,
    246             int[] gones) throws Exception {
    247         WorkSource ws1 = wsNew(lhs);
    248         WorkSource ws2 = wsNew(rhs);
    249         ws1.add(ws2);
    250         checkWorkSource("Add result", ws1, expected);
    251         ws1 = wsNew(lhs);
    252         WorkSource wsNewbs = wsAddReturningNewbs(ws1, ws2);
    253         checkWorkSource("AddReturning result", ws1, expected);
    254         checkWorkSource("Newbs", wsNewbs, newbs);
    255         ws1 = wsNew(lhs);
    256         WorkSource[] res = wsSetReturningDiffs(ws1, ws2);
    257         checkWorkSource("SetReturning result", ws1, rhs);
    258         checkWorkSource("Newbs", res[0], newbs);
    259         checkWorkSource("Gones", res[1], gones);
    260     }
    261 
    262     private int[] makeRepeatingIntArray(String[] stringarray, int value) {
    263         if (stringarray == null) {
    264             return null;
    265         }
    266         int[] res = new int[stringarray.length];
    267         for (int i=0; i<stringarray.length; i++) {
    268             res[i] = value;
    269         }
    270         return res;
    271     }
    272 
    273     private void doTestCombineTwoNames(String[] lhsnames, String[] rhsnames,
    274             String[] expectednames, String[] newbnames,
    275             String[] gonenames) throws Exception {
    276         int[] lhs = makeRepeatingIntArray(lhsnames, 0);
    277         int[] rhs = makeRepeatingIntArray(rhsnames, 0);
    278         int[] expected = makeRepeatingIntArray(expectednames, 0);
    279         int[] newbs = makeRepeatingIntArray(newbnames, 0);
    280         int[] gones = makeRepeatingIntArray(gonenames, 0);
    281         doTestCombineTwoUidsNames(lhs, lhsnames, rhs, rhsnames, expected, expectednames,
    282                 newbs, newbnames, gones, gonenames);
    283     }
    284 
    285     private void doTestCombineTwoUidsNames(int[] lhs, String[] lhsnames, int[] rhs, String[] rhsnames,
    286             int[] expected, String[] expectednames, int[] newbs, String[] newbnames,
    287             int[] gones, String[] gonenames) throws Exception {
    288         WorkSource ws1 = wsNew(lhs, lhsnames);
    289         WorkSource ws2 = wsNew(rhs, rhsnames);
    290         ws1.add(ws2);
    291         checkWorkSource("Add result", ws1, expected, expectednames);
    292         ws1 = wsNew(lhs, lhsnames);
    293         WorkSource wsNewbs = wsAddReturningNewbs(ws1, ws2);
    294         checkWorkSource("AddReturning result", ws1, expected, expectednames);
    295         checkWorkSource("Newbs", wsNewbs, newbs, newbnames);
    296         ws1 = wsNew(lhs, lhsnames);
    297         WorkSource[] res = wsSetReturningDiffs(ws1, ws2);
    298         checkWorkSource("SetReturning result", ws1, rhs, rhsnames);
    299         checkWorkSource("Newbs", res[0], newbs, newbnames);
    300         checkWorkSource("Gones", res[1], gones, gonenames);
    301     }
    302 
    303     private String[] makeRepeatingStringArray(int[] intarray, String value) {
    304         if (intarray == null) {
    305             return null;
    306         }
    307         String[] res = new String[intarray.length];
    308         for (int i=0; i<intarray.length; i++) {
    309             res[i] = value;
    310         }
    311         return res;
    312     }
    313 
    314     private String[] makeStringArray(int[] intarray) {
    315         if (intarray == null) {
    316             return null;
    317         }
    318         String[] res = new String[intarray.length];
    319         for (int i=0; i<intarray.length; i++) {
    320             res[i] = Character.toString((char)('A' + intarray[i]));
    321         }
    322         return res;
    323     }
    324 
    325     private void doTestCombineTwo(int[] lhs, int[] rhs, int[] expected, int[] newbs,
    326             int[] gones) throws Exception {
    327         doTestCombineTwoUids(lhs, rhs, expected, newbs, gones);
    328         doTestCombineTwoUidsNames(lhs, makeRepeatingStringArray(lhs, "A"),
    329                 rhs, makeRepeatingStringArray(rhs, "A"),
    330                 expected, makeRepeatingStringArray(expected, "A"),
    331                 newbs, makeRepeatingStringArray(newbs, "A"),
    332                 gones, makeRepeatingStringArray(gones, "A"));
    333         doTestCombineTwoNames(makeStringArray(lhs), makeStringArray(rhs),
    334                 makeStringArray(expected), makeStringArray(newbs), makeStringArray(gones));
    335     }
    336 
    337     public void testCombineMultiFront() throws Exception {
    338         doTestCombineTwo(
    339                 new int[] { 10, 20, 30, 40 },
    340                 new int[] { 1, 2, 15, 16 },
    341                 new int[] { 1, 2, 10, 15, 16, 20, 30, 40 },
    342                 new int[] { 1, 2, 15, 16 },
    343                 new int[] { 10, 20, 30, 40 });
    344     }
    345 
    346     public void testCombineMultiMiddle() throws Exception {
    347         doTestCombineTwo(
    348                 new int[] { 10, 20, 30, 40 },
    349                 new int[] { 12, 14, 22 },
    350                 new int[] { 10, 12, 14, 20, 22, 30, 40 },
    351                 new int[] { 12, 14, 22 },
    352                 new int[] { 10, 20, 30, 40 });
    353     }
    354 
    355     public void testCombineMultiEnd() throws Exception {
    356         doTestCombineTwo(
    357                 new int[] { 10, 20, 30, 40 },
    358                 new int[] { 35, 45, 50 },
    359                 new int[] { 10, 20, 30, 35, 40, 45, 50 },
    360                 new int[] { 35, 45, 50 },
    361                 new int[] { 10, 20, 30, 40 });
    362     }
    363 
    364     public void testCombineMultiFull() throws Exception {
    365         doTestCombineTwo(
    366                 new int[] { 10, 20, 30, 40 },
    367                 new int[] { 1, 2, 15, 35, 50 },
    368                 new int[] { 1, 2, 10, 15, 20, 30, 35, 40, 50 },
    369                 new int[] { 1, 2, 15, 35, 50 },
    370                 new int[] { 10, 20, 30, 40 });
    371     }
    372 
    373     public void testCombineMultiSame() throws Exception {
    374         doTestCombineTwo(
    375                 new int[] { 10, 20, 30, 40 },
    376                 new int[] { 10, 20, 30 },
    377                 new int[] { 10, 20, 30, 40 },
    378                 null,
    379                 new int[] { 40 });
    380     }
    381 
    382     public void testCombineMultiSomeSame() throws Exception {
    383         doTestCombineTwo(
    384                 new int[] { 10, 20, 30, 40 },
    385                 new int[] { 1, 30, 40 },
    386                 new int[] { 1, 10, 20, 30, 40 },
    387                 new int[] { 1 },
    388                 new int[] { 10, 20 });
    389     }
    390 
    391     public void testCombineMultiSomeSameUidsNames() throws Exception {
    392         doTestCombineTwoUidsNames(
    393                 new int[]    { 10,  10,  20,  30,  30,  30,  40 },
    394                 new String[] { "A", "B", "A", "A", "B", "C", "A" },
    395                 new int[]    { 1,   30,  40,  50 },
    396                 new String[] { "A", "A", "B", "A" },
    397                 new int[]    { 1,   10,  10,  20,  30,  30,  30,  40,  40,  50 },
    398                 new String[] { "A", "A", "B", "A", "A", "B", "C", "A", "B", "A" },
    399                 new int[]    { 1,   40,  50 },
    400                 new String[] { "A", "B", "A" },
    401                 new int[]    { 10,  10,  20,  30,  30,  40 },
    402                 new String[] { "A", "B", "A", "B", "C", "A" });
    403     }
    404 
    405     private void doTestRemoveUids(int[] lhs, int[] rhs, int[] result, boolean diff) throws Exception {
    406         WorkSource ws1 = wsNew(lhs);
    407         WorkSource ws2 = wsNew(rhs);
    408         boolean diffres = ws1.remove(ws2);
    409         if (diffres != diff) {
    410             StringBuilder sb = new StringBuilder();
    411             sb.append("Expected diff ");
    412             sb.append(diff);
    413             sb.append(" but got ");
    414             sb.append(diffres);
    415             sb.append(" when removing ");
    416             sb.append(ws2);
    417             sb.append(" from ");
    418             sb.append(ws1);
    419             fail(sb.toString());
    420         }
    421         checkWorkSource("Remove", ws1, result);
    422     }
    423 
    424     private void doTestRemoveNames(String[] lhsnames, String[] rhsnames,
    425             String[] resultnames, boolean diff) throws Exception {
    426         int[] lhs = makeRepeatingIntArray(lhsnames, 0);
    427         int[] rhs = makeRepeatingIntArray(rhsnames, 0);
    428         int[] result = makeRepeatingIntArray(resultnames, 0);
    429         WorkSource ws1 = wsNew(lhs, lhsnames);
    430         WorkSource ws2 = wsNew(rhs, rhsnames);
    431         boolean diffres = ws1.remove(ws2);
    432         if (diffres != diff) {
    433             StringBuilder sb = new StringBuilder();
    434             sb.append("Expected diff ");
    435             sb.append(diff);
    436             sb.append(" but got ");
    437             sb.append(diffres);
    438             sb.append(" when removing ");
    439             sb.append(ws2);
    440             sb.append(" from ");
    441             sb.append(ws1);
    442             fail(sb.toString());
    443         }
    444         checkWorkSource("Remove", ws1, result, resultnames);
    445     }
    446 
    447     private void doTestRemoveUidsNames(int[] lhs, String[] lhsnames, int[] rhs, String[] rhsnames,
    448             int[] result, String[] resultnames, boolean diff) throws Exception {
    449         WorkSource ws1 = wsNew(lhs, lhsnames);
    450         WorkSource ws2 = wsNew(rhs, rhsnames);
    451         boolean diffres = ws1.remove(ws2);
    452         if (diffres != diff) {
    453             StringBuilder sb = new StringBuilder();
    454             sb.append("Expected diff ");
    455             sb.append(diff);
    456             sb.append(" but got ");
    457             sb.append(diffres);
    458             sb.append(" when removing ");
    459             sb.append(ws2);
    460             sb.append(" from ");
    461             sb.append(ws1);
    462             fail(sb.toString());
    463         }
    464         checkWorkSource("Remove", ws1, result, resultnames);
    465     }
    466 
    467     private void doTestRemove(int[] lhs, int[] rhs, int[] result, boolean diff) throws Exception {
    468         doTestRemoveUids(lhs, rhs, result, diff);
    469         doTestRemoveUidsNames(lhs, makeRepeatingStringArray(lhs, "A"),
    470                 rhs, makeRepeatingStringArray(rhs, "A"),
    471                 result, makeRepeatingStringArray(result, "A"),
    472                 diff);
    473         doTestRemoveNames(makeStringArray(lhs), makeStringArray(rhs),
    474                 makeStringArray(result), diff);
    475     }
    476 
    477     public void testRemoveNone() throws Exception {
    478         doTestRemove(
    479                 new int[] { 10, 20, 30, 40 },
    480                 new int[] { 1, 2, 35, 50 },
    481                 new int[] { 10, 20, 30, 40 },
    482                 false);
    483     }
    484 
    485     public void testRemoveMultiFront() throws Exception {
    486         doTestRemove(
    487                 new int[] { 10, 20, 30, 40 },
    488                 new int[] { 1, 2, 10, 30 },
    489                 new int[] { 20, 40 },
    490                 true);
    491     }
    492 
    493     public void testRemoveMultiMiddle() throws Exception {
    494         doTestRemove(
    495                 new int[] { 10, 20, 30, 40 },
    496                 new int[] { 20, 30 },
    497                 new int[] { 10, 40 },
    498                 true);
    499     }
    500 
    501     public void testRemoveMultiEnd() throws Exception {
    502         doTestRemove(
    503                 new int[] { 10, 20, 30, 40 },
    504                 new int[] { 30, 40, 50 },
    505                 new int[] { 10, 20 },
    506                 true);
    507     }
    508 
    509     public void testRemoveMultiFull() throws Exception {
    510         doTestRemove(
    511                 new int[] { 10, 20, 30, 40 },
    512                 new int[] { 1, 2, 20, 25, 35, 40 },
    513                 new int[] { 10, 30 },
    514                 true);
    515     }
    516 
    517     public void testRemoveMultiAll() throws Exception {
    518         doTestRemove(
    519                 new int[] { 10, 20, 30, 40 },
    520                 new int[] { 10, 20, 30, 40 },
    521                 new int[] { },
    522                 true);
    523     }
    524 }
    525