10a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin// Copyright (C) 2017 The Android Open Source Project
20a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin//
30a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin// Licensed under the Apache License, Version 2.0 (the "License");
40a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin// you may not use this file except in compliance with the License.
50a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin// You may obtain a copy of the License at
60a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin//
70a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin//      http://www.apache.org/licenses/LICENSE-2.0
80a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin//
90a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin// Unless required by applicable law or agreed to in writing, software
100a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin// distributed under the License is distributed on an "AS IS" BASIS,
110a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin// See the License for the specific language governing permissions and
130a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin// limitations under the License.
144e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin#define DEBUG false
15b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin#include "Log.h"
160a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
170a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin#include "FdBuffer.h"
18b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin#include "incidentd_util.h"
190a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
200a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin#include <android-base/file.h>
210a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin#include <android-base/test_utils.h>
2299c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin#include <fcntl.h>
230a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin#include <gtest/gtest.h>
240a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin#include <signal.h>
250a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin#include <string.h>
260a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
276cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jinusing namespace android;
286cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jinusing namespace android::base;
296cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jinusing namespace android::os::incidentd;
306cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jinusing ::testing::Test;
316cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jin
320a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jinconst int READ_TIMEOUT = 5 * 1000;
330a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jinconst int BUFFER_SIZE = 16 * 1024;
34b44f7d46b647e24d8ea4fdf45742bbcbbfb03113Yi Jinconst int QUICK_TIMEOUT_MS = 100;
350a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jinconst std::string HEAD = "[OK]";
360a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
370a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jinclass FdBufferTest : public Test {
380a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jinpublic:
390a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    virtual void SetUp() override {
400a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        ASSERT_NE(tf.fd, -1);
410a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        ASSERT_NE(p2cPipe.init(), -1);
420a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        ASSERT_NE(c2pPipe.init(), -1);
430a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    }
440a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
450a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    void AssertBufferReadSuccessful(size_t expected) {
460a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        EXPECT_EQ(buffer.size(), expected);
470a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        EXPECT_FALSE(buffer.timedOut());
480a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        EXPECT_FALSE(buffer.truncated());
490a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    }
500a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
510a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    void AssertBufferContent(const char* expected) {
52b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        int i = 0;
53c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        EncodedBuffer::iterator it = buffer.data();
54c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        while (it.hasNext()) {
55c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin            ASSERT_EQ(it.next(), expected[i++]);
5699c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin        }
57c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        EXPECT_EQ(expected[i], '\0');
580a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    }
590a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
60e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin    bool DoDataStream(const unique_fd& rFd, const unique_fd& wFd) {
610a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        char buf[BUFFER_SIZE];
620a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        ssize_t nRead;
63e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin        while ((nRead = read(rFd.get(), buf, BUFFER_SIZE)) > 0) {
640a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            ssize_t nWritten = 0;
650a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            while (nWritten < nRead) {
66e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin                ssize_t amt = write(wFd.get(), buf + nWritten, nRead - nWritten);
670a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                if (amt < 0) {
680a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                    return false;
690a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                }
700a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                nWritten += amt;
710a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            }
720a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        }
730a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        return nRead == 0;
740a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    }
750a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
760a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jinprotected:
770a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    FdBuffer buffer;
780a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    TemporaryFile tf;
790a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    Fpipe p2cPipe;
800a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    Fpipe c2pPipe;
810a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
820a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    const std::string kTestPath = GetExecutableDirectory();
830a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    const std::string kTestDataPath = kTestPath + "/testdata/";
840a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin};
850a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
860a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi JinTEST_F(FdBufferTest, ReadAndWrite) {
870a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    std::string testdata = "FdBuffer test string";
88254102d858942393482589b8f1e6102b33797b58Wei Wang    ASSERT_TRUE(WriteStringToFile(testdata, tf.path));
89e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin    ASSERT_EQ(NO_ERROR, buffer.read(tf.fd, READ_TIMEOUT));
900a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    AssertBufferReadSuccessful(testdata.size());
910a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    AssertBufferContent(testdata.c_str());
920a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin}
930a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
940ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi JinTEST_F(FdBufferTest, IterateEmpty) {
95c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    EncodedBuffer::iterator it = buffer.data();
96c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    EXPECT_FALSE(it.hasNext());
9799c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin}
9899c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin
990ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi JinTEST_F(FdBufferTest, ReadAndIterate) {
1000ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    std::string testdata = "FdBuffer test string";
101254102d858942393482589b8f1e6102b33797b58Wei Wang    ASSERT_TRUE(WriteStringToFile(testdata, tf.path));
102e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin    ASSERT_EQ(NO_ERROR, buffer.read(tf.fd, READ_TIMEOUT));
1030ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin
104b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    int i = 0;
105c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    EncodedBuffer::iterator it = buffer.data();
106c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    while (it.hasNext()) {
107c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        EXPECT_EQ(it.next(), (uint8_t)testdata[i++]);
1080ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    }
1090ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin
110c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    it.rp()->rewind();
111c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    it.rp()->move(buffer.size());
1120ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    EXPECT_EQ(it.bytesRead(), testdata.size());
113c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin    EXPECT_FALSE(it.hasNext());
1140ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin}
1150ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin
1160a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi JinTEST_F(FdBufferTest, ReadTimeout) {
1170a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    int pid = fork();
1180a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    ASSERT_TRUE(pid != -1);
1190a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1200a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    if (pid == 0) {
1216355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        c2pPipe.readFd().reset();
122b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        while (true) {
1230a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            write(c2pPipe.writeFd(), "poo", 3);
1240a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            sleep(1);
1250a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        }
126b44f7d46b647e24d8ea4fdf45742bbcbbfb03113Yi Jin        _exit(EXIT_FAILURE);
1270a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    } else {
1286355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        c2pPipe.writeFd().reset();
1290a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
130e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin        status_t status = buffer.read(c2pPipe.readFd().get(), QUICK_TIMEOUT_MS);
1310a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        ASSERT_EQ(NO_ERROR, status);
1320a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        EXPECT_TRUE(buffer.timedOut());
1330a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
134b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        kill(pid, SIGKILL);  // reap the child process
1350a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    }
1360a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin}
1370a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1380a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi JinTEST_F(FdBufferTest, ReadInStreamAndWrite) {
1390a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    std::string testdata = "simply test read in stream";
1400a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    std::string expected = HEAD + testdata;
141254102d858942393482589b8f1e6102b33797b58Wei Wang    ASSERT_TRUE(WriteStringToFile(testdata, tf.path));
1420a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1430a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    int pid = fork();
1440a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    ASSERT_TRUE(pid != -1);
1450a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1460a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    if (pid == 0) {
1476355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        p2cPipe.writeFd().reset();
1486355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        c2pPipe.readFd().reset();
1490a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        ASSERT_TRUE(WriteStringToFd(HEAD, c2pPipe.writeFd()));
150e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin        ASSERT_TRUE(DoDataStream(p2cPipe.readFd(), c2pPipe.writeFd()));
1516355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        p2cPipe.readFd().reset();
1526355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        c2pPipe.writeFd().reset();
1530a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        // Must exit here otherwise the child process will continue executing the test binary.
154b44f7d46b647e24d8ea4fdf45742bbcbbfb03113Yi Jin        _exit(EXIT_SUCCESS);
1550a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    } else {
1566355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        p2cPipe.readFd().reset();
1576355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        c2pPipe.writeFd().reset();
1580a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
159e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin        ASSERT_EQ(NO_ERROR,
160e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin                  buffer.readProcessedDataInStream(tf.fd, std::move(p2cPipe.writeFd()),
161e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin                                                   std::move(c2pPipe.readFd()), READ_TIMEOUT));
1620a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        AssertBufferReadSuccessful(HEAD.size() + testdata.size());
1630a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        AssertBufferContent(expected.c_str());
1640a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        wait(&pid);
1650a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    }
1660a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin}
1670a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1680a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi JinTEST_F(FdBufferTest, ReadInStreamAndWriteAllAtOnce) {
1690a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    std::string testdata = "child process flushes only after all data are read.";
1700a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    std::string expected = HEAD + testdata;
171254102d858942393482589b8f1e6102b33797b58Wei Wang    ASSERT_TRUE(WriteStringToFile(testdata, tf.path));
1720a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1730a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    int pid = fork();
1740a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    ASSERT_TRUE(pid != -1);
1750a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1760a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    if (pid == 0) {
1776355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        p2cPipe.writeFd().reset();
1786355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        c2pPipe.readFd().reset();
1790a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        std::string data;
1800a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        // wait for read finishes then write.
1810a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        ASSERT_TRUE(ReadFdToString(p2cPipe.readFd(), &data));
1820a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        data = HEAD + data;
1830a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        ASSERT_TRUE(WriteStringToFd(data, c2pPipe.writeFd()));
1846355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        p2cPipe.readFd().reset();
1856355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        c2pPipe.writeFd().reset();
1860a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        // Must exit here otherwise the child process will continue executing the test binary.
187b44f7d46b647e24d8ea4fdf45742bbcbbfb03113Yi Jin        _exit(EXIT_SUCCESS);
1880a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    } else {
1896355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        p2cPipe.readFd().reset();
1906355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        c2pPipe.writeFd().reset();
1910a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
192e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin        ASSERT_EQ(NO_ERROR,
193e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin                  buffer.readProcessedDataInStream(tf.fd, std::move(p2cPipe.writeFd()),
194e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin                                                   std::move(c2pPipe.readFd()), READ_TIMEOUT));
1950a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        AssertBufferReadSuccessful(HEAD.size() + testdata.size());
1960a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        AssertBufferContent(expected.c_str());
1970a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        wait(&pid);
1980a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    }
1990a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin}
2000a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2010a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi JinTEST_F(FdBufferTest, ReadInStreamEmpty) {
202254102d858942393482589b8f1e6102b33797b58Wei Wang    ASSERT_TRUE(WriteStringToFile("", tf.path));
2030a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2040a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    int pid = fork();
2050a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    ASSERT_TRUE(pid != -1);
2060a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2070a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    if (pid == 0) {
2086355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        p2cPipe.writeFd().reset();
2096355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        c2pPipe.readFd().reset();
210e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin        ASSERT_TRUE(DoDataStream(p2cPipe.readFd(), c2pPipe.writeFd()));
2116355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        p2cPipe.readFd().reset();
2126355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        c2pPipe.writeFd().reset();
213b44f7d46b647e24d8ea4fdf45742bbcbbfb03113Yi Jin        _exit(EXIT_SUCCESS);
2140a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    } else {
2156355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        p2cPipe.readFd().reset();
2166355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        c2pPipe.writeFd().reset();
2170a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
218e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin        ASSERT_EQ(NO_ERROR,
219e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin                  buffer.readProcessedDataInStream(tf.fd, std::move(p2cPipe.writeFd()),
220e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin                                                   std::move(c2pPipe.readFd()), READ_TIMEOUT));
2210a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        AssertBufferReadSuccessful(0);
2220a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        AssertBufferContent("");
2230a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        wait(&pid);
2240a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    }
2250a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin}
2260a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2270a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi JinTEST_F(FdBufferTest, ReadInStreamMoreThan4MB) {
2280a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    const std::string testFile = kTestDataPath + "morethan4MB.txt";
229b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    size_t fourMB = (size_t)4 * 1024 * 1024;
2306355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin    unique_fd fd(open(testFile.c_str(), O_RDONLY | O_CLOEXEC));
2316355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin    ASSERT_NE(fd.get(), -1);
2320a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    int pid = fork();
2330a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    ASSERT_TRUE(pid != -1);
2340a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2350a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    if (pid == 0) {
2366355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        p2cPipe.writeFd().reset();
2376355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        c2pPipe.readFd().reset();
238e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin        ASSERT_TRUE(DoDataStream(p2cPipe.readFd(), c2pPipe.writeFd()));
2396355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        p2cPipe.readFd().reset();
2406355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        c2pPipe.writeFd().reset();
241b44f7d46b647e24d8ea4fdf45742bbcbbfb03113Yi Jin        _exit(EXIT_SUCCESS);
2420a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    } else {
2436355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        p2cPipe.readFd().reset();
2446355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        c2pPipe.writeFd().reset();
2450a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
246e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin        ASSERT_EQ(NO_ERROR,
247e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin                  buffer.readProcessedDataInStream(fd, std::move(p2cPipe.writeFd()),
248e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin                                                   std::move(c2pPipe.readFd()), READ_TIMEOUT));
2490ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin        EXPECT_EQ(buffer.size(), fourMB);
2500a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        EXPECT_FALSE(buffer.timedOut());
2510a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        EXPECT_TRUE(buffer.truncated());
2520a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        wait(&pid);
253c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        EncodedBuffer::iterator it = buffer.data();
254c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        it.rp()->move(fourMB);
2550ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin        EXPECT_EQ(it.bytesRead(), fourMB);
256c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        EXPECT_FALSE(it.hasNext());
257c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin
258c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        it.rp()->rewind();
259c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        while (it.hasNext()) {
2600ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin            char c = 'A' + (it.bytesRead() % 64 / 8);
261c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin            ASSERT_TRUE(it.next() == c);
2620ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin        }
2630a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    }
2640a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin}
2650a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2660a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi JinTEST_F(FdBufferTest, ReadInStreamTimeOut) {
2670a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    std::string testdata = "timeout test";
268254102d858942393482589b8f1e6102b33797b58Wei Wang    ASSERT_TRUE(WriteStringToFile(testdata, tf.path));
2690a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2700a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    int pid = fork();
2710a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    ASSERT_TRUE(pid != -1);
2720a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2730a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    if (pid == 0) {
2746355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        p2cPipe.writeFd().reset();
2756355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        c2pPipe.readFd().reset();
2760a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        while (true) {
2770a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            sleep(1);
2780a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        }
279b44f7d46b647e24d8ea4fdf45742bbcbbfb03113Yi Jin        _exit(EXIT_FAILURE);
2800a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    } else {
2816355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        p2cPipe.readFd().reset();
2826355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin        c2pPipe.writeFd().reset();
2830a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
284e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin        ASSERT_EQ(NO_ERROR,
285e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin                  buffer.readProcessedDataInStream(tf.fd, std::move(p2cPipe.writeFd()),
286e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin                                                   std::move(c2pPipe.readFd()), QUICK_TIMEOUT_MS));
2870a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        EXPECT_TRUE(buffer.timedOut());
288b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        kill(pid, SIGKILL);  // reap the child process
2890a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    }
2900a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin}
291