OLD | NEW |
| (Empty) |
1 // Copyright 2016 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 // This file tests the C++ wrappers in mojo/public/cpp/system/handle.h. | |
6 | |
7 #include "mojo/public/cpp/system/handle.h" | |
8 | |
9 #include <map> | |
10 #include <utility> | |
11 | |
12 #include "gtest/gtest.h" | |
13 #include "mojo/public/cpp/system/buffer.h" | |
14 #include "mojo/public/cpp/system/macros.h" | |
15 | |
16 namespace mojo { | |
17 namespace { | |
18 | |
19 // Basic |Handle| tests. | |
20 TEST(HandleTest, Handle) { | |
21 EXPECT_EQ(MOJO_HANDLE_INVALID, kInvalidHandleValue); | |
22 | |
23 Handle h0; | |
24 EXPECT_EQ(kInvalidHandleValue, h0.value()); | |
25 EXPECT_EQ(kInvalidHandleValue, *h0.mutable_value()); | |
26 EXPECT_FALSE(h0.is_valid()); | |
27 | |
28 Handle h1(static_cast<MojoHandle>(123)); | |
29 EXPECT_EQ(static_cast<MojoHandle>(123), h1.value()); | |
30 EXPECT_EQ(static_cast<MojoHandle>(123), *h1.mutable_value()); | |
31 EXPECT_TRUE(h1.is_valid()); | |
32 *h1.mutable_value() = static_cast<MojoHandle>(456); | |
33 EXPECT_EQ(static_cast<MojoHandle>(456), h1.value()); | |
34 EXPECT_TRUE(h1.is_valid()); | |
35 | |
36 h1.swap(h0); | |
37 EXPECT_EQ(static_cast<MojoHandle>(456), h0.value()); | |
38 EXPECT_TRUE(h0.is_valid()); | |
39 EXPECT_FALSE(h1.is_valid()); | |
40 | |
41 h1.set_value(static_cast<MojoHandle>(789)); | |
42 h0.swap(h1); | |
43 EXPECT_EQ(static_cast<MojoHandle>(789), h0.value()); | |
44 EXPECT_TRUE(h0.is_valid()); | |
45 EXPECT_EQ(static_cast<MojoHandle>(456), h1.value()); | |
46 EXPECT_TRUE(h1.is_valid()); | |
47 | |
48 // Make sure copy constructor works. | |
49 Handle h2(h0); | |
50 EXPECT_EQ(static_cast<MojoHandle>(789), h2.value()); | |
51 // And assignment. | |
52 h2 = h1; | |
53 EXPECT_EQ(static_cast<MojoHandle>(456), h2.value()); | |
54 | |
55 // Make sure that we can put |Handle|s into |std::map|s. | |
56 h0 = Handle(static_cast<MojoHandle>(987)); | |
57 h1 = Handle(static_cast<MojoHandle>(654)); | |
58 h2 = Handle(static_cast<MojoHandle>(321)); | |
59 Handle h3; | |
60 std::map<Handle, int> handle_to_int; | |
61 handle_to_int[h0] = 0; | |
62 handle_to_int[h1] = 1; | |
63 handle_to_int[h2] = 2; | |
64 handle_to_int[h3] = 3; | |
65 | |
66 EXPECT_EQ(4u, handle_to_int.size()); | |
67 EXPECT_FALSE(handle_to_int.find(h0) == handle_to_int.end()); | |
68 EXPECT_EQ(0, handle_to_int[h0]); | |
69 EXPECT_FALSE(handle_to_int.find(h1) == handle_to_int.end()); | |
70 EXPECT_EQ(1, handle_to_int[h1]); | |
71 EXPECT_FALSE(handle_to_int.find(h2) == handle_to_int.end()); | |
72 EXPECT_EQ(2, handle_to_int[h2]); | |
73 EXPECT_FALSE(handle_to_int.find(h3) == handle_to_int.end()); | |
74 EXPECT_EQ(3, handle_to_int[h3]); | |
75 EXPECT_TRUE(handle_to_int.find(Handle(static_cast<MojoHandle>(13579))) == | |
76 handle_to_int.end()); | |
77 | |
78 // TODO(vtl): With C++11, support |std::unordered_map|s, etc. | |
79 } | |
80 | |
81 // Basic |ScopedHandle| tests. | |
82 TEST(HandleTest, ScopedHandle) { | |
83 // Invalid |ScopedHandle|: | |
84 { | |
85 ScopedHandle sh0; | |
86 | |
87 EXPECT_EQ(kInvalidHandleValue, sh0.get().value()); | |
88 EXPECT_FALSE(sh0.is_valid()); | |
89 | |
90 // This should be a no-op. | |
91 Close(sh0.Pass()); | |
92 | |
93 // It should still be invalid. | |
94 EXPECT_FALSE(sh0.is_valid()); | |
95 | |
96 // Move constructible: | |
97 ScopedHandle sh1(std::move(sh0)); | |
98 EXPECT_FALSE(sh0.is_valid()); | |
99 EXPECT_FALSE(sh1.is_valid()); | |
100 | |
101 // Move assignable: | |
102 sh0 = std::move(sh1); | |
103 EXPECT_FALSE(sh0.is_valid()); | |
104 EXPECT_FALSE(sh1.is_valid()); | |
105 } | |
106 | |
107 // "Valid" |ScopedHandle| (but note that we can't test that it closes the | |
108 // handle on leaving scope without having a valid handle!): | |
109 { | |
110 Handle h0(static_cast<MojoHandle>(123)); | |
111 ScopedHandle sh0(h0); | |
112 | |
113 EXPECT_EQ(h0.value(), sh0.get().value()); | |
114 EXPECT_TRUE(sh0.is_valid()); | |
115 | |
116 // Move constructible: | |
117 ScopedHandle sh1(std::move(sh0)); | |
118 EXPECT_FALSE(sh0.is_valid()); | |
119 EXPECT_TRUE(sh1.is_valid()); | |
120 | |
121 // Move assignable: | |
122 sh0 = std::move(sh1); | |
123 EXPECT_TRUE(sh0.is_valid()); | |
124 EXPECT_FALSE(sh1.is_valid()); | |
125 | |
126 // We have to release |sh0|, since it's not really valid. | |
127 Handle h1 = sh0.release(); | |
128 EXPECT_EQ(h0.value(), h1.value()); | |
129 } | |
130 } | |
131 | |
132 TEST(HandleTest, MakeScopedHandle) { | |
133 EXPECT_FALSE(MakeScopedHandle(Handle()).is_valid()); | |
134 | |
135 Handle h(static_cast<MojoHandle>(123)); | |
136 auto sh = MakeScopedHandle(h); | |
137 EXPECT_TRUE(sh.is_valid()); | |
138 EXPECT_EQ(h.value(), sh.get().value()); | |
139 // Have to release |sh0|, since it's not really valid. | |
140 ignore_result(sh.release()); | |
141 } | |
142 | |
143 TEST(HandleTest, ScopedHandleMoveCtor) { | |
144 // We'll use a shared buffer handle (since we need a valid handle) in a | |
145 // |ScopedSharedBufferHandle|. | |
146 ScopedSharedBufferHandle buffer1; | |
147 EXPECT_EQ(MOJO_RESULT_OK, CreateSharedBuffer(nullptr, 1024, &buffer1)); | |
148 EXPECT_TRUE(buffer1.is_valid()); | |
149 | |
150 ScopedSharedBufferHandle buffer2; | |
151 EXPECT_EQ(MOJO_RESULT_OK, CreateSharedBuffer(nullptr, 1024, &buffer2)); | |
152 EXPECT_TRUE(buffer2.is_valid()); | |
153 | |
154 // If this fails to close buffer1, ScopedHandleBase::CloseIfNecessary() will | |
155 // assert. | |
156 buffer1 = buffer2.Pass(); | |
157 | |
158 EXPECT_TRUE(buffer1.is_valid()); | |
159 EXPECT_FALSE(buffer2.is_valid()); | |
160 } | |
161 | |
162 TEST(HandleTest, ScopedHandleMoveCtorSelf) { | |
163 // We'll use a shared buffer handle (since we need a valid handle) in a | |
164 // |ScopedSharedBufferHandle|. | |
165 ScopedSharedBufferHandle buffer; | |
166 EXPECT_EQ(MOJO_RESULT_OK, CreateSharedBuffer(nullptr, 1024, &buffer)); | |
167 EXPECT_TRUE(buffer.is_valid()); | |
168 | |
169 buffer = buffer.Pass(); | |
170 | |
171 EXPECT_TRUE(buffer.is_valid()); | |
172 } | |
173 | |
174 TEST(HandleTest, RightsReplaceAndDuplicate) { | |
175 static constexpr auto kDuplicate = MOJO_HANDLE_RIGHT_DUPLICATE; | |
176 static constexpr auto kTransfer = MOJO_HANDLE_RIGHT_TRANSFER; | |
177 static constexpr auto kGetOptions = MOJO_HANDLE_RIGHT_GET_OPTIONS; | |
178 | |
179 // We'll use a shared buffer handle (since we need a valid handle that's | |
180 // duplicatable) in a |ScopedSharedBufferHandle|. | |
181 ScopedSharedBufferHandle buffer1; | |
182 EXPECT_EQ(MOJO_RESULT_OK, CreateSharedBuffer(nullptr, 1024, &buffer1)); | |
183 EXPECT_TRUE(buffer1.is_valid()); | |
184 | |
185 EXPECT_EQ(kDuplicate | kTransfer | kGetOptions, | |
186 GetRights(buffer1.get()) & (kDuplicate | kTransfer | kGetOptions)); | |
187 | |
188 MojoHandle old_handle_value = buffer1.get().value(); | |
189 EXPECT_TRUE(ReplaceHandleWithReducedRights(&buffer1, kTransfer)); | |
190 EXPECT_TRUE(buffer1.is_valid()); | |
191 EXPECT_NE(buffer1.get().value(), old_handle_value); | |
192 EXPECT_EQ(kDuplicate | kGetOptions, | |
193 GetRights(buffer1.get()) & (kDuplicate | kTransfer | kGetOptions)); | |
194 | |
195 ScopedSharedBufferHandle buffer2 = | |
196 DuplicateHandleWithReducedRights(buffer1.get(), kGetOptions); | |
197 EXPECT_TRUE(buffer2.is_valid()); | |
198 EXPECT_NE(buffer2.get().value(), buffer1.get().value()); | |
199 EXPECT_EQ(kDuplicate, | |
200 GetRights(buffer2.get()) & (kDuplicate | kTransfer | kGetOptions)); | |
201 EXPECT_EQ(kDuplicate | kGetOptions, | |
202 GetRights(buffer1.get()) & (kDuplicate | kTransfer | kGetOptions)); | |
203 | |
204 ScopedSharedBufferHandle buffer3 = DuplicateHandle(buffer2.get()); | |
205 EXPECT_TRUE(buffer3.is_valid()); | |
206 EXPECT_EQ(kDuplicate, | |
207 GetRights(buffer3.get()) & (kDuplicate | kTransfer | kGetOptions)); | |
208 EXPECT_EQ(kDuplicate, | |
209 GetRights(buffer2.get()) & (kDuplicate | kTransfer | kGetOptions)); | |
210 } | |
211 | |
212 // TODO(vtl): Test |CloseRaw()|. | |
213 // TODO(vtl): Test |reset()| more thoroughly? | |
214 | |
215 } // namespace mojo | |
216 } // namespace | |
OLD | NEW |