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