blob: f1163ed1697cb29a1bd0e206bcff3319ea790bf7 [file] [log] [blame]
// Copyright 2016 The Android Open Source Project
//
// This software is licensed under the terms of the GNU General Public
// License version 2, as published by the Free Software Foundation, and
// may be copied, distributed, and modified under those terms.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
#include "android/emulation/testing/TestAndroidPipeDevice.h"
#include <gtest/gtest.h>
#include <memory>
#include <string>
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
using Guest = android::TestAndroidPipeDevice::Guest;
// A TestAndroidPipeDevice that provides the 'pingpong' service.
extern "C" void android_pipe_add_type_pingpong(void);
class PingPongPipeDevice : public android::TestAndroidPipeDevice {
public:
PingPongPipeDevice() {
android_pipe_add_type_pingpong();
}
};
TEST(AndroidPipe, PingPongPipeWritesAndReadsOfTheSameSize) {
PingPongPipeDevice dev;
std::unique_ptr<Guest> guest(Guest::create());
EXPECT_EQ(0, guest->connect("pingpong"));
EXPECT_EQ(PIPE_POLL_OUT, guest->poll());
static const size_t kSizes[] = {
0, 100, 128, 256, 512, 1000, 2048, 8192, 655356,
};
for (size_t n = 0; n < ARRAY_SIZE(kSizes); n++) {
size_t size = kSizes[n];
// Allocate and fill buffer with simple pattern.
std::string buffer(size, 'x');
for (size_t i = 0u; i < size; ++i) {
buffer[i] = (char)(i + size);
}
// Send buffer to service.
EXPECT_EQ(PIPE_POLL_OUT, guest->poll());
EXPECT_EQ(size, guest->write(buffer.c_str(), size));
if (size > 0) {
EXPECT_EQ(PIPE_POLL_IN|PIPE_POLL_OUT, guest->poll());
// Erase buffer, then receive data from service.
memset(&buffer[0], '\xff', size);
EXPECT_EQ(size, guest->read(&buffer[0], size));
EXPECT_EQ(PIPE_POLL_OUT, guest->poll());
// Check returned pattern
for (size_t i = 0; i < size; ++i) {
EXPECT_EQ((char)(i + size), buffer[i]) << "# " << i << " / " << size;
}
} else {
EXPECT_EQ(PIPE_POLL_OUT, guest->poll());
EXPECT_GT(0, guest->read(&buffer[0], size));
}
}
}
TEST(AndroidPipe, PingPongPipeLargeWriteWithSmallReads) {
PingPongPipeDevice dev;
std::unique_ptr<Guest> guest(Guest::create());
EXPECT_EQ(0, guest->connect("pingpong"));
EXPECT_EQ(PIPE_POLL_OUT, guest->poll());
const size_t size = 100000;
std::string buffer(size, 'x');
for (size_t i = 0; i < size; ++i) {
buffer[i] = (char)i;
}
EXPECT_EQ(size, guest->write(buffer.c_str(), size));
for (size_t i = 0; i < size; i++) {
char tmp[1];
EXPECT_EQ(PIPE_POLL_IN|PIPE_POLL_OUT, guest->poll());
EXPECT_EQ(1, guest->read(tmp, 1));
EXPECT_EQ((char)i, tmp[0]) << "# " << i << " expected " << (char)i;
}
EXPECT_EQ(PIPE_POLL_OUT, guest->poll());
}
TEST(AndroidPipe, PingPongSmallWritesAndLargeRead) {
PingPongPipeDevice dev;
std::unique_ptr<Guest> guest(Guest::create());
EXPECT_EQ(0, guest->connect("pingpong"));
EXPECT_EQ(PIPE_POLL_OUT, guest->poll());
const size_t size = 100000;
std::string buffer(size, 'x');
for (size_t i = 0; i < size; ++i) {
buffer[i] = (char)i;
}
for (size_t i = 0; i < size; i++) {
EXPECT_EQ(1, guest->write(&buffer[i], 1)) << "# " << i << " / " << size;
EXPECT_EQ(PIPE_POLL_IN|PIPE_POLL_OUT, guest->poll());
}
memset(&buffer[0], '\xff', size);
EXPECT_EQ(size, guest->read(&buffer[0], size));
EXPECT_EQ(PIPE_POLL_OUT, guest->poll());
for (size_t i = 0; i < size; i++) {
EXPECT_EQ((char)i, buffer[i]) << "# " << i << " / " << size;
}
EXPECT_EQ(PIPE_POLL_OUT, guest->poll());
}