2 * Copyright 2015 Facebook, Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #include <folly/wangle/channel/FileRegion.h>
17 #include <folly/io/async/test/AsyncSocketTest.h>
18 #include <gtest/gtest.h>
20 using namespace folly;
21 using namespace folly::wangle;
22 using namespace testing;
24 struct FileRegionTest : public Test {
27 socket = AsyncSocket::newSocket(&evb);
28 socket->connect(&ccb, server.getAddress(), 30);
30 // Accept the connection
31 acceptedSocket = server.acceptAsync(&evb);
32 acceptedSocket->setReadCB(&rcb);
35 char path[] = "/tmp/AsyncSocketTest.WriteFile.XXXXXX";
36 fd = mkostemp(path, O_RDWR);
38 EXPECT_EQ(0, unlink(path));
41 ~FileRegionTest() override {
44 acceptedSocket->close();
50 std::shared_ptr<AsyncSocket> socket;
51 std::shared_ptr<AsyncSocket> acceptedSocket;
57 TEST_F(FileRegionTest, Basic) {
58 size_t count = 1000000000; // 1 GB
59 void* zeroBuf = calloc(1, count);
60 write(fd, zeroBuf, count);
62 FileRegion fileRegion(fd, 0, count);
63 auto f = fileRegion.transferTo(socket);
66 } catch (std::exception& e) {
67 LOG(FATAL) << exceptionStr(e);
70 // Let the reads run to completion
71 socket->shutdownWrite();
74 ASSERT_EQ(rcb.state, STATE_SUCCEEDED);
76 size_t receivedBytes = 0;
77 for (auto& buf : rcb.buffers) {
78 receivedBytes += buf.length;
79 ASSERT_EQ(memcmp(buf.buffer, zeroBuf, buf.length), 0);
81 ASSERT_EQ(receivedBytes, count);
84 TEST_F(FileRegionTest, Repeated) {
85 size_t count = 1000000;
86 void* zeroBuf = calloc(1, count);
87 write(fd, zeroBuf, count);
91 FileRegion fileRegion(fd, 0, count);
92 std::vector<Future<void>> fs;
93 for (int i = 0; i < sendCount; i++) {
94 fs.push_back(fileRegion.transferTo(socket));
97 ASSERT_NO_THROW(f.getVia(&evb));
99 // Let the reads run to completion
100 socket->shutdownWrite();
103 ASSERT_EQ(rcb.state, STATE_SUCCEEDED);
105 size_t receivedBytes = 0;
106 for (auto& buf : rcb.buffers) {
107 receivedBytes += buf.length;
109 ASSERT_EQ(receivedBytes, sendCount*count);