198 lines
8.8 KiB
C++
198 lines
8.8 KiB
C++
/**
|
|
* @file llstreamqueue_test.cpp
|
|
* @author Nat Goodspeed
|
|
* @date 2012-01-05
|
|
* @brief Test for llstreamqueue.
|
|
*
|
|
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
|
|
* Copyright (c) 2012, Linden Research, Inc.
|
|
* $/LicenseInfo$
|
|
*/
|
|
|
|
// Precompiled header
|
|
#include "linden_common.h"
|
|
// associated header
|
|
#include "llstreamqueue.h"
|
|
// STL headers
|
|
#include <vector>
|
|
// std headers
|
|
// external library headers
|
|
#include <boost/foreach.hpp>
|
|
// other Linden headers
|
|
#include "../test/lltut.h"
|
|
#include "stringize.h"
|
|
|
|
/*****************************************************************************
|
|
* TUT
|
|
*****************************************************************************/
|
|
namespace tut
|
|
{
|
|
struct llstreamqueue_data
|
|
{
|
|
llstreamqueue_data():
|
|
// we want a buffer with actual bytes in it, not an empty vector
|
|
buffer(10)
|
|
{}
|
|
// As LLStreamQueue is merely a typedef for
|
|
// LLGenericStreamQueue<char>, and no logic in LLGenericStreamQueue is
|
|
// specific to the <char> instantiation, we're comfortable for now
|
|
// testing only the narrow-char version.
|
|
LLStreamQueue strq;
|
|
// buffer for use in multiple tests
|
|
std::vector<char> buffer;
|
|
};
|
|
typedef test_group<llstreamqueue_data> llstreamqueue_group;
|
|
typedef llstreamqueue_group::object object;
|
|
llstreamqueue_group llstreamqueuegrp("llstreamqueue");
|
|
|
|
template<> template<>
|
|
void object::test<1>()
|
|
{
|
|
set_test_name("empty LLStreamQueue");
|
|
ensure_equals("brand-new LLStreamQueue isn't empty",
|
|
strq.size(), 0);
|
|
ensure_equals("brand-new LLStreamQueue returns data",
|
|
strq.asSource().read(&buffer[0], buffer.size()), 0);
|
|
strq.asSink().close();
|
|
ensure_equals("closed empty LLStreamQueue not at EOF",
|
|
strq.asSource().read(&buffer[0], buffer.size()), -1);
|
|
}
|
|
|
|
template<> template<>
|
|
void object::test<2>()
|
|
{
|
|
set_test_name("one internal block, one buffer");
|
|
LLStreamQueue::Sink sink(strq.asSink());
|
|
ensure_equals("write(\"\")", sink.write("", 0), 0);
|
|
ensure_equals("0 write should leave LLStreamQueue empty (size())",
|
|
strq.size(), 0);
|
|
ensure_equals("0 write should leave LLStreamQueue empty (peek())",
|
|
strq.peek(&buffer[0], buffer.size()), 0);
|
|
// The meaning of "atomic" is that it must be smaller than our buffer.
|
|
std::string atomic("atomic");
|
|
ensure("test data exceeds buffer", atomic.length() < buffer.size());
|
|
ensure_equals(STRINGIZE("write(\"" << atomic << "\")"),
|
|
sink.write(&atomic[0], atomic.length()), atomic.length());
|
|
ensure_equals("size() after write()", strq.size(), atomic.length());
|
|
size_t peeklen(strq.peek(&buffer[0], buffer.size()));
|
|
ensure_equals(STRINGIZE("peek(\"" << atomic << "\")"),
|
|
peeklen, atomic.length());
|
|
ensure_equals(STRINGIZE("peek(\"" << atomic << "\") result"),
|
|
std::string(buffer.begin(), buffer.begin() + peeklen), atomic);
|
|
ensure_equals("size() after peek()", strq.size(), atomic.length());
|
|
// peek() should not consume. Use a different buffer to prove it isn't
|
|
// just leftover data from the first peek().
|
|
std::vector<char> again(buffer.size());
|
|
peeklen = size_t(strq.peek(&again[0], again.size()));
|
|
ensure_equals(STRINGIZE("peek(\"" << atomic << "\") again"),
|
|
peeklen, atomic.length());
|
|
ensure_equals(STRINGIZE("peek(\"" << atomic << "\") again result"),
|
|
std::string(again.begin(), again.begin() + peeklen), atomic);
|
|
// now consume.
|
|
std::vector<char> third(buffer.size());
|
|
size_t readlen(strq.read(&third[0], third.size()));
|
|
ensure_equals(STRINGIZE("read(\"" << atomic << "\")"),
|
|
readlen, atomic.length());
|
|
ensure_equals(STRINGIZE("read(\"" << atomic << "\") result"),
|
|
std::string(third.begin(), third.begin() + readlen), atomic);
|
|
ensure_equals("peek() after read()", strq.peek(&buffer[0], buffer.size()), 0);
|
|
ensure_equals("size() after read()", strq.size(), 0);
|
|
}
|
|
|
|
template<> template<>
|
|
void object::test<3>()
|
|
{
|
|
set_test_name("basic skip()");
|
|
std::string lovecraft("lovecraft");
|
|
ensure("test data exceeds buffer", lovecraft.length() < buffer.size());
|
|
ensure_equals(STRINGIZE("write(\"" << lovecraft << "\")"),
|
|
strq.write(&lovecraft[0], lovecraft.length()), lovecraft.length());
|
|
size_t peeklen(strq.peek(&buffer[0], buffer.size()));
|
|
ensure_equals(STRINGIZE("peek(\"" << lovecraft << "\")"),
|
|
peeklen, lovecraft.length());
|
|
ensure_equals(STRINGIZE("peek(\"" << lovecraft << "\") result"),
|
|
std::string(buffer.begin(), buffer.begin() + peeklen), lovecraft);
|
|
std::streamsize skip1(4);
|
|
ensure_equals(STRINGIZE("skip(" << skip1 << ")"), strq.skip(skip1), skip1);
|
|
ensure_equals("size() after skip()", strq.size(), lovecraft.length() - skip1);
|
|
size_t readlen(strq.read(&buffer[0], buffer.size()));
|
|
ensure_equals(STRINGIZE("read(\"" << lovecraft.substr(skip1) << "\")"),
|
|
readlen, lovecraft.length() - skip1);
|
|
ensure_equals(STRINGIZE("read(\"" << lovecraft.substr(skip1) << "\") result"),
|
|
std::string(buffer.begin(), buffer.begin() + readlen),
|
|
lovecraft.substr(skip1));
|
|
ensure_equals("unconsumed", strq.read(&buffer[0], buffer.size()), 0);
|
|
}
|
|
|
|
template<> template<>
|
|
void object::test<4>()
|
|
{
|
|
set_test_name("skip() multiple blocks");
|
|
std::string blocks[] = { "books of ", "H.P. ", "Lovecraft" };
|
|
std::streamsize total(blocks[0].length() + blocks[1].length() + blocks[2].length());
|
|
std::streamsize leave(5); // len("craft") above
|
|
std::streamsize skip(total - leave);
|
|
std::streamsize written(0);
|
|
BOOST_FOREACH(const std::string& block, blocks)
|
|
{
|
|
written += strq.write(&block[0], block.length());
|
|
ensure_equals("size() after write()", strq.size(), written);
|
|
}
|
|
std::streamsize skiplen(strq.skip(skip));
|
|
ensure_equals(STRINGIZE("skip(" << skip << ")"), skiplen, skip);
|
|
ensure_equals("size() after skip()", strq.size(), leave);
|
|
size_t readlen(strq.read(&buffer[0], buffer.size()));
|
|
ensure_equals("read(\"craft\")", readlen, leave);
|
|
ensure_equals("read(\"craft\") result",
|
|
std::string(buffer.begin(), buffer.begin() + readlen), "craft");
|
|
}
|
|
|
|
template<> template<>
|
|
void object::test<5>()
|
|
{
|
|
set_test_name("concatenate blocks");
|
|
std::string blocks[] = { "abcd", "efghij", "klmnopqrs" };
|
|
BOOST_FOREACH(const std::string& block, blocks)
|
|
{
|
|
strq.write(&block[0], block.length());
|
|
}
|
|
std::vector<char> longbuffer(30);
|
|
std::streamsize readlen(strq.read(&longbuffer[0], longbuffer.size()));
|
|
ensure_equals("read() multiple blocks",
|
|
readlen, blocks[0].length() + blocks[1].length() + blocks[2].length());
|
|
ensure_equals("read() multiple blocks result",
|
|
std::string(longbuffer.begin(), longbuffer.begin() + readlen),
|
|
blocks[0] + blocks[1] + blocks[2]);
|
|
}
|
|
|
|
template<> template<>
|
|
void object::test<6>()
|
|
{
|
|
set_test_name("split blocks");
|
|
std::string blocks[] = { "abcdefghijklm", "nopqrstuvwxyz" };
|
|
BOOST_FOREACH(const std::string& block, blocks)
|
|
{
|
|
strq.write(&block[0], block.length());
|
|
}
|
|
strq.close();
|
|
// We've already verified what strq.size() should be at this point;
|
|
// see above test named "skip() multiple blocks"
|
|
std::streamsize chksize(strq.size());
|
|
std::streamsize readlen(strq.read(&buffer[0], buffer.size()));
|
|
ensure_equals("read() 0", readlen, buffer.size());
|
|
ensure_equals("read() 0 result", std::string(buffer.begin(), buffer.end()), "abcdefghij");
|
|
chksize -= readlen;
|
|
ensure_equals("size() after read() 0", strq.size(), chksize);
|
|
readlen = strq.read(&buffer[0], buffer.size());
|
|
ensure_equals("read() 1", readlen, buffer.size());
|
|
ensure_equals("read() 1 result", std::string(buffer.begin(), buffer.end()), "klmnopqrst");
|
|
chksize -= readlen;
|
|
ensure_equals("size() after read() 1", strq.size(), chksize);
|
|
readlen = strq.read(&buffer[0], buffer.size());
|
|
ensure_equals("read() 2", readlen, chksize);
|
|
ensure_equals("read() 2 result",
|
|
std::string(buffer.begin(), buffer.begin() + readlen), "uvwxyz");
|
|
ensure_equals("read() 3", strq.read(&buffer[0], buffer.size()), -1);
|
|
}
|
|
} // namespace tut
|