1 /* 2 * Copyright (C) 2015 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 com.android.ahat; 18 19 import com.android.ahat.heapdump.AhatClassObj; 20 import com.android.ahat.heapdump.AhatHeap; 21 import com.android.ahat.heapdump.AhatInstance; 22 import com.android.ahat.heapdump.AhatSnapshot; 23 import com.android.ahat.heapdump.PathElement; 24 import com.android.ahat.heapdump.Reachability; 25 import com.android.ahat.heapdump.Size; 26 import com.android.ahat.heapdump.Value; 27 import java.io.IOException; 28 import java.util.List; 29 import org.junit.Test; 30 31 import static org.junit.Assert.assertEquals; 32 import static org.junit.Assert.assertFalse; 33 import static org.junit.Assert.assertNotNull; 34 import static org.junit.Assert.assertNull; 35 import static org.junit.Assert.assertTrue; 36 37 public class InstanceTest { 38 @Test asStringBasic()39 public void asStringBasic() throws IOException { 40 TestDump dump = TestDump.getTestDump(); 41 AhatInstance str = dump.getDumpedAhatInstance("basicString"); 42 assertEquals("hello, world", str.asString()); 43 } 44 45 @Test asStringNonAscii()46 public void asStringNonAscii() throws IOException { 47 TestDump dump = TestDump.getTestDump(); 48 AhatInstance str = dump.getDumpedAhatInstance("nonAscii"); 49 assertEquals("Sigma (Ʃ) is not ASCII", str.asString()); 50 } 51 52 @Test asStringEmbeddedZero()53 public void asStringEmbeddedZero() throws IOException { 54 TestDump dump = TestDump.getTestDump(); 55 AhatInstance str = dump.getDumpedAhatInstance("embeddedZero"); 56 assertEquals("embedded\0...", str.asString()); 57 } 58 59 @Test asStringCharArray()60 public void asStringCharArray() throws IOException { 61 TestDump dump = TestDump.getTestDump(); 62 AhatInstance str = dump.getDumpedAhatInstance("charArray"); 63 assertEquals("char thing", str.asString()); 64 } 65 66 @Test asStringTruncated()67 public void asStringTruncated() throws IOException { 68 TestDump dump = TestDump.getTestDump(); 69 AhatInstance str = dump.getDumpedAhatInstance("basicString"); 70 assertEquals("hello", str.asString(5)); 71 } 72 73 @Test asStringTruncatedNonAscii()74 public void asStringTruncatedNonAscii() throws IOException { 75 TestDump dump = TestDump.getTestDump(); 76 AhatInstance str = dump.getDumpedAhatInstance("nonAscii"); 77 assertEquals("Sigma (Ʃ)", str.asString(9)); 78 } 79 80 @Test asStringTruncatedEmbeddedZero()81 public void asStringTruncatedEmbeddedZero() throws IOException { 82 TestDump dump = TestDump.getTestDump(); 83 AhatInstance str = dump.getDumpedAhatInstance("embeddedZero"); 84 assertEquals("embed", str.asString(5)); 85 } 86 87 @Test asStringCharArrayTruncated()88 public void asStringCharArrayTruncated() throws IOException { 89 TestDump dump = TestDump.getTestDump(); 90 AhatInstance str = dump.getDumpedAhatInstance("charArray"); 91 assertEquals("char ", str.asString(5)); 92 } 93 94 @Test asStringExactMax()95 public void asStringExactMax() throws IOException { 96 TestDump dump = TestDump.getTestDump(); 97 AhatInstance str = dump.getDumpedAhatInstance("basicString"); 98 assertEquals("hello, world", str.asString(12)); 99 } 100 101 @Test asStringExactMaxNonAscii()102 public void asStringExactMaxNonAscii() throws IOException { 103 TestDump dump = TestDump.getTestDump(); 104 AhatInstance str = dump.getDumpedAhatInstance("nonAscii"); 105 assertEquals("Sigma (Ʃ) is not ASCII", str.asString(22)); 106 } 107 108 @Test asStringExactMaxEmbeddedZero()109 public void asStringExactMaxEmbeddedZero() throws IOException { 110 TestDump dump = TestDump.getTestDump(); 111 AhatInstance str = dump.getDumpedAhatInstance("embeddedZero"); 112 assertEquals("embedded\0...", str.asString(12)); 113 } 114 115 @Test asStringCharArrayExactMax()116 public void asStringCharArrayExactMax() throws IOException { 117 TestDump dump = TestDump.getTestDump(); 118 AhatInstance str = dump.getDumpedAhatInstance("charArray"); 119 assertEquals("char thing", str.asString(10)); 120 } 121 122 @Test asStringNotTruncated()123 public void asStringNotTruncated() throws IOException { 124 TestDump dump = TestDump.getTestDump(); 125 AhatInstance str = dump.getDumpedAhatInstance("basicString"); 126 assertEquals("hello, world", str.asString(50)); 127 } 128 129 @Test asStringNotTruncatedNonAscii()130 public void asStringNotTruncatedNonAscii() throws IOException { 131 TestDump dump = TestDump.getTestDump(); 132 AhatInstance str = dump.getDumpedAhatInstance("nonAscii"); 133 assertEquals("Sigma (Ʃ) is not ASCII", str.asString(50)); 134 } 135 136 @Test asStringNotTruncatedEmbeddedZero()137 public void asStringNotTruncatedEmbeddedZero() throws IOException { 138 TestDump dump = TestDump.getTestDump(); 139 AhatInstance str = dump.getDumpedAhatInstance("embeddedZero"); 140 assertEquals("embedded\0...", str.asString(50)); 141 } 142 143 @Test asStringCharArrayNotTruncated()144 public void asStringCharArrayNotTruncated() throws IOException { 145 TestDump dump = TestDump.getTestDump(); 146 AhatInstance str = dump.getDumpedAhatInstance("charArray"); 147 assertEquals("char thing", str.asString(50)); 148 } 149 150 @Test asStringNegativeMax()151 public void asStringNegativeMax() throws IOException { 152 TestDump dump = TestDump.getTestDump(); 153 AhatInstance str = dump.getDumpedAhatInstance("basicString"); 154 assertEquals("hello, world", str.asString(-3)); 155 } 156 157 @Test asStringNegativeMaxNonAscii()158 public void asStringNegativeMaxNonAscii() throws IOException { 159 TestDump dump = TestDump.getTestDump(); 160 AhatInstance str = dump.getDumpedAhatInstance("nonAscii"); 161 assertEquals("Sigma (Ʃ) is not ASCII", str.asString(-3)); 162 } 163 164 @Test asStringNegativeMaxEmbeddedZero()165 public void asStringNegativeMaxEmbeddedZero() throws IOException { 166 TestDump dump = TestDump.getTestDump(); 167 AhatInstance str = dump.getDumpedAhatInstance("embeddedZero"); 168 assertEquals("embedded\0...", str.asString(-3)); 169 } 170 171 @Test asStringCharArrayNegativeMax()172 public void asStringCharArrayNegativeMax() throws IOException { 173 TestDump dump = TestDump.getTestDump(); 174 AhatInstance str = dump.getDumpedAhatInstance("charArray"); 175 assertEquals("char thing", str.asString(-3)); 176 } 177 178 @Test asStringNull()179 public void asStringNull() throws IOException { 180 TestDump dump = TestDump.getTestDump(); 181 AhatInstance obj = dump.getDumpedAhatInstance("nullString"); 182 assertNull(obj); 183 } 184 185 @Test asStringNotString()186 public void asStringNotString() throws IOException { 187 TestDump dump = TestDump.getTestDump(); 188 AhatInstance obj = dump.getDumpedAhatInstance("anObject"); 189 assertNotNull(obj); 190 assertNull(obj.asString()); 191 } 192 193 @Test basicReference()194 public void basicReference() throws IOException { 195 TestDump dump = TestDump.getTestDump(); 196 197 AhatInstance pref = dump.getDumpedAhatInstance("aPhantomReference"); 198 AhatInstance wref = dump.getDumpedAhatInstance("aWeakReference"); 199 AhatInstance nref = dump.getDumpedAhatInstance("aNullReferentReference"); 200 AhatInstance referent = dump.getDumpedAhatInstance("anObject"); 201 assertNotNull(pref); 202 assertNotNull(wref); 203 assertNotNull(nref); 204 assertNotNull(referent); 205 assertEquals(referent, pref.getReferent()); 206 assertEquals(referent, wref.getReferent()); 207 assertNull(nref.getReferent()); 208 assertNull(referent.getReferent()); 209 } 210 211 @Test unreachableReferent()212 public void unreachableReferent() throws IOException { 213 // The test dump program should never be under enough GC pressure for the 214 // soft reference to be cleared. Ensure that ahat will show the soft 215 // reference as having a non-null referent. 216 TestDump dump = TestDump.getTestDump(); 217 AhatInstance ref = dump.getDumpedAhatInstance("aSoftReference"); 218 AhatInstance referent = ref.getReferent(); 219 assertNotNull(referent); 220 assertEquals(Reachability.SOFT, referent.getReachability()); 221 assertTrue(referent.isWeaklyReachable()); 222 } 223 224 @Test reachability()225 public void reachability() throws IOException { 226 TestDump dump = TestDump.getTestDump(); 227 AhatInstance strong1 = dump.getDumpedAhatInstance("reachabilityReferenceChain"); 228 AhatInstance soft1 = strong1.getField("referent").asAhatInstance(); 229 AhatInstance strong2 = soft1.getField("referent").asAhatInstance(); 230 AhatInstance weak1 = strong2.getField("referent").asAhatInstance(); 231 AhatInstance soft2 = weak1.getField("referent").asAhatInstance(); 232 AhatInstance phantom1 = soft2.getField("referent").asAhatInstance(); 233 AhatInstance obj = phantom1.getField("referent").asAhatInstance(); 234 235 assertEquals(Reachability.STRONG, strong1.getReachability()); 236 assertEquals(Reachability.STRONG, soft1.getReachability()); 237 assertEquals(Reachability.SOFT, strong2.getReachability()); 238 assertEquals(Reachability.SOFT, weak1.getReachability()); 239 assertEquals(Reachability.WEAK, soft2.getReachability()); 240 assertEquals(Reachability.WEAK, phantom1.getReachability()); 241 assertEquals(Reachability.PHANTOM, obj.getReachability()); 242 } 243 244 @Test gcRootPath()245 public void gcRootPath() throws IOException { 246 TestDump dump = TestDump.getTestDump(); 247 248 AhatClassObj main = dump.findClass("Main"); 249 AhatInstance gcPathArray = dump.getDumpedAhatInstance("gcPathArray"); 250 Value value = gcPathArray.asArrayInstance().getValue(2); 251 AhatInstance base = value.asAhatInstance(); 252 AhatInstance left = base.getRefField("left"); 253 AhatInstance right = base.getRefField("right"); 254 AhatInstance target = left.getRefField("right"); 255 256 List<PathElement> path = target.getPathFromGcRoot(); 257 assertEquals(6, path.size()); 258 259 assertEquals(main, path.get(0).instance); 260 assertEquals(".stuff", path.get(0).field); 261 assertTrue(path.get(0).isDominator); 262 263 assertEquals(".gcPathArray", path.get(1).field); 264 assertTrue(path.get(1).isDominator); 265 266 assertEquals(gcPathArray, path.get(2).instance); 267 assertEquals("[2]", path.get(2).field); 268 assertTrue(path.get(2).isDominator); 269 270 assertEquals(base, path.get(3).instance); 271 assertTrue(path.get(3).isDominator); 272 273 // There are two possible paths. Either it can go through the 'left' node, 274 // or the 'right' node. 275 if (path.get(3).field.equals(".left")) { 276 assertEquals(".left", path.get(3).field); 277 278 assertEquals(left, path.get(4).instance); 279 assertEquals(".right", path.get(4).field); 280 assertFalse(path.get(4).isDominator); 281 282 } else { 283 assertEquals(".right", path.get(3).field); 284 285 assertEquals(right, path.get(4).instance); 286 assertEquals(".left", path.get(4).field); 287 assertFalse(path.get(4).isDominator); 288 } 289 290 assertEquals(target, path.get(5).instance); 291 assertEquals("", path.get(5).field); 292 assertTrue(path.get(5).isDominator); 293 } 294 295 @Test gcRootPathNotWeak()296 public void gcRootPathNotWeak() throws IOException { 297 TestDump dump = TestDump.getTestDump(); 298 299 // The test dump is set up to have the following graph: 300 // -S-> strong1 -S-> strong2 -S-> strong3 -S-> object 301 // -S-> weak1 -W-> weak2 ------------------S->-/ 302 // The gc root path should go through the longer chain of strong 303 // references, not the shorter chain with weak references (even though the 304 // last element in the shorter chain is a strong reference). 305 306 AhatInstance strong1 = dump.getDumpedAhatInstance("aLongStrongPathToSamplePathObject"); 307 AhatInstance strong2 = strong1.getField("referent").asAhatInstance(); 308 AhatInstance strong3 = strong2.getField("referent").asAhatInstance(); 309 AhatInstance object = strong3.getField("referent").asAhatInstance(); 310 311 List<PathElement> path = object.getPathFromGcRoot(); 312 assertEquals(strong3, path.get(path.size() - 2).instance); 313 } 314 315 @Test retainedSize()316 public void retainedSize() throws IOException { 317 TestDump dump = TestDump.getTestDump(); 318 319 // anObject should not be an immediate dominator of any other object. This 320 // means its retained size should be equal to its size for the heap it was 321 // allocated on, and should be 0 for all other heaps. 322 AhatInstance anObject = dump.getDumpedAhatInstance("anObject"); 323 AhatSnapshot snapshot = dump.getAhatSnapshot(); 324 Size size = anObject.getSize(); 325 assertEquals(size, anObject.getTotalRetainedSize()); 326 assertEquals(size, anObject.getRetainedSize(anObject.getHeap())); 327 for (AhatHeap heap : snapshot.getHeaps()) { 328 if (!heap.equals(anObject.getHeap())) { 329 assertEquals(String.format("For heap '%s'", heap.getName()), 330 Size.ZERO, anObject.getRetainedSize(heap)); 331 } 332 } 333 } 334 335 @Test retainedSizeByRetained()336 public void retainedSizeByRetained() throws IOException { 337 // The test dump program should never be under enough GC pressure for the 338 // soft reference to be cleared. The referent should be included in 339 // retained size if --retained is soft, but not if --retained is strong. 340 TestDump dumpStrong = TestDump.getTestDump("test-dump.hprof", 341 "test-dump-base.hprof", 342 "test-dump.map", 343 Reachability.STRONG); 344 AhatInstance refStrong = dumpStrong.getDumpedAhatInstance("aSoftReference"); 345 long sizeStrong = refStrong.getTotalRetainedSize().getSize(); 346 347 TestDump dumpSoft = TestDump.getTestDump("test-dump.hprof", 348 "test-dump-base.hprof", 349 "test-dump.map", 350 Reachability.SOFT); 351 AhatInstance refSoft = dumpSoft.getDumpedAhatInstance("aSoftReference"); 352 long sizeSoft = refSoft.getTotalRetainedSize().getSize(); 353 354 assertTrue(sizeStrong < sizeSoft); 355 } 356 357 @Test 358 public void objectNotABitmap() throws IOException { 359 TestDump dump = TestDump.getTestDump(); 360 AhatInstance obj = dump.getDumpedAhatInstance("anObject"); 361 assertNull(obj.asBitmap()); 362 } 363 364 @Test 365 public void arrayNotABitmap() throws IOException { 366 TestDump dump = TestDump.getTestDump(); 367 AhatInstance obj = dump.getDumpedAhatInstance("gcPathArray"); 368 assertNull(obj.asBitmap()); 369 } 370 371 @Test 372 public void classObjNotABitmap() throws IOException { 373 TestDump dump = TestDump.getTestDump(); 374 AhatInstance obj = dump.findClass("Main"); 375 assertNull(obj.asBitmap()); 376 } 377 378 @Test 379 public void classInstanceToString() throws IOException { 380 TestDump dump = TestDump.getTestDump(); 381 AhatInstance obj = dump.getDumpedAhatInstance("aPhantomReference"); 382 long id = obj.getId(); 383 assertEquals(String.format("java.lang.ref.PhantomReference@%08x", id), obj.toString()); 384 } 385 386 @Test 387 public void classObjToString() throws IOException { 388 TestDump dump = TestDump.getTestDump(); 389 AhatInstance obj = dump.findClass("Main"); 390 assertEquals("class Main", obj.toString()); 391 } 392 393 @Test 394 public void arrayInstanceToString() throws IOException { 395 TestDump dump = TestDump.getTestDump(); 396 AhatInstance obj = dump.getDumpedAhatInstance("gcPathArray"); 397 long id = obj.getId(); 398 399 // There's a bug in perfib's proguard deobfuscation for arrays. 400 // To work around that bug for the time being, only test the suffix of 401 // the toString result. Ideally we test for string equality against 402 // "Main$ObjectTree[4]@%08x", id. 403 assertTrue(obj.toString().endsWith(String.format("[4]@%08x", id))); 404 } 405 406 @Test 407 public void primArrayInstanceToString() throws IOException { 408 TestDump dump = TestDump.getTestDump(); 409 AhatInstance obj = dump.getDumpedAhatInstance("bigArray"); 410 long id = obj.getId(); 411 assertEquals(String.format("byte[1000000]@%08x", id), obj.toString()); 412 } 413 414 @Test 415 public void isRoot() throws IOException { 416 // We expect the Main class to be a root. 417 TestDump dump = TestDump.getTestDump(); 418 AhatInstance main = dump.findClass("Main"); 419 assertTrue(main.isRoot()); 420 assertNull(main.getImmediateDominator()); 421 } 422 423 @Test 424 public void isNotRoot() throws IOException { 425 TestDump dump = TestDump.getTestDump(); 426 AhatInstance obj = dump.getDumpedAhatInstance("anObject"); 427 assertFalse(obj.isRoot()); 428 assertNull(obj.getRootTypes()); 429 } 430 431 @Test 432 public void weakRefToGcRoot() throws IOException { 433 TestDump dump = TestDump.getTestDump(); 434 AhatInstance ref = dump.getDumpedAhatInstance("aWeakRefToGcRoot"); 435 436 // The weak reference points to Main.class, which we expect will be marked 437 // as a GC root. In theory Main.class doesn't have to be a GC root, in 438 // which case this test case will need to be revised. 439 AhatInstance root = ref.getField("referent").asAhatInstance(); 440 assertTrue(root.isRoot()); 441 442 // We had a bug in the past where weak references to GC roots caused the 443 // roots to be incorrectly be considered weakly reachable. 444 assertEquals(Reachability.STRONG, root.getReachability()); 445 assertTrue(root.isStronglyReachable()); 446 assertFalse(root.isWeaklyReachable()); 447 } 448 449 @Test 450 public void softReferenceChain() throws IOException { 451 // If the only reference to a chain of strongly referenced objects is a 452 // soft reference, then all of the objects should be considered softly 453 // reachable. 454 TestDump dump = TestDump.getTestDump(); 455 AhatInstance ref = dump.getDumpedAhatInstance("aSoftChain"); 456 AhatInstance soft1 = ref.getField("referent").asAhatInstance(); 457 AhatInstance soft2 = soft1.getField("referent").asAhatInstance(); 458 AhatInstance soft3 = soft2.getField("referent").asAhatInstance(); 459 assertTrue(ref.isStronglyReachable()); 460 assertEquals(Reachability.SOFT, soft1.getReachability()); 461 assertEquals(Reachability.SOFT, soft2.getReachability()); 462 assertEquals(Reachability.SOFT, soft3.getReachability()); 463 464 // Test the deprecated isWeaklyReachable API, which interprets weak as any 465 // kind of phantom/finalizer/weak/soft reference. 466 assertTrue(soft1.isWeaklyReachable()); 467 assertTrue(soft2.isWeaklyReachable()); 468 assertTrue(soft3.isWeaklyReachable()); 469 } 470 471 @Test 472 public void reverseReferences() throws IOException { 473 TestDump dump = TestDump.getTestDump(); 474 AhatInstance obj = dump.getDumpedAhatInstance("anObject"); 475 AhatInstance ref = dump.getDumpedAhatInstance("aReference"); 476 AhatInstance weak = dump.getDumpedAhatInstance("aWeakReference"); 477 assertTrue(obj.getReverseReferences().contains(ref)); 478 assertTrue(obj.getReverseReferences().contains(weak)); 479 assertTrue(obj.getHardReverseReferences().contains(ref)); 480 assertFalse(obj.getHardReverseReferences().contains(weak)); 481 assertFalse(obj.getSoftReverseReferences().contains(ref)); 482 assertTrue(obj.getSoftReverseReferences().contains(weak)); 483 } 484 485 @Test 486 public void asStringEmbedded() throws IOException { 487 // On Android L, image strings were backed by a single big char array. 488 // Verify we show just the relative part of the string, not the entire 489 // char array. 490 TestDump dump = TestDump.getTestDump("L.hprof", null, null, Reachability.STRONG); 491 AhatSnapshot snapshot = dump.getAhatSnapshot(); 492 493 // java.lang.String@0x6fe17050 is an image string "char" backed by a 494 // shared char array. 495 AhatInstance str = snapshot.findInstance(0x6fe17050); 496 assertEquals("char", str.asString()); 497 } 498 499 @Test 500 public void nonDefaultHeapRoot() throws IOException { 501 TestDump dump = TestDump.getTestDump("O.hprof", null, null, Reachability.STRONG); 502 AhatSnapshot snapshot = dump.getAhatSnapshot(); 503 504 // java.util.HashMap@6004fdb8 is marked as a VM INTERNAL root. 505 // Previously we had a bug where roots not on the default heap were not 506 // properly treated as roots (b/65356532). 507 AhatInstance map = snapshot.findInstance(0x6004fdb8); 508 assertEquals("java.util.HashMap", map.getClassName()); 509 assertTrue(map.isRoot()); 510 } 511 512 @Test 513 public void threadRoot() throws IOException { 514 TestDump dump = TestDump.getTestDump("O.hprof", null, null, Reachability.STRONG); 515 AhatSnapshot snapshot = dump.getAhatSnapshot(); 516 517 // java.lang.Thread@12c03470 is marked as a thread root. 518 // Previously we had a bug where thread roots were not properly treated as 519 // roots (b/65356532). 520 AhatInstance thread = snapshot.findInstance(0x12c03470); 521 assertEquals("java.lang.Thread", thread.getClassName()); 522 assertTrue(thread.isRoot()); 523 } 524 525 @Test 526 public void classOfClass() throws IOException { 527 TestDump dump = TestDump.getTestDump(); 528 AhatInstance obj = dump.getDumpedAhatInstance("anObject"); 529 AhatClassObj cls = obj.getClassObj(); 530 AhatClassObj clscls = cls.getClassObj(); 531 assertNotNull(clscls); 532 assertEquals("java.lang.Class", clscls.getName()); 533 } 534 535 @Test 536 public void nullValueString() throws IOException { 537 TestDump dump = TestDump.getTestDump("RI.hprof", null, null, Reachability.STRONG); 538 AhatSnapshot snapshot = dump.getAhatSnapshot(); 539 540 // java.lang.String@500001a8 has a null 'value' field, which should not 541 // cause ahat to crash. 542 AhatInstance str = snapshot.findInstance(0x500001a8); 543 assertEquals("java.lang.String", str.getClassName()); 544 assertNull(str.asString()); 545 } 546 547 @Test 548 public void classOverhead() throws IOException { 549 TestDump dump = TestDump.getTestDump("O.hprof", null, null, Reachability.STRONG); 550 AhatSnapshot snapshot = dump.getAhatSnapshot(); 551 552 // class libore.io.IoTracker has byte[124]@12c028d1 as its class overhead. 553 AhatInstance overhead = snapshot.findInstance(0x12c028d1); 554 AhatClassObj cls = overhead.getAssociatedClassForOverhead(); 555 assertEquals(0x12c028d0, cls.getId()); 556 assertEquals("libcore.io.IoTracker", cls.getName()); 557 558 // Other kinds of objects should not have associated classes for overhead. 559 assertNull(cls.getAssociatedClassForOverhead()); 560 } 561 562 @Test 563 public void binderProxy() throws IOException { 564 TestDump dump = TestDump.getTestDump(); 565 566 AhatInstance correctObj = dump.getDumpedAhatInstance("correctBinderProxy"); 567 assertEquals("DumpedStuff$IDumpedManager", correctObj.getBinderProxyInterfaceName()); 568 569 AhatInstance imposedObj = dump.getDumpedAhatInstance("imposedBinderProxy"); 570 assertNull(imposedObj.getBinderProxyInterfaceName()); 571 572 AhatInstance carriedObj = dump.getDumpedAhatInstance("carriedBinderProxy"); 573 assertNull(carriedObj.getBinderProxyInterfaceName()); 574 } 575 576 @Test 577 public void binderToken() throws IOException { 578 TestDump dump = TestDump.getTestDump(); 579 580 // Tokens without a descriptor return an empty string 581 AhatInstance binderToken = dump.getDumpedAhatInstance("binderToken"); 582 assertEquals("", binderToken.getBinderTokenDescriptor()); 583 584 // Named binder tokens return their descriptor 585 AhatInstance namedBinderToken = dump.getDumpedAhatInstance("namedBinderToken"); 586 assertEquals("awesomeToken", namedBinderToken.getBinderTokenDescriptor()); 587 588 // Binder stubs aren't considered binder tokens 589 AhatInstance binderService = dump.getDumpedAhatInstance("binderService"); 590 assertEquals(null, binderService.getBinderTokenDescriptor()); 591 } 592 593 @Test 594 public void binderStub() throws IOException { 595 TestDump dump = TestDump.getTestDump(); 596 597 // Regular binder service returns the interface name and no token descriptor 598 AhatInstance binderService = dump.getDumpedAhatInstance("binderService"); 599 assertEquals("DumpedStuff$IDumpedManager", binderService.getBinderStubInterfaceName()); 600 601 // Binder tokens aren't considered binder services 602 AhatInstance binderToken = dump.getDumpedAhatInstance("binderToken"); 603 assertEquals(null, binderToken.getBinderStubInterfaceName()); 604 605 // Named binder tokens aren't considered binder services 606 AhatInstance namedBinderToken = dump.getDumpedAhatInstance("namedBinderToken"); 607 assertEquals(null, namedBinderToken.getBinderStubInterfaceName()); 608 609 // Fake service returns null 610 AhatInstance fakeService = dump.getDumpedAhatInstance("fakeBinderService"); 611 assertNull(fakeService.getBinderStubInterfaceName()); 612 613 // Random non-binder object returns null 614 AhatInstance nonBinderObject = dump.getDumpedAhatInstance("anObject"); 615 assertNull(nonBinderObject.getBinderStubInterfaceName()); 616 } 617 } 618