Add GL version support in gpu blacklist and workaround list.
[chromium-blink-merge.git] / mojo / embedder / platform_channel_pair_posix_unittest.cc
blob17fb3bc8e1be48aa6117bb23514214b1b69f633b
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
3 // found in the LICENSE file.
5 #include "mojo/embedder/platform_channel_pair.h"
7 #include <errno.h>
8 #include <poll.h>
9 #include <signal.h>
10 #include <stdio.h>
11 #include <sys/socket.h>
12 #include <sys/types.h>
13 #include <sys/uio.h>
14 #include <unistd.h>
16 #include <vector>
18 #include "base/file_util.h"
19 #include "base/files/file_path.h"
20 #include "base/logging.h"
21 #include "base/macros.h"
22 #include "mojo/embedder/platform_channel_utils_posix.h"
23 #include "mojo/embedder/scoped_platform_handle.h"
24 #include "testing/gtest/include/gtest/gtest.h"
26 namespace mojo {
27 namespace embedder {
28 namespace {
30 ScopedPlatformHandle PlatformHandleFromFILE(FILE* fp) {
31 CHECK(fp);
32 return ScopedPlatformHandle(PlatformHandle(dup(fileno(fp))));
35 FILE* FILEFromPlatformHandle(ScopedPlatformHandle h, const char* mode) {
36 CHECK(h.is_valid());
37 return fdopen(h.release().fd, mode);
40 void WaitReadable(PlatformHandle h) {
41 struct pollfd pfds = {};
42 pfds.fd = h.fd;
43 pfds.events = POLLIN;
44 CHECK_EQ(poll(&pfds, 1, -1), 1);
47 class PlatformChannelPairPosixTest : public testing::Test {
48 public:
49 PlatformChannelPairPosixTest() {}
50 virtual ~PlatformChannelPairPosixTest() {}
52 virtual void SetUp() OVERRIDE {
53 // Make sure |SIGPIPE| isn't being ignored.
54 struct sigaction action = {};
55 action.sa_handler = SIG_DFL;
56 ASSERT_EQ(0, sigaction(SIGPIPE, &action, &old_action_));
59 virtual void TearDown() OVERRIDE {
60 // Restore the |SIGPIPE| handler.
61 ASSERT_EQ(0, sigaction(SIGPIPE, &old_action_, NULL));
64 private:
65 struct sigaction old_action_;
67 DISALLOW_COPY_AND_ASSIGN(PlatformChannelPairPosixTest);
70 TEST_F(PlatformChannelPairPosixTest, NoSigPipe) {
71 PlatformChannelPair channel_pair;
72 ScopedPlatformHandle server_handle = channel_pair.PassServerHandle().Pass();
73 ScopedPlatformHandle client_handle = channel_pair.PassClientHandle().Pass();
75 // Write to the client.
76 static const char kHello[] = "hello";
77 EXPECT_EQ(static_cast<ssize_t>(sizeof(kHello)),
78 write(client_handle.get().fd, kHello, sizeof(kHello)));
80 // Close the client.
81 client_handle.reset();
83 // Read from the server; this should be okay.
84 char buffer[100] = {};
85 EXPECT_EQ(static_cast<ssize_t>(sizeof(kHello)),
86 read(server_handle.get().fd, buffer, sizeof(buffer)));
87 EXPECT_STREQ(kHello, buffer);
89 // Try reading again.
90 ssize_t result = read(server_handle.get().fd, buffer, sizeof(buffer));
91 // We should probably get zero (for "end of file"), but -1 would also be okay.
92 EXPECT_TRUE(result == 0 || result == -1);
93 if (result == -1)
94 PLOG(WARNING) << "read (expected 0 for EOF)";
96 // Test our replacement for |write()|/|send()|.
97 result = PlatformChannelWrite(server_handle.get(), kHello, sizeof(kHello));
98 EXPECT_EQ(-1, result);
99 if (errno != EPIPE)
100 PLOG(WARNING) << "write (expected EPIPE)";
102 // Test our replacement for |writev()|/|sendv()|.
103 struct iovec iov[2] = {
104 { const_cast<char*>(kHello), sizeof(kHello) },
105 { const_cast<char*>(kHello), sizeof(kHello) }
107 result = PlatformChannelWritev(server_handle.get(), iov, 2);
108 EXPECT_EQ(-1, result);
109 if (errno != EPIPE)
110 PLOG(WARNING) << "write (expected EPIPE)";
113 TEST_F(PlatformChannelPairPosixTest, SendReceiveData) {
114 PlatformChannelPair channel_pair;
115 ScopedPlatformHandle server_handle = channel_pair.PassServerHandle().Pass();
116 ScopedPlatformHandle client_handle = channel_pair.PassClientHandle().Pass();
118 for (size_t i = 0; i < 10; i++) {
119 std::string send_string(1 << i, 'A' + i);
121 EXPECT_EQ(static_cast<ssize_t>(send_string.size()),
122 PlatformChannelWrite(server_handle.get(), send_string.data(),
123 send_string.size()));
125 WaitReadable(client_handle.get());
127 char buf[10000] = {};
128 scoped_ptr<PlatformHandleVector> received_handles;
129 ssize_t result = PlatformChannelRecvmsg(client_handle.get(), buf,
130 sizeof(buf), &received_handles);
131 EXPECT_EQ(static_cast<ssize_t>(send_string.size()), result);
132 EXPECT_EQ(send_string, std::string(buf, static_cast<size_t>(result)));
133 EXPECT_FALSE(received_handles);
137 TEST_F(PlatformChannelPairPosixTest, SendReceiveFDs) {
138 PlatformChannelPair channel_pair;
139 ScopedPlatformHandle server_handle = channel_pair.PassServerHandle().Pass();
140 ScopedPlatformHandle client_handle = channel_pair.PassClientHandle().Pass();
142 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.
144 PlatformHandleVector platform_handles;
145 for (size_t j = 1; j <= i; j++) {
146 base::FilePath ignored;
147 FILE* fp = base::CreateAndOpenTemporaryFile(&ignored);
148 ASSERT_TRUE(fp);
149 platform_handles.push_back(PlatformHandleFromFILE(fp).release());
150 ASSERT_TRUE(platform_handles.back().is_valid());
151 fwrite(std::string(j, '0' + i).data(), 1, j, fp);
152 fclose(fp);
155 // Send the FDs.
156 EXPECT_TRUE(PlatformChannelSendHandles(server_handle.get(),
157 &platform_handles[0],
158 platform_handles.size()));
160 WaitReadable(client_handle.get());
162 char buf[100] = { 'a' };
163 scoped_ptr<PlatformHandleVector> received_handles;
164 EXPECT_EQ(1, PlatformChannelRecvmsg(client_handle.get(), buf, sizeof(buf),
165 &received_handles));
166 EXPECT_EQ('\0', buf[0]);
167 ASSERT_TRUE(received_handles);
168 EXPECT_EQ(i, received_handles->size());
170 for (size_t j = 0; j < received_handles->size(); j++) {
171 FILE* fp = FILEFromPlatformHandle(
172 ScopedPlatformHandle((*received_handles)[j]), "rb");
173 (*received_handles)[j] = PlatformHandle();
174 ASSERT_TRUE(fp);
175 rewind(fp);
176 char read_buf[100];
177 size_t bytes_read = fread(read_buf, 1, sizeof(read_buf), fp);
178 fclose(fp);
179 EXPECT_EQ(j + 1, bytes_read);
180 EXPECT_EQ(std::string(j + 1, '0' + i), std::string(read_buf, bytes_read));
185 TEST_F(PlatformChannelPairPosixTest, AppendReceivedFDs) {
186 PlatformChannelPair channel_pair;
187 ScopedPlatformHandle server_handle = channel_pair.PassServerHandle().Pass();
188 ScopedPlatformHandle client_handle = channel_pair.PassClientHandle().Pass();
190 const std::string file_contents("hello world");
193 base::FilePath ignored;
194 FILE* fp = base::CreateAndOpenTemporaryFile(&ignored);
195 ASSERT_TRUE(fp);
196 PlatformHandleVector platform_handles;
197 platform_handles.push_back(PlatformHandleFromFILE(fp).release());
198 ASSERT_TRUE(platform_handles.back().is_valid());
199 fwrite(file_contents.data(), 1, file_contents.size(), fp);
200 fclose(fp);
202 // Send the FD.
203 EXPECT_TRUE(PlatformChannelSendHandles(server_handle.get(),
204 &platform_handles[0],
205 platform_handles.size()));
208 WaitReadable(client_handle.get());
210 // Start with an invalid handle in the vector.
211 scoped_ptr<PlatformHandleVector> handles(new PlatformHandleVector());
212 handles->push_back(PlatformHandle());
214 char buf[100] = { 'a' };
215 EXPECT_EQ(1, PlatformChannelRecvmsg(client_handle.get(), buf, sizeof(buf),
216 &handles));
217 EXPECT_EQ('\0', buf[0]);
218 ASSERT_TRUE(handles);
219 ASSERT_EQ(2u, handles->size());
220 EXPECT_FALSE((*handles)[0].is_valid());
221 EXPECT_TRUE((*handles)[1].is_valid());
224 FILE* fp = FILEFromPlatformHandle(ScopedPlatformHandle((*handles)[1]),
225 "rb");
226 (*handles)[1] = PlatformHandle();
227 ASSERT_TRUE(fp);
228 rewind(fp);
229 char read_buf[100];
230 size_t bytes_read = fread(read_buf, 1, sizeof(read_buf), fp);
231 fclose(fp);
232 EXPECT_EQ(file_contents.size(), bytes_read);
233 EXPECT_EQ(file_contents, std::string(read_buf, bytes_read));
237 } // namespace
238 } // namespace embedder
239 } // namespace mojo