New CTS test for WorkSource class.
Change-Id: I3cb10ab9930a07fe89de97a283f7c8287061a013
diff --git a/tests/tests/os/src/android/os/cts/WorkSourceTest.java b/tests/tests/os/src/android/os/cts/WorkSourceTest.java
new file mode 100644
index 0000000..f3986b1
--- /dev/null
+++ b/tests/tests/os/src/android/os/cts/WorkSourceTest.java
@@ -0,0 +1,557 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.os.cts;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import android.os.WorkSource;
+import android.test.AndroidTestCase;
+
+public class WorkSourceTest extends AndroidTestCase {
+ private Constructor<WorkSource> mConstructWS;
+ private Object[] mConstructWSArgs = new Object[1];
+ private Method mAddUid;
+ private Object[] mAddUidArgs = new Object[1];
+ private Method mAddUidName;
+ private Object[] mAddUidNameArgs = new Object[2];
+ private Method mAddReturningNewbs;
+ private Object[] mAddReturningNewbsArgs = new Object[1];
+ private Method mSetReturningDiffs;
+ private Object[] mSetReturningDiffsArgs = new Object[1];
+ private Method mStripNames;
+ private Object[] mStripNamesArgs = new Object[0];
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mConstructWS = WorkSource.class.getConstructor(new Class[] { int.class });
+ mAddUid = WorkSource.class.getMethod("add", new Class[] { int.class });
+ mAddUidName = WorkSource.class.getMethod("add", new Class[] { int.class, String.class });
+ mAddReturningNewbs = WorkSource.class.getMethod("addReturningNewbs", new Class[] { WorkSource.class });
+ mSetReturningDiffs = WorkSource.class.getMethod("setReturningDiffs", new Class[] { WorkSource.class });
+ mStripNames = WorkSource.class.getMethod("stripNames", new Class[] { });
+ }
+
+ private WorkSource wsNew(int uid) throws IllegalArgumentException,
+ InstantiationException, IllegalAccessException, InvocationTargetException {
+ mConstructWSArgs[0] = uid;
+ return mConstructWS.newInstance(mConstructWSArgs);
+ }
+
+ private WorkSource wsNew(int[] uids) throws IllegalArgumentException,
+ InstantiationException, IllegalAccessException, InvocationTargetException {
+ WorkSource ws = new WorkSource();
+ for (int i=0; i<uids.length; i++) {
+ wsAdd(ws, uids[i]);
+ }
+ checkWorkSource("Constructed", ws, uids);
+ return ws;
+ }
+
+ private WorkSource wsNew(int[] uids, String[] names) throws IllegalArgumentException,
+ InstantiationException, IllegalAccessException, InvocationTargetException {
+ WorkSource ws = new WorkSource();
+ for (int i=0; i<uids.length; i++) {
+ wsAdd(ws, uids[i], names[i]);
+ }
+ checkWorkSource("Constructed", ws, uids, names);
+ return ws;
+ }
+
+ private boolean wsAdd(WorkSource ws, int uid) throws IllegalArgumentException,
+ InstantiationException, IllegalAccessException, InvocationTargetException {
+ mAddUidArgs[0] = uid;
+ return (Boolean)mAddUid.invoke(ws, mAddUidArgs);
+ }
+
+ private boolean wsAdd(WorkSource ws, int uid, String name) throws IllegalArgumentException,
+ InstantiationException, IllegalAccessException, InvocationTargetException {
+ mAddUidNameArgs[0] = uid;
+ mAddUidNameArgs[1] = name;
+ return (Boolean)mAddUidName.invoke(ws, mAddUidNameArgs);
+ }
+
+ private WorkSource wsAddReturningNewbs(WorkSource ws, WorkSource other) throws IllegalArgumentException,
+ InstantiationException, IllegalAccessException, InvocationTargetException {
+ mAddReturningNewbsArgs[0] = other;
+ return (WorkSource)mAddReturningNewbs.invoke(ws, mAddReturningNewbsArgs);
+ }
+
+ private WorkSource[] wsSetReturningDiffs(WorkSource ws, WorkSource other) throws IllegalArgumentException,
+ InstantiationException, IllegalAccessException, InvocationTargetException {
+ mSetReturningDiffsArgs[0] = other;
+ return (WorkSource[])mSetReturningDiffs.invoke(ws, mSetReturningDiffsArgs);
+ }
+
+ private WorkSource wsStripNames(WorkSource ws) throws IllegalArgumentException,
+ InstantiationException, IllegalAccessException, InvocationTargetException {
+ return (WorkSource)mStripNames.invoke(ws);
+ }
+
+ private void printArrays(StringBuilder sb, int[] uids, String[] names) {
+ sb.append("{ ");
+ for (int i=0; i<uids.length; i++) {
+ if (i > 0) sb.append(", ");
+ sb.append(uids[i]);
+ if (names != null) {
+ sb.append(" ");
+ sb.append(names[i]);
+ }
+ }
+ sb.append(" }");
+ }
+
+ private void failWorkSource(String op, WorkSource ws, int[] uids) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(op);
+ sb.append(": Expected: ");
+ printArrays(sb, uids, null);
+ sb.append(", got: ");
+ sb.append(ws);
+ fail(sb.toString());
+ }
+
+ private void failWorkSource(String op, WorkSource ws, int[] uids, String[] names) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(op);
+ sb.append(": Expected: ");
+ printArrays(sb, uids, names);
+ sb.append(", got: ");
+ sb.append(ws);
+ fail(sb.toString());
+ }
+
+ private void checkWorkSource(String op, WorkSource ws, int[] uids) {
+ if (ws == null || uids == null) {
+ if (ws != null) {
+ fail(op + ": WorkSource is not null " + ws +", but expected null");
+ }
+ if (uids != null) {
+ fail(op + "WorkSource is null, but expected non-null: " + uids);
+ }
+ return;
+ }
+ if (ws.size() != uids.length) {
+ failWorkSource(op, ws, uids);
+ }
+ for (int i=0; i<uids.length; i++) {
+ if (uids[i] != ws.get(i)) {
+ failWorkSource(op, ws, uids);
+ }
+ }
+ }
+
+ private void checkWorkSource(String op, WorkSource ws, int[] uids, String[] names) {
+ if (ws == null || uids == null) {
+ if (ws != null) {
+ fail(op + ": WorkSource is not null " + ws +", but expected null");
+ }
+ if (uids != null) {
+ fail(op + "WorkSource is null, but expected non-null: " + uids);
+ }
+ return;
+ }
+ if (ws.size() != uids.length) {
+ failWorkSource(op, ws, uids, names);
+ }
+ for (int i=0; i<uids.length; i++) {
+ if (uids[i] != ws.get(i) || !names[i].equals(ws.getName(i))) {
+ failWorkSource(op, ws, uids, names);
+ }
+ }
+ }
+
+ public void testConstructEmpty() {
+ checkWorkSource("Empty", new WorkSource(), new int[] { });
+ }
+
+ public void testConstructSingle() throws Exception {
+ checkWorkSource("Single 1", wsNew(1), new int[] { 1 });
+ }
+
+ public void testAddRawOrdered() throws Exception {
+ WorkSource ws = wsNew(1);
+ wsAdd(ws, 2);
+ checkWorkSource("First", ws, new int[] { 1 , 2 });
+ wsAdd(ws, 20);
+ checkWorkSource("Second", ws, new int[] { 1 , 2, 20 });
+ wsAdd(ws, 100);
+ checkWorkSource("Third", ws, new int[] { 1, 2, 20, 100 });
+ }
+
+ public void testAddRawRevOrdered() throws Exception {
+ WorkSource ws = wsNew(100);
+ wsAdd(ws, 20);
+ checkWorkSource("First", ws, new int[] { 20, 100 });
+ wsAdd(ws, 2);
+ checkWorkSource("Second", ws, new int[] { 2, 20, 100 });
+ wsAdd(ws, 1);
+ checkWorkSource("Third", ws, new int[] { 1, 2, 20, 100 });
+ }
+
+ public void testAddRawUnordered() throws Exception {
+ WorkSource ws = wsNew(10);
+ wsAdd(ws, 2);
+ checkWorkSource("First", ws, new int[] { 2, 10 });
+ wsAdd(ws, 5);
+ checkWorkSource("Second", ws, new int[] { 2, 5, 10 });
+ wsAdd(ws, 1);
+ checkWorkSource("Third", ws, new int[] { 1, 2, 5, 10 });
+ wsAdd(ws, 100);
+ checkWorkSource("Fourth", ws, new int[] { 1, 2, 5, 10, 100 });
+ }
+
+ public void testAddWsOrdered() throws Exception {
+ WorkSource ws = wsNew(1);
+ ws.add(wsNew(2));
+ checkWorkSource("First", ws, new int[] { 1 , 2 });
+ ws.add(wsNew(20));
+ checkWorkSource("Second", ws, new int[] { 1 , 2, 20 });
+ ws.add(wsNew(100));
+ checkWorkSource("Third", ws, new int[] { 1 , 2, 20, 100 });
+ }
+
+ public void testAddWsRevOrdered() throws Exception {
+ WorkSource ws = wsNew(100);
+ ws.add(wsNew(20));
+ checkWorkSource("First", ws, new int[] { 20, 100 });
+ ws.add(wsNew(2));
+ checkWorkSource("Second", ws, new int[] { 2, 20, 100 });
+ ws.add(wsNew(1));
+ checkWorkSource("Third", ws, new int[] { 1, 2, 20, 100 });
+ }
+
+ public void testAddWsUnordered() throws Exception {
+ WorkSource ws = wsNew(10);
+ ws.add(wsNew(2));
+ checkWorkSource("First", ws, new int[] { 2, 10 });
+ ws.add(wsNew(5));
+ checkWorkSource("Second", ws, new int[] { 2, 5, 10 });
+ ws.add(wsNew(1));
+ checkWorkSource("Third", ws, new int[] { 1, 2, 5, 10 });
+ ws.add(wsNew(100));
+ checkWorkSource("Fourth", ws, new int[] { 1, 2, 5, 10, 100 });
+ }
+
+ private void doTestCombineTwoUids(int[] lhs, int[] rhs, int[] expected, int[] newbs,
+ int[] gones) throws Exception {
+ WorkSource ws1 = wsNew(lhs);
+ WorkSource ws2 = wsNew(rhs);
+ ws1.add(ws2);
+ checkWorkSource("Add result", ws1, expected);
+ ws1 = wsNew(lhs);
+ WorkSource wsNewbs = wsAddReturningNewbs(ws1, ws2);
+ checkWorkSource("AddReturning result", ws1, expected);
+ checkWorkSource("Newbs", wsNewbs, newbs);
+ ws1 = wsNew(lhs);
+ WorkSource[] res = wsSetReturningDiffs(ws1, ws2);
+ checkWorkSource("SetReturning result", ws1, rhs);
+ checkWorkSource("Newbs", res[0], newbs);
+ checkWorkSource("Gones", res[1], gones);
+ }
+
+ private int[] makeRepeatingIntArray(String[] stringarray, int value) {
+ if (stringarray == null) {
+ return null;
+ }
+ int[] res = new int[stringarray.length];
+ for (int i=0; i<stringarray.length; i++) {
+ res[i] = value;
+ }
+ return res;
+ }
+
+ private void doTestCombineTwoNames(String[] lhsnames, String[] rhsnames,
+ String[] expectednames, String[] newbnames,
+ String[] gonenames) throws Exception {
+ int[] lhs = makeRepeatingIntArray(lhsnames, 0);
+ int[] rhs = makeRepeatingIntArray(rhsnames, 0);
+ int[] expected = makeRepeatingIntArray(expectednames, 0);
+ int[] newbs = makeRepeatingIntArray(newbnames, 0);
+ int[] gones = makeRepeatingIntArray(gonenames, 0);
+ doTestCombineTwoUidsNames(lhs, lhsnames, rhs, rhsnames, expected, expectednames,
+ newbs, newbnames, gones, gonenames);
+ }
+
+ private void doTestCombineTwoUidsNames(int[] lhs, String[] lhsnames, int[] rhs, String[] rhsnames,
+ int[] expected, String[] expectednames, int[] newbs, String[] newbnames,
+ int[] gones, String[] gonenames) throws Exception {
+ WorkSource ws1 = wsNew(lhs, lhsnames);
+ WorkSource ws2 = wsNew(rhs, rhsnames);
+ ws1.add(ws2);
+ checkWorkSource("Add result", ws1, expected, expectednames);
+ ws1 = wsNew(lhs, lhsnames);
+ WorkSource wsNewbs = wsAddReturningNewbs(ws1, ws2);
+ checkWorkSource("AddReturning result", ws1, expected, expectednames);
+ checkWorkSource("Newbs", wsNewbs, newbs, newbnames);
+ ws1 = wsNew(lhs, lhsnames);
+ WorkSource[] res = wsSetReturningDiffs(ws1, ws2);
+ checkWorkSource("SetReturning result", ws1, rhs, rhsnames);
+ checkWorkSource("Newbs", res[0], newbs, newbnames);
+ checkWorkSource("Gones", res[1], gones, gonenames);
+ }
+
+ private String[] makeRepeatingStringArray(int[] intarray, String value) {
+ if (intarray == null) {
+ return null;
+ }
+ String[] res = new String[intarray.length];
+ for (int i=0; i<intarray.length; i++) {
+ res[i] = value;
+ }
+ return res;
+ }
+
+ private String[] makeStringArray(int[] intarray) {
+ if (intarray == null) {
+ return null;
+ }
+ String[] res = new String[intarray.length];
+ for (int i=0; i<intarray.length; i++) {
+ res[i] = Character.toString((char)('A' + intarray[i]));
+ }
+ return res;
+ }
+
+ private void doTestCombineTwo(int[] lhs, int[] rhs, int[] expected, int[] newbs,
+ int[] gones) throws Exception {
+ doTestCombineTwoUids(lhs, rhs, expected, newbs, gones);
+ doTestCombineTwoUidsNames(lhs, makeRepeatingStringArray(lhs, "A"),
+ rhs, makeRepeatingStringArray(rhs, "A"),
+ expected, makeRepeatingStringArray(expected, "A"),
+ newbs, makeRepeatingStringArray(newbs, "A"),
+ gones, makeRepeatingStringArray(gones, "A"));
+ doTestCombineTwoNames(makeStringArray(lhs), makeStringArray(rhs),
+ makeStringArray(expected), makeStringArray(newbs), makeStringArray(gones));
+ }
+
+ public void testCombineMultiFront() throws Exception {
+ doTestCombineTwo(
+ new int[] { 10, 20, 30, 40 },
+ new int[] { 1, 2, 15, 16 },
+ new int[] { 1, 2, 10, 15, 16, 20, 30, 40 },
+ new int[] { 1, 2, 15, 16 },
+ new int[] { 10, 20, 30, 40 });
+ }
+
+ public void testCombineMultiMiddle() throws Exception {
+ doTestCombineTwo(
+ new int[] { 10, 20, 30, 40 },
+ new int[] { 12, 14, 22 },
+ new int[] { 10, 12, 14, 20, 22, 30, 40 },
+ new int[] { 12, 14, 22 },
+ new int[] { 10, 20, 30, 40 });
+ }
+
+ public void testCombineMultiEnd() throws Exception {
+ doTestCombineTwo(
+ new int[] { 10, 20, 30, 40 },
+ new int[] { 35, 45, 50 },
+ new int[] { 10, 20, 30, 35, 40, 45, 50 },
+ new int[] { 35, 45, 50 },
+ new int[] { 10, 20, 30, 40 });
+ }
+
+ public void testCombineMultiFull() throws Exception {
+ doTestCombineTwo(
+ new int[] { 10, 20, 30, 40 },
+ new int[] { 1, 2, 15, 35, 50 },
+ new int[] { 1, 2, 10, 15, 20, 30, 35, 40, 50 },
+ new int[] { 1, 2, 15, 35, 50 },
+ new int[] { 10, 20, 30, 40 });
+ }
+
+ public void testCombineMultiSame() throws Exception {
+ doTestCombineTwo(
+ new int[] { 10, 20, 30, 40 },
+ new int[] { 10, 20, 30 },
+ new int[] { 10, 20, 30, 40 },
+ null,
+ new int[] { 40 });
+ }
+
+ public void testCombineMultiSomeSame() throws Exception {
+ doTestCombineTwo(
+ new int[] { 10, 20, 30, 40 },
+ new int[] { 1, 30, 40 },
+ new int[] { 1, 10, 20, 30, 40 },
+ new int[] { 1 },
+ new int[] { 10, 20 });
+ }
+
+ public void testCombineMultiSomeSameUidsNames() throws Exception {
+ doTestCombineTwoUidsNames(
+ new int[] { 10, 10, 20, 30, 30, 30, 40 },
+ new String[] { "A", "B", "A", "A", "B", "C", "A" },
+ new int[] { 1, 30, 40, 50 },
+ new String[] { "A", "A", "B", "A" },
+ new int[] { 1, 10, 10, 20, 30, 30, 30, 40, 40, 50 },
+ new String[] { "A", "A", "B", "A", "A", "B", "C", "A", "B", "A" },
+ new int[] { 1, 40, 50 },
+ new String[] { "A", "B", "A" },
+ new int[] { 10, 10, 20, 30, 30, 40 },
+ new String[] { "A", "B", "A", "B", "C", "A" });
+ }
+
+ private void doTestRemoveUids(int[] lhs, int[] rhs, int[] result, boolean diff) throws Exception {
+ WorkSource ws1 = wsNew(lhs);
+ WorkSource ws2 = wsNew(rhs);
+ boolean diffres = ws1.remove(ws2);
+ if (diffres != diff) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("Expected diff ");
+ sb.append(diff);
+ sb.append(" but got ");
+ sb.append(diffres);
+ sb.append(" when removing ");
+ sb.append(ws2);
+ sb.append(" from ");
+ sb.append(ws1);
+ fail(sb.toString());
+ }
+ checkWorkSource("Remove", ws1, result);
+ }
+
+ private void doTestRemoveNames(String[] lhsnames, String[] rhsnames,
+ String[] resultnames, boolean diff) throws Exception {
+ int[] lhs = makeRepeatingIntArray(lhsnames, 0);
+ int[] rhs = makeRepeatingIntArray(rhsnames, 0);
+ int[] result = makeRepeatingIntArray(resultnames, 0);
+ WorkSource ws1 = wsNew(lhs, lhsnames);
+ WorkSource ws2 = wsNew(rhs, rhsnames);
+ boolean diffres = ws1.remove(ws2);
+ if (diffres != diff) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("Expected diff ");
+ sb.append(diff);
+ sb.append(" but got ");
+ sb.append(diffres);
+ sb.append(" when removing ");
+ sb.append(ws2);
+ sb.append(" from ");
+ sb.append(ws1);
+ fail(sb.toString());
+ }
+ checkWorkSource("Remove", ws1, result, resultnames);
+ }
+
+ private void doTestRemoveUidsNames(int[] lhs, String[] lhsnames, int[] rhs, String[] rhsnames,
+ int[] result, String[] resultnames, boolean diff) throws Exception {
+ WorkSource ws1 = wsNew(lhs, lhsnames);
+ WorkSource ws2 = wsNew(rhs, rhsnames);
+ boolean diffres = ws1.remove(ws2);
+ if (diffres != diff) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("Expected diff ");
+ sb.append(diff);
+ sb.append(" but got ");
+ sb.append(diffres);
+ sb.append(" when removing ");
+ sb.append(ws2);
+ sb.append(" from ");
+ sb.append(ws1);
+ fail(sb.toString());
+ }
+ checkWorkSource("Remove", ws1, result, resultnames);
+ }
+
+ private void doTestRemove(int[] lhs, int[] rhs, int[] result, boolean diff) throws Exception {
+ doTestRemoveUids(lhs, rhs, result, diff);
+ doTestRemoveUidsNames(lhs, makeRepeatingStringArray(lhs, "A"),
+ rhs, makeRepeatingStringArray(rhs, "A"),
+ result, makeRepeatingStringArray(result, "A"),
+ diff);
+ doTestRemoveNames(makeStringArray(lhs), makeStringArray(rhs),
+ makeStringArray(result), diff);
+ }
+
+ public void testRemoveNone() throws Exception {
+ doTestRemove(
+ new int[] { 10, 20, 30, 40 },
+ new int[] { 1, 2, 35, 50 },
+ new int[] { 10, 20, 30, 40 },
+ false);
+ }
+
+ public void testRemoveMultiFront() throws Exception {
+ doTestRemove(
+ new int[] { 10, 20, 30, 40 },
+ new int[] { 1, 2, 10, 30 },
+ new int[] { 20, 40 },
+ true);
+ }
+
+ public void testRemoveMultiMiddle() throws Exception {
+ doTestRemove(
+ new int[] { 10, 20, 30, 40 },
+ new int[] { 20, 30 },
+ new int[] { 10, 40 },
+ true);
+ }
+
+ public void testRemoveMultiEnd() throws Exception {
+ doTestRemove(
+ new int[] { 10, 20, 30, 40 },
+ new int[] { 30, 40, 50 },
+ new int[] { 10, 20 },
+ true);
+ }
+
+ public void testRemoveMultiFull() throws Exception {
+ doTestRemove(
+ new int[] { 10, 20, 30, 40 },
+ new int[] { 1, 2, 20, 25, 35, 40 },
+ new int[] { 10, 30 },
+ true);
+ }
+
+ public void testRemoveMultiAll() throws Exception {
+ doTestRemove(
+ new int[] { 10, 20, 30, 40 },
+ new int[] { 10, 20, 30, 40 },
+ new int[] { },
+ true);
+ }
+
+ private void doTestStripNames(int[] uids, String[] names, int[] expected) throws Exception {
+ WorkSource ws1 = wsNew(uids, names);
+ WorkSource res = wsStripNames(ws1);
+ checkWorkSource("StripNames", res, expected);
+ }
+
+ public void testStripNamesSimple() throws Exception {
+ doTestStripNames(
+ new int[] { 10, 20, 30, 40 },
+ new String[] { "A", "A", "A", "A" },
+ new int[] { 10, 20, 30, 40 });
+ }
+
+ public void testStripNamesFull() throws Exception {
+ doTestStripNames(
+ new int[] { 10, 10, 10, 10 },
+ new String[] { "A", "B", "C", "D" },
+ new int[] { 10 });
+ }
+
+ public void testStripNamesComplex() throws Exception {
+ doTestStripNames(
+ new int[] { 10, 20, 20, 30, 40, 40 },
+ new String[] { "A", "A", "B", "A", "A", "B" },
+ new int[] { 10, 20, 30, 40 });
+ }
+}