PageRenderTime 56ms CodeModel.GetById 1ms app.highlight 49ms RepoModel.GetById 2ms app.codeStats 0ms

/indra/test/llmessagetemplateparser_tut.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 368 lines | 283 code | 48 blank | 37 comment | 11 complexity | 5a853d70d15c82eee7249e616f232cd5 MD5 | raw file
  1/** 
  2 * @file llmessagetemplateparser_tut.cpp
  3 * @date April 2007
  4 * @brief LLMessageTemplateParser unit tests
  5 *
  6 * $LicenseInfo:firstyear=2006&license=viewerlgpl$
  7 * Second Life Viewer Source Code
  8 * Copyright (C) 2010, Linden Research, Inc.
  9 * 
 10 * This library is free software; you can redistribute it and/or
 11 * modify it under the terms of the GNU Lesser General Public
 12 * License as published by the Free Software Foundation;
 13 * version 2.1 of the License only.
 14 * 
 15 * This library is distributed in the hope that it will be useful,
 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 18 * Lesser General Public License for more details.
 19 * 
 20 * You should have received a copy of the GNU Lesser General Public
 21 * License along with this library; if not, write to the Free Software
 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 23 * 
 24 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 25 * $/LicenseInfo$
 26 */
 27
 28#include "linden_common.h"
 29#include "llmessagetemplateparser.h"
 30#include "lltut.h"
 31
 32namespace tut
 33{
 34	struct LLMessageTemplateParserTestData {
 35		LLMessageTemplateParserTestData() : mMessage("unset message")
 36		{
 37		}
 38
 39		~LLMessageTemplateParserTestData()
 40		{
 41		}
 42
 43		void ensure_next(LLTemplateTokenizer & tokens,
 44						 std::string value,
 45						 U32 line)
 46		{
 47			std::string next = tokens.next();
 48			ensure_equals(mMessage + " token matches", next, value);
 49			ensure_equals(mMessage + " line matches", tokens.line(), line);
 50		}
 51
 52		char * prehash(const char * name)
 53		{
 54			return LLMessageStringTable::getInstance()->getString(name);
 55		}
 56
 57		void ensure_block_attributes(std::string identifier,
 58									 const LLMessageTemplate * message,
 59									 const char * name,
 60									 EMsgBlockType type,
 61									 S32 number,
 62									 S32 total_size)
 63		{
 64			const LLMessageBlock * block = message->getBlock(prehash(name));
 65			identifier = identifier + ":" + message->mName + ":" + name + " block";
 66			ensure(identifier + " exists", block != NULL);
 67			ensure_equals(identifier + " name", block->mName, prehash(name));
 68			ensure_equals(identifier + " type", block->mType, type);
 69			ensure_equals(identifier + " number", block->mNumber, number);
 70			ensure_equals(identifier + " total size", block->mTotalSize, total_size);
 71		}
 72
 73		void ensure_variable_attributes(std::string identifier,
 74										const LLMessageBlock * block,
 75										const char * name,
 76										EMsgVariableType type,
 77										S32 size)
 78		{
 79			const LLMessageVariable * var = block->getVariable(prehash(name));
 80			identifier = identifier + ":" + block->mName + ":" + name + " variable";
 81			ensure(identifier + " exists", var != NULL);
 82			ensure_equals(
 83				identifier + " name", var->getName(), prehash(name));
 84			ensure_equals(
 85				identifier + " type", var->getType(), type);
 86			ensure_equals(identifier + " size", var->getSize(), size);
 87		}
 88		
 89		std::string mMessage;
 90			
 91	};
 92	
 93	typedef test_group<LLMessageTemplateParserTestData> LLMessageTemplateParserTestGroup;
 94	typedef LLMessageTemplateParserTestGroup::object LLMessageTemplateParserTestObject;
 95	LLMessageTemplateParserTestGroup llMessageTemplateParserTestGroup("LLMessageTemplateParser");
 96	
 97	template<> template<>
 98	void LLMessageTemplateParserTestObject::test<1>()
 99		// tests tokenizer constructor and next methods
100	{
101		mMessage = "test method 1 walkthrough";
102		LLTemplateTokenizer tokens("first line\nnext\t line\n\nfourth");
103		ensure_next(tokens, "first", 1);
104		ensure_next(tokens, "line", 1);
105		ensure_next(tokens, "next", 2);
106		ensure_next(tokens, "line", 2);
107		ensure_next(tokens, "fourth", 4);
108
109		tokens = LLTemplateTokenizer("\n\t{ \t   Test1 Fixed \n 523 }\n\n");
110		ensure(tokens.want("{"));
111		ensure_next(tokens, "Test1", 2);
112		ensure_next(tokens, "Fixed", 2);
113		ensure_next(tokens, "523", 3);
114		ensure(tokens.want("}"));
115
116		tokens = LLTemplateTokenizer("first line\nnext\t line\n\nfourth");
117		ensure(tokens.want("first"));
118		ensure_next(tokens, "line", 1);
119		ensure_next(tokens, "next", 2);
120		ensure_next(tokens, "line", 2);
121		ensure(tokens.want("fourth"));
122	}
123
124	template<> template<>
125	void LLMessageTemplateParserTestObject::test<2>()
126		// tests tokenizer want method
127	{
128		// *NOTE: order matters
129		LLTemplateTokenizer tokens("first line\nnext\t line\n\nfourth");
130		ensure_equals("wants first token", tokens.want("first"), true);
131		ensure_equals("doesn't want blar token", tokens.want("blar"), false);
132		ensure_equals("wants line token", tokens.want("line"), true);
133	}
134
135	template<> template<>
136	void LLMessageTemplateParserTestObject::test<3>()
137		// tests tokenizer eof methods
138	{
139		LLTemplateTokenizer tokens("single\n\n");
140		ensure_equals("is not at eof at beginning", tokens.atEOF(), false);
141		ensure_equals("doesn't want eof", tokens.wantEOF(), false);
142		ensure_equals("wants the first token just to consume it",
143					  tokens.want("single"), true);
144		ensure_equals("is not at eof in middle", tokens.atEOF(), false);
145		ensure_equals("wants eof", tokens.wantEOF(), true);
146		ensure_equals("is at eof at end", tokens.atEOF(), true);
147	}
148
149	template<> template<>
150	void LLMessageTemplateParserTestObject::test<4>()
151		// tests variable parsing method
152	{
153		LLTemplateTokenizer tokens(std::string("{    Test0  \n\t\n   U32 \n\n }"));
154		LLMessageVariable * var = LLTemplateParser::parseVariable(tokens);
155
156		ensure("test0 var parsed", var != 0);
157		ensure_equals("name of variable", std::string(var->getName()), std::string("Test0"));
158		ensure_equals("type of variable is U32", var->getType(), MVT_U32);
159		ensure_equals("size of variable", var->getSize(), 4);
160
161		delete var;
162
163		std::string message_string("\n\t{ \t   Test1 Fixed \n 523 }\n\n");
164		tokens = LLTemplateTokenizer(message_string);
165		var = LLTemplateParser::parseVariable(tokens);
166
167		ensure("test1 var parsed", var != 0);
168		ensure_equals("name of variable", std::string(var->getName()), std::string("Test1"));
169		ensure_equals("type of variable is Fixed", var->getType(), MVT_FIXED);
170		ensure_equals("size of variable", var->getSize(), 523);
171
172		delete var;
173	
174		// *NOTE: the parsers call llerrs on invalid input, so we can't really
175		// test that  :-(
176	}
177
178	template<> template<>
179	void LLMessageTemplateParserTestObject::test<5>()
180		// tests block parsing method
181	{
182		LLTemplateTokenizer tokens("{ BlockA Single { VarX F32 } }");
183		LLMessageBlock * block = LLTemplateParser::parseBlock(tokens);
184
185		ensure("blockA block parsed", block != 0);
186		ensure_equals("name of block", std::string(block->mName), std::string("BlockA"));
187		ensure_equals("type of block is Single", block->mType, MBT_SINGLE);
188		ensure_equals("total size of block", block->mTotalSize, 4);
189		ensure_equals("number of block defaults to 1", block->mNumber, 1);
190		ensure_equals("variable type of VarX is F32",
191					  block->getVariableType(prehash("VarX")), MVT_F32);
192		ensure_equals("variable size of VarX",
193					  block->getVariableSize(prehash("VarX")), 4);
194
195		delete block;
196
197		tokens = LLTemplateTokenizer("{ Stuff Variable { Id LLUUID } }");
198		block = LLTemplateParser::parseBlock(tokens);
199
200		ensure("stuff block parsed", block != 0);
201		ensure_equals("name of block", std::string(block->mName), std::string("Stuff"));
202		ensure_equals("type of block is Multiple", block->mType, MBT_VARIABLE);
203		ensure_equals("total size of block", block->mTotalSize, 16);
204		ensure_equals("number of block defaults to 1", block->mNumber, 1);
205		ensure_equals("variable type of Id is LLUUID",
206					  block->getVariableType(prehash("Id")), MVT_LLUUID);
207		ensure_equals("variable size of Id",
208					  block->getVariableSize(prehash("Id")), 16);
209
210		delete block;
211
212		tokens = LLTemplateTokenizer("{ Stuff2 Multiple 45 { Shid LLVector3d } }");
213		block = LLTemplateParser::parseBlock(tokens);
214
215		ensure("stuff2 block parsed", block != 0);
216		ensure_equals("name of block", std::string(block->mName), std::string("Stuff2"));
217		ensure_equals("type of block is Multiple", block->mType, MBT_MULTIPLE);
218		ensure_equals("total size of block", block->mTotalSize, 24);
219		ensure_equals("number of blocks", block->mNumber, 45);
220		ensure_equals("variable type of Shid is Vector3d",
221					  block->getVariableType(prehash("Shid")), MVT_LLVector3d);
222		ensure_equals("variable size of Shid",
223					  block->getVariableSize(prehash("Shid")), 24);
224
225		delete block;		
226	}
227
228	template<> template<>
229	void LLMessageTemplateParserTestObject::test<6>()
230		// tests message parsing method on a simple message
231	{
232		std::string message_skel(
233			"{\n"
234			"TestMessage Low 1 NotTrusted Zerocoded\n"
235			"// comment \n"
236			"  {\n"
237			"TestBlock1      Single\n"
238			"      {   Test1       U32 }\n"
239			"  }\n"
240			"  {\n"
241			"      NeighborBlock       Multiple        4\n"
242			"      {   Test0       U32 }\n"
243			"      {   Test1       U32 }\n"
244			"      {   Test2       U32 }\n"
245			"  }\n"
246			"}");
247		LLTemplateTokenizer tokens(message_skel);
248		LLMessageTemplate * message = LLTemplateParser::parseMessage(tokens);
249
250		ensure("simple message parsed", message != 0);
251		ensure_equals("name of message", std::string(message->mName), std::string("TestMessage"));
252		ensure_equals("frequency is Low", message->mFrequency, MFT_LOW);
253		ensure_equals("trust is untrusted", message->mTrust, MT_NOTRUST);
254		ensure_equals("message number", message->mMessageNumber, (U32)((255 << 24) | (255 << 16) | 1));
255		ensure_equals("message encoding is zerocoded", message->mEncoding, ME_ZEROCODED);
256		ensure_equals("message deprecation is notdeprecated", message->mDeprecation, MD_NOTDEPRECATED);
257
258		LLMessageBlock * block = message->getBlock(prehash("NonexistantBlock"));
259		ensure("Nonexistant block does not exist", block == 0);
260		
261		delete message;
262	}
263
264		template<> template<>
265	void LLMessageTemplateParserTestObject::test<7>()
266		// tests message parsing method on a deprecated message
267	{
268		std::string message_skel(
269			"{\n"
270			"TestMessageDeprecated High 34 Trusted Unencoded Deprecated\n"
271			"  {\n"
272			"TestBlock2      Single\n"
273			"      {   Test2       S32 }\n"
274			"  }\n"
275			"}");
276		LLTemplateTokenizer tokens(message_skel);
277		LLMessageTemplate * message = LLTemplateParser::parseMessage(tokens);
278		
279		ensure("deprecated message parsed", message != 0);
280		ensure_equals("name of message", std::string(message->mName), std::string("TestMessageDeprecated"));
281		ensure_equals("frequency is High", message->mFrequency, MFT_HIGH);
282		ensure_equals("trust is trusted", message->mTrust, MT_TRUST);
283		ensure_equals("message number", message->mMessageNumber, (U32)34);
284		ensure_equals("message encoding is unencoded", message->mEncoding, ME_UNENCODED);
285		ensure_equals("message deprecation is deprecated", message->mDeprecation, MD_DEPRECATED);
286
287		delete message;
288	}
289
290	template<> template<> void LLMessageTemplateParserTestObject::test<8>()
291		// tests message parsing on RezMultipleAttachmentsFromInv, a possibly-faulty message
292	{
293		std::string message_skel(
294			"{\n\
295				RezMultipleAttachmentsFromInv Low 452 NotTrusted Zerocoded\n\
296				{\n\
297					AgentData			Single\n\
298					{	AgentID			LLUUID	}\n\
299					{	SessionID		LLUUID	}\n\
300				}	\n\
301				{\n\
302					HeaderData			Single\n\
303					{	CompoundMsgID			LLUUID  }	// All messages a single \"compound msg\" must have the same id\n\
304					{	TotalObjects			U8	}\n\
305					{	FirstDetachAll			BOOL	}\n\
306				}\n\
307				{\n\
308					ObjectData			Variable		// 1 to 4 of these per packet\n\
309					{	ItemID					LLUUID	}\n\
310					{	OwnerID					LLUUID	}\n\
311					{	AttachmentPt			U8	}	// 0 for default\n\
312					{	ItemFlags				U32 }\n\
313					{	GroupMask				U32 }\n\
314					{	EveryoneMask			U32 }\n\
315					{	NextOwnerMask			U32	}\n\
316					{	Name					Variable	1	}\n\
317					{	Description				Variable	1	}\n\
318				}\n\
319			}\n\
320			");
321		LLTemplateTokenizer tokens(message_skel);
322		LLMessageTemplate * message = LLTemplateParser::parseMessage(tokens);
323
324		ensure("RezMultipleAttachmentsFromInv message parsed", message != 0);
325		ensure_equals("name of message", message->mName, prehash("RezMultipleAttachmentsFromInv"));
326		ensure_equals("frequency is low", message->mFrequency, MFT_LOW);
327		ensure_equals("trust is not trusted", message->mTrust, MT_NOTRUST);
328		ensure_equals("message number", message->mMessageNumber, (U32)((255 << 24) | (255 << 16) | 452));
329		ensure_equals("message encoding is zerocoded", message->mEncoding, ME_ZEROCODED);
330
331		ensure_block_attributes(
332			"RMAFI", message, "AgentData", MBT_SINGLE, 1, 16+16);
333		LLMessageBlock * block = message->getBlock(prehash("AgentData"));
334		ensure_variable_attributes("RMAFI",
335								   block, "AgentID", MVT_LLUUID, 16);
336		ensure_variable_attributes("RMAFI",
337								   block, "SessionID", MVT_LLUUID, 16);
338		
339		ensure_block_attributes(
340			"RMAFI", message, "HeaderData", MBT_SINGLE, 1, 16+1+1);
341		block = message->getBlock(prehash("HeaderData"));
342		ensure_variable_attributes(
343			"RMAFI", block, "CompoundMsgID", MVT_LLUUID, 16);
344		ensure_variable_attributes(
345			"RMAFI", block, "TotalObjects", MVT_U8, 1);
346		ensure_variable_attributes(
347			"RMAFI", block, "FirstDetachAll", MVT_BOOL, 1);
348
349
350		ensure_block_attributes(
351			"RMAFI", message, "ObjectData", MBT_VARIABLE, 1, -1);
352		block = message->getBlock(prehash("ObjectData"));
353		ensure_variable_attributes("RMAFI", block, "ItemID", MVT_LLUUID, 16);
354		ensure_variable_attributes("RMAFI", block, "OwnerID", MVT_LLUUID, 16);
355		ensure_variable_attributes("RMAFI", block, "AttachmentPt", MVT_U8, 1);
356		ensure_variable_attributes("RMAFI", block, "ItemFlags", MVT_U32, 4);
357		ensure_variable_attributes("RMAFI", block, "GroupMask", MVT_U32, 4);
358		ensure_variable_attributes("RMAFI", block, "EveryoneMask", MVT_U32, 4);
359		ensure_variable_attributes("RMAFI", block, "NextOwnerMask", MVT_U32, 4);
360		ensure_variable_attributes("RMAFI", block, "Name", MVT_VARIABLE, 1);
361		ensure_variable_attributes("RMAFI", block, "Description", MVT_VARIABLE, 1);
362
363		delete message;
364	}
365
366	
367
368}