FdBuffer_test.cpp revision 99c248feb2d1f863b864bdfd1e3b37af17f18732
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.
140a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
150a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin#define LOG_TAG "incidentd"
160a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
170a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin#include "FdBuffer.h"
1899c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin#include "io_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
270a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jinconst int READ_TIMEOUT = 5 * 1000;
280a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jinconst int BUFFER_SIZE = 16 * 1024;
29b44f7d46b647e24d8ea4fdf45742bbcbbfb03113Yi Jinconst int QUICK_TIMEOUT_MS = 100;
300a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jinconst std::string HEAD = "[OK]";
310a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
320a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jinusing namespace android;
330a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jinusing namespace android::base;
340a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jinusing ::testing::Test;
350a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
360a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jinclass FdBufferTest : public Test {
370a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jinpublic:
380a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    virtual void SetUp() override {
390a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        ASSERT_NE(tf.fd, -1);
400a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        ASSERT_NE(p2cPipe.init(), -1);
410a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        ASSERT_NE(c2pPipe.init(), -1);
420a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    }
430a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
440a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    void AssertBufferReadSuccessful(size_t expected) {
450a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        EXPECT_EQ(buffer.size(), expected);
460a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        EXPECT_FALSE(buffer.timedOut());
470a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        EXPECT_FALSE(buffer.truncated());
480a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    }
490a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
500a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    void AssertBufferContent(const char* expected) {
5199c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin        int i=0;
5299c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin        FdBuffer::iterator it = buffer.begin();
5399c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin        while (expected[i] != '\0') {
5499c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin            ASSERT_EQ(*it, expected[i++]);
5599c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin            it++;
5699c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin        }
5799c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin        ASSERT_EQ(it, buffer.end());
580a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    }
590a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
600a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    bool DoDataStream(int rFd, int wFd) {
610a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        char buf[BUFFER_SIZE];
620a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        ssize_t nRead;
630a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        while ((nRead = read(rFd, buf, BUFFER_SIZE)) > 0) {
640a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            ssize_t nWritten = 0;
650a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            while (nWritten < nRead) {
660a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                ssize_t amt = write(wFd, 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";
880a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    ASSERT_TRUE(WriteStringToFile(testdata, tf.path, false));
890a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi 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) {
950ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    FdBuffer::iterator it = buffer.begin();
960ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    EXPECT_EQ(it, buffer.end());
970ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    it += 1;
980ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    EXPECT_TRUE(it.outOfBound());
990ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin}
1000ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin
10199c248feb2d1f863b864bdfd1e3b37af17f18732Yi JinTEST_F(FdBufferTest, IteratorSnapshot) {
10299c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin    FdBuffer::iterator it = buffer.begin();
10399c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin    it += 4;
10499c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin    FdBuffer::iterator snapshot = it.snapshot();
10599c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin    it += 5;
10699c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin    EXPECT_TRUE(snapshot != it);
10799c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin    EXPECT_EQ(it - snapshot, 5);
10899c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin    EXPECT_EQ(snapshot - it, -5);
10999c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin}
11099c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin
1110ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi JinTEST_F(FdBufferTest, ReadAndIterate) {
1120ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    std::string testdata = "FdBuffer test string";
1130ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    ASSERT_TRUE(WriteStringToFile(testdata, tf.path, false));
1140ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    ASSERT_EQ(NO_ERROR, buffer.read(tf.fd, READ_TIMEOUT));
1150ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin
1160ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    int i=0;
1170ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    for (FdBuffer::iterator it = buffer.begin(); it != buffer.end(); ++it) {
1180ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin        EXPECT_EQ(*it, (uint8_t)testdata[i++]);
1190ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    }
1200ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin
1210ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    FdBuffer::iterator it = buffer.begin();
1220ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    it += buffer.size();
1230ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    EXPECT_EQ(it, buffer.end());
1240ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    EXPECT_EQ(it.bytesRead(), testdata.size());
1250ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    EXPECT_FALSE(it.outOfBound());
1260ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin}
1270ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin
1280a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi JinTEST_F(FdBufferTest, ReadTimeout) {
1290a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    int pid = fork();
1300a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    ASSERT_TRUE(pid != -1);
1310a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1320a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    if (pid == 0) {
1330a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(c2pPipe.readFd());
1340a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        while(true) {
1350a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            write(c2pPipe.writeFd(), "poo", 3);
1360a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            sleep(1);
1370a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        }
138b44f7d46b647e24d8ea4fdf45742bbcbbfb03113Yi Jin        _exit(EXIT_FAILURE);
1390a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    } else {
1400a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(c2pPipe.writeFd());
1410a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
142b44f7d46b647e24d8ea4fdf45742bbcbbfb03113Yi Jin        status_t status = buffer.read(c2pPipe.readFd(), QUICK_TIMEOUT_MS);
1430a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        ASSERT_EQ(NO_ERROR, status);
1440a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        EXPECT_TRUE(buffer.timedOut());
1450a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1460a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        kill(pid, SIGKILL); // reap the child process
1470a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    }
1480a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin}
1490a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1500a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi JinTEST_F(FdBufferTest, ReadInStreamAndWrite) {
1510a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    std::string testdata = "simply test read in stream";
1520a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    std::string expected = HEAD + testdata;
1530a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    ASSERT_TRUE(WriteStringToFile(testdata, tf.path, false));
1540a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1550a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    int pid = fork();
1560a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    ASSERT_TRUE(pid != -1);
1570a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1580a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    if (pid == 0) {
1590a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(p2cPipe.writeFd());
1600a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(c2pPipe.readFd());
1610a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        ASSERT_TRUE(WriteStringToFd(HEAD, c2pPipe.writeFd()));
1620a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        ASSERT_TRUE(DoDataStream(p2cPipe.readFd(), c2pPipe.writeFd()));
1630a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(p2cPipe.readFd());
1640a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(c2pPipe.writeFd());
1650a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        // Must exit here otherwise the child process will continue executing the test binary.
166b44f7d46b647e24d8ea4fdf45742bbcbbfb03113Yi Jin        _exit(EXIT_SUCCESS);
1670a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    } else {
1680a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(p2cPipe.readFd());
1690a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(c2pPipe.writeFd());
1700a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1710a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        ASSERT_EQ(NO_ERROR, buffer.readProcessedDataInStream(tf.fd,
1720a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            p2cPipe.writeFd(), c2pPipe.readFd(), READ_TIMEOUT));
1730a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        AssertBufferReadSuccessful(HEAD.size() + testdata.size());
1740a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        AssertBufferContent(expected.c_str());
1750a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        wait(&pid);
1760a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    }
1770a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin}
1780a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1790a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi JinTEST_F(FdBufferTest, ReadInStreamAndWriteAllAtOnce) {
1800a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    std::string testdata = "child process flushes only after all data are read.";
1810a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    std::string expected = HEAD + testdata;
1820a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    ASSERT_TRUE(WriteStringToFile(testdata, tf.path, false));
1830a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1840a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    int pid = fork();
1850a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    ASSERT_TRUE(pid != -1);
1860a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1870a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    if (pid == 0) {
1880a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(p2cPipe.writeFd());
1890a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(c2pPipe.readFd());
1900a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        std::string data;
1910a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        // wait for read finishes then write.
1920a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        ASSERT_TRUE(ReadFdToString(p2cPipe.readFd(), &data));
1930a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        data = HEAD + data;
1940a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        ASSERT_TRUE(WriteStringToFd(data, c2pPipe.writeFd()));
1950a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(p2cPipe.readFd());
1960a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(c2pPipe.writeFd());
1970a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        // Must exit here otherwise the child process will continue executing the test binary.
198b44f7d46b647e24d8ea4fdf45742bbcbbfb03113Yi Jin        _exit(EXIT_SUCCESS);
1990a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    } else {
2000a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(p2cPipe.readFd());
2010a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(c2pPipe.writeFd());
2020a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2030a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        ASSERT_EQ(NO_ERROR, buffer.readProcessedDataInStream(tf.fd,
2040a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            p2cPipe.writeFd(), c2pPipe.readFd(), READ_TIMEOUT));
2050a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        AssertBufferReadSuccessful(HEAD.size() + testdata.size());
2060a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        AssertBufferContent(expected.c_str());
2070a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        wait(&pid);
2080a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    }
2090a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin}
2100a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2110a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi JinTEST_F(FdBufferTest, ReadInStreamEmpty) {
2120a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    ASSERT_TRUE(WriteStringToFile("", tf.path, false));
2130a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2140a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    int pid = fork();
2150a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    ASSERT_TRUE(pid != -1);
2160a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2170a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    if (pid == 0) {
2180a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(p2cPipe.writeFd());
2190a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(c2pPipe.readFd());
2200a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        ASSERT_TRUE(DoDataStream(p2cPipe.readFd(), c2pPipe.writeFd()));
2210a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(p2cPipe.readFd());
2220a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(c2pPipe.writeFd());
223b44f7d46b647e24d8ea4fdf45742bbcbbfb03113Yi Jin        _exit(EXIT_SUCCESS);
2240a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    } else {
2250a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(p2cPipe.readFd());
2260a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(c2pPipe.writeFd());
2270a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2280a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        ASSERT_EQ(NO_ERROR, buffer.readProcessedDataInStream(tf.fd,
2290a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            p2cPipe.writeFd(), c2pPipe.readFd(), READ_TIMEOUT));
2300a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        AssertBufferReadSuccessful(0);
2310a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        AssertBufferContent("");
2320a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        wait(&pid);
2330a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    }
2340a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin}
2350a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2360a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi JinTEST_F(FdBufferTest, ReadInStreamMoreThan4MB) {
2370a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    const std::string testFile = kTestDataPath + "morethan4MB.txt";
2380ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    size_t fourMB = (size_t) 4 * 1024 * 1024;
23999c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin    int fd = open(testFile.c_str(), O_RDONLY | O_CLOEXEC);
2400a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    ASSERT_NE(fd, -1);
2410a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    int pid = fork();
2420a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    ASSERT_TRUE(pid != -1);
2430a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2440a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    if (pid == 0) {
2450a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(p2cPipe.writeFd());
2460a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(c2pPipe.readFd());
2470a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        ASSERT_TRUE(DoDataStream(p2cPipe.readFd(), c2pPipe.writeFd()));
2480a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(p2cPipe.readFd());
2490a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(c2pPipe.writeFd());
250b44f7d46b647e24d8ea4fdf45742bbcbbfb03113Yi Jin        _exit(EXIT_SUCCESS);
2510a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    } else {
2520a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(p2cPipe.readFd());
2530a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(c2pPipe.writeFd());
2540a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2550a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        ASSERT_EQ(NO_ERROR, buffer.readProcessedDataInStream(fd,
2560a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            p2cPipe.writeFd(), c2pPipe.readFd(), READ_TIMEOUT));
2570ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin        EXPECT_EQ(buffer.size(), fourMB);
2580a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        EXPECT_FALSE(buffer.timedOut());
2590a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        EXPECT_TRUE(buffer.truncated());
2600a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        wait(&pid);
2610ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin        FdBuffer::iterator it = buffer.begin();
2620ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin        it += fourMB;
2630ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin        EXPECT_EQ(it.bytesRead(), fourMB);
2640ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin        EXPECT_EQ(it, buffer.end());
2650ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin        for (FdBuffer::iterator it = buffer.begin(); it != buffer.end(); it++) {
2660ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin            char c = 'A' + (it.bytesRead() % 64 / 8);
2670ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin            ASSERT_TRUE(*it == c);
2680ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin        }
2690a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    }
2700a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin}
2710a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2720a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi JinTEST_F(FdBufferTest, ReadInStreamTimeOut) {
2730a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    std::string testdata = "timeout test";
2740a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    ASSERT_TRUE(WriteStringToFile(testdata, tf.path, false));
2750a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2760a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    int pid = fork();
2770a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    ASSERT_TRUE(pid != -1);
2780a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2790a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    if (pid == 0) {
2800a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(p2cPipe.writeFd());
2810a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(c2pPipe.readFd());
2820a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        while (true) {
2830a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            sleep(1);
2840a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        }
285b44f7d46b647e24d8ea4fdf45742bbcbbfb03113Yi Jin        _exit(EXIT_FAILURE);
2860a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    } else {
2870a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(p2cPipe.readFd());
2880a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        close(c2pPipe.writeFd());
2890a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2900a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        ASSERT_EQ(NO_ERROR, buffer.readProcessedDataInStream(tf.fd,
291b44f7d46b647e24d8ea4fdf45742bbcbbfb03113Yi Jin            p2cPipe.writeFd(), c2pPipe.readFd(), QUICK_TIMEOUT_MS));
2920a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        EXPECT_TRUE(buffer.timedOut());
2930a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        kill(pid, SIGKILL); // reap the child process
2940a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    }
2950a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin}
296