| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "mojo/embedder/platform_channel_pair.h" | 5 #include "mojo/embedder/platform_channel_pair.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <poll.h> | 8 #include <poll.h> |
| 9 #include <signal.h> | 9 #include <signal.h> |
| 10 #include <stdio.h> | 10 #include <stdio.h> |
| 11 #include <sys/socket.h> | 11 #include <sys/socket.h> |
| 12 #include <sys/types.h> | 12 #include <sys/types.h> |
| 13 #include <sys/uio.h> | 13 #include <sys/uio.h> |
| 14 #include <unistd.h> | 14 #include <unistd.h> |
| 15 | 15 |
| 16 #include <vector> | 16 #include <vector> |
| 17 | 17 |
| 18 #include "base/file_util.h" | 18 #include "base/file_util.h" |
| 19 #include "base/files/file_path.h" | 19 #include "base/files/file_path.h" |
| 20 #include "base/files/scoped_file.h" |
| 20 #include "base/logging.h" | 21 #include "base/logging.h" |
| 21 #include "base/macros.h" | 22 #include "base/macros.h" |
| 23 #include "mojo/common/test/test_utils.h" |
| 22 #include "mojo/embedder/platform_channel_utils_posix.h" | 24 #include "mojo/embedder/platform_channel_utils_posix.h" |
| 23 #include "mojo/embedder/scoped_platform_handle.h" | 25 #include "mojo/embedder/scoped_platform_handle.h" |
| 24 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
| 25 | 27 |
| 26 namespace mojo { | 28 namespace mojo { |
| 27 namespace embedder { | 29 namespace embedder { |
| 28 namespace { | 30 namespace { |
| 29 | 31 |
| 30 ScopedPlatformHandle PlatformHandleFromFILE(FILE* fp) { | |
| 31 CHECK(fp); | |
| 32 return ScopedPlatformHandle(PlatformHandle(dup(fileno(fp)))); | |
| 33 } | |
| 34 | |
| 35 FILE* FILEFromPlatformHandle(ScopedPlatformHandle h, const char* mode) { | |
| 36 CHECK(h.is_valid()); | |
| 37 return fdopen(h.release().fd, mode); | |
| 38 } | |
| 39 | |
| 40 void WaitReadable(PlatformHandle h) { | 32 void WaitReadable(PlatformHandle h) { |
| 41 struct pollfd pfds = {}; | 33 struct pollfd pfds = {}; |
| 42 pfds.fd = h.fd; | 34 pfds.fd = h.fd; |
| 43 pfds.events = POLLIN; | 35 pfds.events = POLLIN; |
| 44 CHECK_EQ(poll(&pfds, 1, -1), 1); | 36 CHECK_EQ(poll(&pfds, 1, -1), 1); |
| 45 } | 37 } |
| 46 | 38 |
| 47 class PlatformChannelPairPosixTest : public testing::Test { | 39 class PlatformChannelPairPosixTest : public testing::Test { |
| 48 public: | 40 public: |
| 49 PlatformChannelPairPosixTest() {} | 41 PlatformChannelPairPosixTest() {} |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 TEST_F(PlatformChannelPairPosixTest, SendReceiveFDs) { | 129 TEST_F(PlatformChannelPairPosixTest, SendReceiveFDs) { |
| 138 PlatformChannelPair channel_pair; | 130 PlatformChannelPair channel_pair; |
| 139 ScopedPlatformHandle server_handle = channel_pair.PassServerHandle().Pass(); | 131 ScopedPlatformHandle server_handle = channel_pair.PassServerHandle().Pass(); |
| 140 ScopedPlatformHandle client_handle = channel_pair.PassClientHandle().Pass(); | 132 ScopedPlatformHandle client_handle = channel_pair.PassClientHandle().Pass(); |
| 141 | 133 |
| 142 for (size_t i = 1; i < kPlatformChannelMaxNumHandles; i++) { | 134 for (size_t i = 1; i < kPlatformChannelMaxNumHandles; i++) { |
| 143 // Make |i| files, with the j-th file consisting of j copies of the digit i. | 135 // Make |i| files, with the j-th file consisting of j copies of the digit i. |
| 144 PlatformHandleVector platform_handles; | 136 PlatformHandleVector platform_handles; |
| 145 for (size_t j = 1; j <= i; j++) { | 137 for (size_t j = 1; j <= i; j++) { |
| 146 base::FilePath ignored; | 138 base::FilePath ignored; |
| 147 FILE* fp = base::CreateAndOpenTemporaryFile(&ignored); | 139 base::ScopedFILE fp(base::CreateAndOpenTemporaryFile(&ignored)); |
| 148 ASSERT_TRUE(fp); | 140 ASSERT_TRUE(fp); |
| 149 platform_handles.push_back(PlatformHandleFromFILE(fp).release()); | 141 fwrite(std::string(j, '0' + i).data(), 1, j, fp.get()); |
| 142 platform_handles.push_back( |
| 143 test::PlatformHandleFromFILE(fp.Pass()).release()); |
| 150 ASSERT_TRUE(platform_handles.back().is_valid()); | 144 ASSERT_TRUE(platform_handles.back().is_valid()); |
| 151 fwrite(std::string(j, '0' + i).data(), 1, j, fp); | |
| 152 fclose(fp); | |
| 153 } | 145 } |
| 154 | 146 |
| 155 // Send the FDs. | 147 // Send the FDs. |
| 156 EXPECT_TRUE(PlatformChannelSendHandles(server_handle.get(), | 148 EXPECT_TRUE(PlatformChannelSendHandles(server_handle.get(), |
| 157 &platform_handles[0], | 149 &platform_handles[0], |
| 158 platform_handles.size())); | 150 platform_handles.size())); |
| 159 | 151 |
| 160 WaitReadable(client_handle.get()); | 152 WaitReadable(client_handle.get()); |
| 161 | 153 |
| 162 char buf[100] = { 'a' }; | 154 char buf[100] = { 'a' }; |
| 163 scoped_ptr<PlatformHandleVector> received_handles; | 155 scoped_ptr<PlatformHandleVector> received_handles; |
| 164 EXPECT_EQ(1, PlatformChannelRecvmsg(client_handle.get(), buf, sizeof(buf), | 156 EXPECT_EQ(1, PlatformChannelRecvmsg(client_handle.get(), buf, sizeof(buf), |
| 165 &received_handles)); | 157 &received_handles)); |
| 166 EXPECT_EQ('\0', buf[0]); | 158 EXPECT_EQ('\0', buf[0]); |
| 167 ASSERT_TRUE(received_handles); | 159 ASSERT_TRUE(received_handles); |
| 168 EXPECT_EQ(i, received_handles->size()); | 160 EXPECT_EQ(i, received_handles->size()); |
| 169 | 161 |
| 170 for (size_t j = 0; j < received_handles->size(); j++) { | 162 for (size_t j = 0; j < received_handles->size(); j++) { |
| 171 FILE* fp = FILEFromPlatformHandle( | 163 base::ScopedFILE fp(test::FILEFromPlatformHandle( |
| 172 ScopedPlatformHandle((*received_handles)[j]), "rb"); | 164 ScopedPlatformHandle((*received_handles)[j]), "rb")); |
| 173 (*received_handles)[j] = PlatformHandle(); | 165 (*received_handles)[j] = PlatformHandle(); |
| 174 ASSERT_TRUE(fp); | 166 ASSERT_TRUE(fp); |
| 175 rewind(fp); | 167 rewind(fp.get()); |
| 176 char read_buf[100]; | 168 char read_buf[100]; |
| 177 size_t bytes_read = fread(read_buf, 1, sizeof(read_buf), fp); | 169 size_t bytes_read = fread(read_buf, 1, sizeof(read_buf), fp.get()); |
| 178 fclose(fp); | |
| 179 EXPECT_EQ(j + 1, bytes_read); | 170 EXPECT_EQ(j + 1, bytes_read); |
| 180 EXPECT_EQ(std::string(j + 1, '0' + i), std::string(read_buf, bytes_read)); | 171 EXPECT_EQ(std::string(j + 1, '0' + i), std::string(read_buf, bytes_read)); |
| 181 } | 172 } |
| 182 } | 173 } |
| 183 } | 174 } |
| 184 | 175 |
| 185 TEST_F(PlatformChannelPairPosixTest, AppendReceivedFDs) { | 176 TEST_F(PlatformChannelPairPosixTest, AppendReceivedFDs) { |
| 186 PlatformChannelPair channel_pair; | 177 PlatformChannelPair channel_pair; |
| 187 ScopedPlatformHandle server_handle = channel_pair.PassServerHandle().Pass(); | 178 ScopedPlatformHandle server_handle = channel_pair.PassServerHandle().Pass(); |
| 188 ScopedPlatformHandle client_handle = channel_pair.PassClientHandle().Pass(); | 179 ScopedPlatformHandle client_handle = channel_pair.PassClientHandle().Pass(); |
| 189 | 180 |
| 190 const std::string file_contents("hello world"); | 181 const std::string file_contents("hello world"); |
| 191 | 182 |
| 192 { | 183 { |
| 193 base::FilePath ignored; | 184 base::FilePath ignored; |
| 194 FILE* fp = base::CreateAndOpenTemporaryFile(&ignored); | 185 base::ScopedFILE fp(base::CreateAndOpenTemporaryFile(&ignored)); |
| 195 ASSERT_TRUE(fp); | 186 ASSERT_TRUE(fp); |
| 187 fwrite(file_contents.data(), 1, file_contents.size(), fp.get()); |
| 196 PlatformHandleVector platform_handles; | 188 PlatformHandleVector platform_handles; |
| 197 platform_handles.push_back(PlatformHandleFromFILE(fp).release()); | 189 platform_handles.push_back( |
| 190 test::PlatformHandleFromFILE(fp.Pass()).release()); |
| 198 ASSERT_TRUE(platform_handles.back().is_valid()); | 191 ASSERT_TRUE(platform_handles.back().is_valid()); |
| 199 fwrite(file_contents.data(), 1, file_contents.size(), fp); | |
| 200 fclose(fp); | |
| 201 | 192 |
| 202 // Send the FD. | 193 // Send the FD. |
| 203 EXPECT_TRUE(PlatformChannelSendHandles(server_handle.get(), | 194 EXPECT_TRUE(PlatformChannelSendHandles(server_handle.get(), |
| 204 &platform_handles[0], | 195 &platform_handles[0], |
| 205 platform_handles.size())); | 196 platform_handles.size())); |
| 206 } | 197 } |
| 207 | 198 |
| 208 WaitReadable(client_handle.get()); | 199 WaitReadable(client_handle.get()); |
| 209 | 200 |
| 210 // Start with an invalid handle in the vector. | 201 // Start with an invalid handle in the vector. |
| 211 scoped_ptr<PlatformHandleVector> handles(new PlatformHandleVector()); | 202 scoped_ptr<PlatformHandleVector> handles(new PlatformHandleVector()); |
| 212 handles->push_back(PlatformHandle()); | 203 handles->push_back(PlatformHandle()); |
| 213 | 204 |
| 214 char buf[100] = { 'a' }; | 205 char buf[100] = { 'a' }; |
| 215 EXPECT_EQ(1, PlatformChannelRecvmsg(client_handle.get(), buf, sizeof(buf), | 206 EXPECT_EQ(1, PlatformChannelRecvmsg(client_handle.get(), buf, sizeof(buf), |
| 216 &handles)); | 207 &handles)); |
| 217 EXPECT_EQ('\0', buf[0]); | 208 EXPECT_EQ('\0', buf[0]); |
| 218 ASSERT_TRUE(handles); | 209 ASSERT_TRUE(handles); |
| 219 ASSERT_EQ(2u, handles->size()); | 210 ASSERT_EQ(2u, handles->size()); |
| 220 EXPECT_FALSE((*handles)[0].is_valid()); | 211 EXPECT_FALSE((*handles)[0].is_valid()); |
| 221 EXPECT_TRUE((*handles)[1].is_valid()); | 212 EXPECT_TRUE((*handles)[1].is_valid()); |
| 222 | 213 |
| 223 { | 214 { |
| 224 FILE* fp = FILEFromPlatformHandle(ScopedPlatformHandle((*handles)[1]), | 215 base::ScopedFILE fp(test::FILEFromPlatformHandle( |
| 225 "rb"); | 216 ScopedPlatformHandle((*handles)[1]), "rb")); |
| 226 (*handles)[1] = PlatformHandle(); | 217 (*handles)[1] = PlatformHandle(); |
| 227 ASSERT_TRUE(fp); | 218 ASSERT_TRUE(fp); |
| 228 rewind(fp); | 219 rewind(fp.get()); |
| 229 char read_buf[100]; | 220 char read_buf[100]; |
| 230 size_t bytes_read = fread(read_buf, 1, sizeof(read_buf), fp); | 221 size_t bytes_read = fread(read_buf, 1, sizeof(read_buf), fp.get()); |
| 231 fclose(fp); | |
| 232 EXPECT_EQ(file_contents.size(), bytes_read); | 222 EXPECT_EQ(file_contents.size(), bytes_read); |
| 233 EXPECT_EQ(file_contents, std::string(read_buf, bytes_read)); | 223 EXPECT_EQ(file_contents, std::string(read_buf, bytes_read)); |
| 234 } | 224 } |
| 235 } | 225 } |
| 236 | 226 |
| 237 } // namespace | 227 } // namespace |
| 238 } // namespace embedder | 228 } // namespace embedder |
| 239 } // namespace mojo | 229 } // namespace mojo |
| OLD | NEW |