#include <gtest/gtest.h>
#include "runtime/state/memory/ByteStreamStateHandle.h"
TEST(ByteStreamStateHandleTest, StreamSeekAndPos)
{
std::vector<uint8_t> data = {34, 25, 22, 66, 88, 54};
ByteStreamStateHandle handle("name", data);
for (int i = static_cast<int>(data.size()); i >= 0; --i) {
auto in = handle.OpenInputStream();
in->Seek(i);
EXPECT_EQ(i, in->GetPos());
if (i < static_cast<int>(data.size())) {
EXPECT_EQ(data[i], in->Read());
EXPECT_EQ(i + 1, in->GetPos());
} else {
EXPECT_EQ(-1, in->Read());
EXPECT_EQ(i, in->GetPos());
}
}
auto in = handle.OpenInputStream();
in->Seek(data.size());
EXPECT_EQ(-1, in->Read());
EXPECT_EQ(-1, in->Read());
EXPECT_EQ(-1, in->Read());
EXPECT_EQ(data.size(), in->GetPos());
}
TEST(ByteStreamStateHandleTest, StreamSeekOutOfBounds)
{
int len = 10;
ByteStreamStateHandle handle("name", std::vector<uint8_t>(len));
auto in = handle.OpenInputStream();
EXPECT_THROW(in->Seek(-2), std::ios_base::failure);
in = handle.OpenInputStream();
EXPECT_THROW(in->Seek(len + 1), std::ios_base::failure);
in = handle.OpenInputStream();
EXPECT_THROW(in->Seek(static_cast<long long>(INT32_MAX) + 100), std::ios_base::failure);
}
TEST(ByteStreamStateHandleTest, BulkRead)
{
std::vector<uint8_t> data = {34, 25, 22, 66};
ByteStreamStateHandle handle("name", data);
int targetLen = 8;
for (int start = 0; start < static_cast<int>(data.size()); ++start) {
for (int num = 0; num < targetLen; ++num) {
auto in = handle.OpenInputStream();
in->Seek(start);
std::vector<uint8_t> target(targetLen, 0);
int Read = in->Read(target, targetLen - num, num);
int expectedRead = std::min(num, static_cast<int>(data.size()) - start);
EXPECT_EQ(expectedRead, Read);
for (int i = 0; i < Read; ++i) {
EXPECT_EQ(data[start + i], static_cast<uint8_t>(target[targetLen - num + i]));
}
int newPos = start + Read;
EXPECT_EQ(newPos, in->GetPos());
int expectedNextByte = (newPos < static_cast<int>(data.size())) ? data[newPos] : -1;
EXPECT_EQ(expectedNextByte, in->Read());
}
}
}
TEST(ByteStreamStateHandleTest, BulkReadIndexOutOfBounds)
{
ByteStreamStateHandle handle("name", std::vector<uint8_t>(10));
auto check_invalid = [&](int off, int len) {
auto in = handle.OpenInputStream();
std::vector<uint8_t> buffer(10);
EXPECT_THROW(in->Read(buffer, off, len), std::out_of_range);
};
check_invalid(-1, 5);
check_invalid(10, 5);
check_invalid(0, -2);
check_invalid(5, 6);
check_invalid(5, INT32_MAX);
}