375 lines
14 KiB
C++
375 lines
14 KiB
C++
/**
|
|
* @file llmessagetemplateparser_tut.cpp
|
|
* @date April 2007
|
|
* @brief LLMessageTemplateParser unit tests
|
|
*
|
|
* $LicenseInfo:firstyear=2006&license=viewergpl$
|
|
*
|
|
* Copyright (c) 2006-2009, Linden Research, Inc.
|
|
*
|
|
* Second Life Viewer Source Code
|
|
* The source code in this file ("Source Code") is provided by Linden Lab
|
|
* to you under the terms of the GNU General Public License, version 2.0
|
|
* ("GPL"), unless you have obtained a separate licensing agreement
|
|
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
|
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
|
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
|
*
|
|
* There are special exceptions to the terms and conditions of the GPL as
|
|
* it is applied to this Source Code. View the full text of the exception
|
|
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
|
* online at
|
|
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
|
*
|
|
* By copying, modifying or distributing this software, you acknowledge
|
|
* that you have read and understood your obligations described above,
|
|
* and agree to abide by those obligations.
|
|
*
|
|
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
|
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
|
* COMPLETENESS OR PERFORMANCE.
|
|
* $/LicenseInfo$
|
|
*/
|
|
|
|
#include "linden_common.h"
|
|
#include "llmessagetemplateparser.h"
|
|
#include "lltut.h"
|
|
|
|
namespace tut
|
|
{
|
|
struct LLMessageTemplateParserTestData {
|
|
LLMessageTemplateParserTestData() : mMessage("unset message")
|
|
{
|
|
}
|
|
|
|
~LLMessageTemplateParserTestData()
|
|
{
|
|
}
|
|
|
|
void ensure_next(LLTemplateTokenizer & tokens,
|
|
std::string value,
|
|
U32 line)
|
|
{
|
|
std::string next = tokens.next();
|
|
ensure_equals(mMessage + " token matches", next, value);
|
|
ensure_equals(mMessage + " line matches", tokens.line(), line);
|
|
}
|
|
|
|
char * prehash(const char * name)
|
|
{
|
|
return LLMessageStringTable::getInstance()->getString(name);
|
|
}
|
|
|
|
void ensure_block_attributes(std::string identifier,
|
|
const LLMessageTemplate * message,
|
|
const char * name,
|
|
EMsgBlockType type,
|
|
S32 number,
|
|
S32 total_size)
|
|
{
|
|
const LLMessageBlock * block = message->getBlock(prehash(name));
|
|
identifier = identifier + ":" + message->mName + ":" + name + " block";
|
|
ensure(identifier + " exists", block != NULL);
|
|
ensure_equals(identifier + " name", block->mName, prehash(name));
|
|
ensure_equals(identifier + " type", block->mType, type);
|
|
ensure_equals(identifier + " number", block->mNumber, number);
|
|
ensure_equals(identifier + " total size", block->mTotalSize, total_size);
|
|
}
|
|
|
|
void ensure_variable_attributes(std::string identifier,
|
|
const LLMessageBlock * block,
|
|
const char * name,
|
|
EMsgVariableType type,
|
|
S32 size)
|
|
{
|
|
const LLMessageVariable * var = block->getVariable(prehash(name));
|
|
identifier = identifier + ":" + block->mName + ":" + name + " variable";
|
|
ensure(identifier + " exists", var != NULL);
|
|
ensure_equals(
|
|
identifier + " name", var->getName(), prehash(name));
|
|
ensure_equals(
|
|
identifier + " type", var->getType(), type);
|
|
ensure_equals(identifier + " size", var->getSize(), size);
|
|
}
|
|
|
|
std::string mMessage;
|
|
|
|
};
|
|
|
|
typedef test_group<LLMessageTemplateParserTestData> LLMessageTemplateParserTestGroup;
|
|
typedef LLMessageTemplateParserTestGroup::object LLMessageTemplateParserTestObject;
|
|
LLMessageTemplateParserTestGroup llMessageTemplateParserTestGroup("LLMessageTemplateParser");
|
|
|
|
template<> template<>
|
|
void LLMessageTemplateParserTestObject::test<1>()
|
|
// tests tokenizer constructor and next methods
|
|
{
|
|
mMessage = "test method 1 walkthrough";
|
|
LLTemplateTokenizer tokens("first line\nnext\t line\n\nfourth");
|
|
ensure_next(tokens, "first", 1);
|
|
ensure_next(tokens, "line", 1);
|
|
ensure_next(tokens, "next", 2);
|
|
ensure_next(tokens, "line", 2);
|
|
ensure_next(tokens, "fourth", 4);
|
|
|
|
tokens = LLTemplateTokenizer("\n\t{ \t Test1 Fixed \n 523 }\n\n");
|
|
ensure(tokens.want("{"));
|
|
ensure_next(tokens, "Test1", 2);
|
|
ensure_next(tokens, "Fixed", 2);
|
|
ensure_next(tokens, "523", 3);
|
|
ensure(tokens.want("}"));
|
|
|
|
tokens = LLTemplateTokenizer("first line\nnext\t line\n\nfourth");
|
|
ensure(tokens.want("first"));
|
|
ensure_next(tokens, "line", 1);
|
|
ensure_next(tokens, "next", 2);
|
|
ensure_next(tokens, "line", 2);
|
|
ensure(tokens.want("fourth"));
|
|
}
|
|
|
|
template<> template<>
|
|
void LLMessageTemplateParserTestObject::test<2>()
|
|
// tests tokenizer want method
|
|
{
|
|
// *NOTE: order matters
|
|
LLTemplateTokenizer tokens("first line\nnext\t line\n\nfourth");
|
|
ensure_equals("wants first token", tokens.want("first"), true);
|
|
ensure_equals("doesn't want blar token", tokens.want("blar"), false);
|
|
ensure_equals("wants line token", tokens.want("line"), true);
|
|
}
|
|
|
|
template<> template<>
|
|
void LLMessageTemplateParserTestObject::test<3>()
|
|
// tests tokenizer eof methods
|
|
{
|
|
LLTemplateTokenizer tokens("single\n\n");
|
|
ensure_equals("is not at eof at beginning", tokens.atEOF(), false);
|
|
ensure_equals("doesn't want eof", tokens.wantEOF(), false);
|
|
ensure_equals("wants the first token just to consume it",
|
|
tokens.want("single"), true);
|
|
ensure_equals("is not at eof in middle", tokens.atEOF(), false);
|
|
ensure_equals("wants eof", tokens.wantEOF(), true);
|
|
ensure_equals("is at eof at end", tokens.atEOF(), true);
|
|
}
|
|
|
|
template<> template<>
|
|
void LLMessageTemplateParserTestObject::test<4>()
|
|
// tests variable parsing method
|
|
{
|
|
LLTemplateTokenizer tokens(std::string("{ Test0 \n\t\n U32 \n\n }"));
|
|
LLMessageVariable * var = LLTemplateParser::parseVariable(tokens);
|
|
|
|
ensure("test0 var parsed", var != 0);
|
|
ensure_equals("name of variable", std::string(var->getName()), std::string("Test0"));
|
|
ensure_equals("type of variable is U32", var->getType(), MVT_U32);
|
|
ensure_equals("size of variable", var->getSize(), 4);
|
|
|
|
delete var;
|
|
|
|
std::string message_string("\n\t{ \t Test1 Fixed \n 523 }\n\n");
|
|
tokens = LLTemplateTokenizer(message_string);
|
|
var = LLTemplateParser::parseVariable(tokens);
|
|
|
|
ensure("test1 var parsed", var != 0);
|
|
ensure_equals("name of variable", std::string(var->getName()), std::string("Test1"));
|
|
ensure_equals("type of variable is Fixed", var->getType(), MVT_FIXED);
|
|
ensure_equals("size of variable", var->getSize(), 523);
|
|
|
|
delete var;
|
|
|
|
// *NOTE: the parsers call llerrs on invalid input, so we can't really
|
|
// test that :-(
|
|
}
|
|
|
|
template<> template<>
|
|
void LLMessageTemplateParserTestObject::test<5>()
|
|
// tests block parsing method
|
|
{
|
|
LLTemplateTokenizer tokens("{ BlockA Single { VarX F32 } }");
|
|
LLMessageBlock * block = LLTemplateParser::parseBlock(tokens);
|
|
|
|
ensure("blockA block parsed", block != 0);
|
|
ensure_equals("name of block", std::string(block->mName), std::string("BlockA"));
|
|
ensure_equals("type of block is Single", block->mType, MBT_SINGLE);
|
|
ensure_equals("total size of block", block->mTotalSize, 4);
|
|
ensure_equals("number of block defaults to 1", block->mNumber, 1);
|
|
ensure_equals("variable type of VarX is F32",
|
|
block->getVariableType(prehash("VarX")), MVT_F32);
|
|
ensure_equals("variable size of VarX",
|
|
block->getVariableSize(prehash("VarX")), 4);
|
|
|
|
delete block;
|
|
|
|
tokens = LLTemplateTokenizer("{ Stuff Variable { Id LLUUID } }");
|
|
block = LLTemplateParser::parseBlock(tokens);
|
|
|
|
ensure("stuff block parsed", block != 0);
|
|
ensure_equals("name of block", std::string(block->mName), std::string("Stuff"));
|
|
ensure_equals("type of block is Multiple", block->mType, MBT_VARIABLE);
|
|
ensure_equals("total size of block", block->mTotalSize, 16);
|
|
ensure_equals("number of block defaults to 1", block->mNumber, 1);
|
|
ensure_equals("variable type of Id is LLUUID",
|
|
block->getVariableType(prehash("Id")), MVT_LLUUID);
|
|
ensure_equals("variable size of Id",
|
|
block->getVariableSize(prehash("Id")), 16);
|
|
|
|
delete block;
|
|
|
|
tokens = LLTemplateTokenizer("{ Stuff2 Multiple 45 { Shid LLVector3d } }");
|
|
block = LLTemplateParser::parseBlock(tokens);
|
|
|
|
ensure("stuff2 block parsed", block != 0);
|
|
ensure_equals("name of block", std::string(block->mName), std::string("Stuff2"));
|
|
ensure_equals("type of block is Multiple", block->mType, MBT_MULTIPLE);
|
|
ensure_equals("total size of block", block->mTotalSize, 24);
|
|
ensure_equals("number of blocks", block->mNumber, 45);
|
|
ensure_equals("variable type of Shid is Vector3d",
|
|
block->getVariableType(prehash("Shid")), MVT_LLVector3d);
|
|
ensure_equals("variable size of Shid",
|
|
block->getVariableSize(prehash("Shid")), 24);
|
|
|
|
delete block;
|
|
}
|
|
|
|
template<> template<>
|
|
void LLMessageTemplateParserTestObject::test<6>()
|
|
// tests message parsing method on a simple message
|
|
{
|
|
std::string message_skel(
|
|
"{\n"
|
|
"TestMessage Low 1 NotTrusted Zerocoded\n"
|
|
"// comment \n"
|
|
" {\n"
|
|
"TestBlock1 Single\n"
|
|
" { Test1 U32 }\n"
|
|
" }\n"
|
|
" {\n"
|
|
" NeighborBlock Multiple 4\n"
|
|
" { Test0 U32 }\n"
|
|
" { Test1 U32 }\n"
|
|
" { Test2 U32 }\n"
|
|
" }\n"
|
|
"}");
|
|
LLTemplateTokenizer tokens(message_skel);
|
|
LLMessageTemplate * message = LLTemplateParser::parseMessage(tokens);
|
|
|
|
ensure("simple message parsed", message != 0);
|
|
ensure_equals("name of message", std::string(message->mName), std::string("TestMessage"));
|
|
ensure_equals("frequency is Low", message->mFrequency, MFT_LOW);
|
|
ensure_equals("trust is untrusted", message->mTrust, MT_NOTRUST);
|
|
ensure_equals("message number", message->mMessageNumber, (U32)((255 << 24) | (255 << 16) | 1));
|
|
ensure_equals("message encoding is zerocoded", message->mEncoding, ME_ZEROCODED);
|
|
ensure_equals("message deprecation is notdeprecated", message->mDeprecation, MD_NOTDEPRECATED);
|
|
|
|
LLMessageBlock * block = message->getBlock(prehash("NonexistantBlock"));
|
|
ensure("Nonexistant block does not exist", block == 0);
|
|
|
|
delete message;
|
|
}
|
|
|
|
template<> template<>
|
|
void LLMessageTemplateParserTestObject::test<7>()
|
|
// tests message parsing method on a deprecated message
|
|
{
|
|
std::string message_skel(
|
|
"{\n"
|
|
"TestMessageDeprecated High 34 Trusted Unencoded Deprecated\n"
|
|
" {\n"
|
|
"TestBlock2 Single\n"
|
|
" { Test2 S32 }\n"
|
|
" }\n"
|
|
"}");
|
|
LLTemplateTokenizer tokens(message_skel);
|
|
LLMessageTemplate * message = LLTemplateParser::parseMessage(tokens);
|
|
|
|
ensure("deprecated message parsed", message != 0);
|
|
ensure_equals("name of message", std::string(message->mName), std::string("TestMessageDeprecated"));
|
|
ensure_equals("frequency is High", message->mFrequency, MFT_HIGH);
|
|
ensure_equals("trust is trusted", message->mTrust, MT_TRUST);
|
|
ensure_equals("message number", message->mMessageNumber, (U32)34);
|
|
ensure_equals("message encoding is unencoded", message->mEncoding, ME_UNENCODED);
|
|
ensure_equals("message deprecation is deprecated", message->mDeprecation, MD_DEPRECATED);
|
|
|
|
delete message;
|
|
}
|
|
|
|
template<> template<> void LLMessageTemplateParserTestObject::test<8>()
|
|
// tests message parsing on RezMultipleAttachmentsFromInv, a possibly-faulty message
|
|
{
|
|
std::string message_skel(
|
|
"{\n\
|
|
RezMultipleAttachmentsFromInv Low 452 NotTrusted Zerocoded\n\
|
|
{\n\
|
|
AgentData Single\n\
|
|
{ AgentID LLUUID }\n\
|
|
{ SessionID LLUUID }\n\
|
|
} \n\
|
|
{\n\
|
|
HeaderData Single\n\
|
|
{ CompoundMsgID LLUUID } // All messages a single \"compound msg\" must have the same id\n\
|
|
{ TotalObjects U8 }\n\
|
|
{ FirstDetachAll BOOL }\n\
|
|
}\n\
|
|
{\n\
|
|
ObjectData Variable // 1 to 4 of these per packet\n\
|
|
{ ItemID LLUUID }\n\
|
|
{ OwnerID LLUUID }\n\
|
|
{ AttachmentPt U8 } // 0 for default\n\
|
|
{ ItemFlags U32 }\n\
|
|
{ GroupMask U32 }\n\
|
|
{ EveryoneMask U32 }\n\
|
|
{ NextOwnerMask U32 }\n\
|
|
{ Name Variable 1 }\n\
|
|
{ Description Variable 1 }\n\
|
|
}\n\
|
|
}\n\
|
|
");
|
|
LLTemplateTokenizer tokens(message_skel);
|
|
LLMessageTemplate * message = LLTemplateParser::parseMessage(tokens);
|
|
|
|
ensure("RezMultipleAttachmentsFromInv message parsed", message != 0);
|
|
ensure_equals("name of message", message->mName, prehash("RezMultipleAttachmentsFromInv"));
|
|
ensure_equals("frequency is low", message->mFrequency, MFT_LOW);
|
|
ensure_equals("trust is not trusted", message->mTrust, MT_NOTRUST);
|
|
ensure_equals("message number", message->mMessageNumber, (U32)((255 << 24) | (255 << 16) | 452));
|
|
ensure_equals("message encoding is zerocoded", message->mEncoding, ME_ZEROCODED);
|
|
|
|
ensure_block_attributes(
|
|
"RMAFI", message, "AgentData", MBT_SINGLE, 1, 16+16);
|
|
LLMessageBlock * block = message->getBlock(prehash("AgentData"));
|
|
ensure_variable_attributes("RMAFI",
|
|
block, "AgentID", MVT_LLUUID, 16);
|
|
ensure_variable_attributes("RMAFI",
|
|
block, "SessionID", MVT_LLUUID, 16);
|
|
|
|
ensure_block_attributes(
|
|
"RMAFI", message, "HeaderData", MBT_SINGLE, 1, 16+1+1);
|
|
block = message->getBlock(prehash("HeaderData"));
|
|
ensure_variable_attributes(
|
|
"RMAFI", block, "CompoundMsgID", MVT_LLUUID, 16);
|
|
ensure_variable_attributes(
|
|
"RMAFI", block, "TotalObjects", MVT_U8, 1);
|
|
ensure_variable_attributes(
|
|
"RMAFI", block, "FirstDetachAll", MVT_BOOL, 1);
|
|
|
|
|
|
ensure_block_attributes(
|
|
"RMAFI", message, "ObjectData", MBT_VARIABLE, 1, -1);
|
|
block = message->getBlock(prehash("ObjectData"));
|
|
ensure_variable_attributes("RMAFI", block, "ItemID", MVT_LLUUID, 16);
|
|
ensure_variable_attributes("RMAFI", block, "OwnerID", MVT_LLUUID, 16);
|
|
ensure_variable_attributes("RMAFI", block, "AttachmentPt", MVT_U8, 1);
|
|
ensure_variable_attributes("RMAFI", block, "ItemFlags", MVT_U32, 4);
|
|
ensure_variable_attributes("RMAFI", block, "GroupMask", MVT_U32, 4);
|
|
ensure_variable_attributes("RMAFI", block, "EveryoneMask", MVT_U32, 4);
|
|
ensure_variable_attributes("RMAFI", block, "NextOwnerMask", MVT_U32, 4);
|
|
ensure_variable_attributes("RMAFI", block, "Name", MVT_VARIABLE, 1);
|
|
ensure_variable_attributes("RMAFI", block, "Description", MVT_VARIABLE, 1);
|
|
|
|
delete message;
|
|
}
|
|
|
|
|
|
|
|
}
|