Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(876)

Side by Side Diff: chrome/browser/ui/cocoa/objc_zombie_unittest.mm

Issue 7826016: [Mac] Enable CrZombie for all processes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Whitespace, and verify merge. Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/ui/cocoa/objc_zombie.mm ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #import <Cocoa/Cocoa.h>
6 #include <dlfcn.h>
7
8 #include "base/logging.h"
9 #import "base/memory/scoped_nsobject.h"
10 #import "chrome/browser/ui/cocoa/objc_zombie.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "testing/platform_test.h"
13
14 namespace {
15
16 // Dynamically look up |objc_setAssociatedObject()|, which isn't
17 // available until the 10.6 SDK.
18
19 typedef void objc_setAssociatedObjectFn(id object, void *key, id value,
20 int policy);
21 objc_setAssociatedObjectFn* LookupSetAssociatedObjectFn() {
22 return reinterpret_cast<objc_setAssociatedObjectFn*>(
23 dlsym(RTLD_DEFAULT, "objc_setAssociatedObject"));
24 }
25
26 } // namespace
27
28 @interface ZombieCxxDestructTest : NSObject
29 {
30 scoped_nsobject<id> aRef_;
31 }
32 - (id)initWith:(id)anObject;
33 @end
34
35 @implementation ZombieCxxDestructTest
36 - (id)initWith:(id)anObject {
37 self = [super init];
38 if (self) {
39 aRef_.reset([anObject retain]);
40 }
41 return self;
42 }
43 @end
44
45 @interface ZombieAssociatedObjectTest : NSObject
46 + (BOOL)supportsAssociatedObjects;
47 - (id)initWithAssociatedObject:(id)anObject;
48 @end
49
50 @implementation ZombieAssociatedObjectTest
51
52 + (BOOL)supportsAssociatedObjects {
53 if (LookupSetAssociatedObjectFn())
54 return YES;
55 return NO;
56 }
57
58 - (id)initWithAssociatedObject:(id)anObject {
59 self = [super init];
60 if (self) {
61 objc_setAssociatedObjectFn* fn = LookupSetAssociatedObjectFn();
62 if (fn) {
63 // Cribbed from 10.6 <objc/runtime.h>.
64 static const int kObjcAssociationRetain = 01401;
65
66 // The address of the variable itself is the unique key, the
67 // contents don't matter.
68 static char kAssociatedObjectKey = 'x';
69
70 (*fn)(self, &kAssociatedObjectKey, anObject, kObjcAssociationRetain);
71 }
72 }
73 return self;
74 }
75
76 @end
77
78 namespace {
79
80 // Verify that the C++ destructors run when the last reference to the
81 // object is released.
82 // NOTE(shess): To test the negative, comment out the |g_objectDestruct()|
83 // call in |ZombieDealloc()|.
84 TEST(ObjcZombieTest, CxxDestructors) {
85 scoped_nsobject<id> anObject([[NSObject alloc] init]);
86 EXPECT_EQ(1u, [anObject retainCount]);
87
88 ASSERT_TRUE(ObjcEvilDoers::ZombieEnable(YES, 100));
89
90 scoped_nsobject<ZombieCxxDestructTest> soonInfected(
91 [[ZombieCxxDestructTest alloc] initWith:anObject]);
92 EXPECT_EQ(2u, [anObject retainCount]);
93
94 // When |soonInfected| becomes a zombie, the C++ destructors should
95 // run and release a reference to |anObject|.
96 soonInfected.reset();
97 EXPECT_EQ(1u, [anObject retainCount]);
98
99 // The local reference should remain (C++ destructors aren't re-run).
100 ObjcEvilDoers::ZombieDisable();
101 EXPECT_EQ(1u, [anObject retainCount]);
102 }
103
104 // Verify that the associated objects are released when the object is
105 // released.
106 // NOTE(shess): To test the negative, hardcode |g_objectDestruct| to
107 // the 10.5 version in |ZombieInit()|, and run this test on 10.6.
108 TEST(ObjcZombieTest, AssociatedObjectsReleased) {
109 if (![ZombieAssociatedObjectTest supportsAssociatedObjects]) {
110 LOG(ERROR)
111 << "ObjcZombieTest.AssociatedObjectsReleased not supported on 10.5";
112 return;
113 }
114
115 scoped_nsobject<id> anObject([[NSObject alloc] init]);
116 EXPECT_EQ(1u, [anObject retainCount]);
117
118 ASSERT_TRUE(ObjcEvilDoers::ZombieEnable(YES, 100));
119
120 scoped_nsobject<ZombieAssociatedObjectTest> soonInfected(
121 [[ZombieAssociatedObjectTest alloc] initWithAssociatedObject:anObject]);
122 EXPECT_EQ(2u, [anObject retainCount]);
123
124 // When |soonInfected| becomes a zombie, the associated object
125 // should be released.
126 soonInfected.reset();
127 EXPECT_EQ(1u, [anObject retainCount]);
128
129 // The local reference should remain (associated objects not re-released).
130 ObjcEvilDoers::ZombieDisable();
131 EXPECT_EQ(1u, [anObject retainCount]);
132 }
133
134 } // namespace
OLDNEW
« no previous file with comments | « chrome/browser/ui/cocoa/objc_zombie.mm ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698