PageRenderTime 29ms CodeModel.GetById 17ms RepoModel.GetById 0ms 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
Possible License(s): LGPL-2.1
  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. #include "linden_common.h"
  28. #include "llmessagetemplateparser.h"
  29. #include "lltut.h"
  30. namespace tut
  31. {
  32. struct LLMessageTemplateParserTestData {
  33. LLMessageTemplateParserTestData() : mMessage("unset message")
  34. {
  35. }
  36. ~LLMessageTemplateParserTestData()
  37. {
  38. }
  39. void ensure_next(LLTemplateTokenizer & tokens,
  40. std::string value,
  41. U32 line)
  42. {
  43. std::string next = tokens.next();
  44. ensure_equals(mMessage + " token matches", next, value);
  45. ensure_equals(mMessage + " line matches", tokens.line(), line);
  46. }
  47. char * prehash(const char * name)
  48. {
  49. return LLMessageStringTable::getInstance()->getString(name);
  50. }
  51. void ensure_block_attributes(std::string identifier,
  52. const LLMessageTemplate * message,
  53. const char * name,
  54. EMsgBlockType type,
  55. S32 number,
  56. S32 total_size)
  57. {
  58. const LLMessageBlock * block = message->getBlock(prehash(name));
  59. identifier = identifier + ":" + message->mName + ":" + name + " block";
  60. ensure(identifier + " exists", block != NULL);
  61. ensure_equals(identifier + " name", block->mName, prehash(name));
  62. ensure_equals(identifier + " type", block->mType, type);
  63. ensure_equals(identifier + " number", block->mNumber, number);
  64. ensure_equals(identifier + " total size", block->mTotalSize, total_size);
  65. }
  66. void ensure_variable_attributes(std::string identifier,
  67. const LLMessageBlock * block,
  68. const char * name,
  69. EMsgVariableType type,
  70. S32 size)
  71. {
  72. const LLMessageVariable * var = block->getVariable(prehash(name));
  73. identifier = identifier + ":" + block->mName + ":" + name + " variable";
  74. ensure(identifier + " exists", var != NULL);
  75. ensure_equals(
  76. identifier + " name", var->getName(), prehash(name));
  77. ensure_equals(
  78. identifier + " type", var->getType(), type);
  79. ensure_equals(identifier + " size", var->getSize(), size);
  80. }
  81. std::string mMessage;
  82. };
  83. typedef test_group<LLMessageTemplateParserTestData> LLMessageTemplateParserTestGroup;
  84. typedef LLMessageTemplateParserTestGroup::object LLMessageTemplateParserTestObject;
  85. LLMessageTemplateParserTestGroup llMessageTemplateParserTestGroup("LLMessageTemplateParser");
  86. template<> template<>
  87. void LLMessageTemplateParserTestObject::test<1>()
  88. // tests tokenizer constructor and next methods
  89. {
  90. mMessage = "test method 1 walkthrough";
  91. LLTemplateTokenizer tokens("first line\nnext\t line\n\nfourth");
  92. ensure_next(tokens, "first", 1);
  93. ensure_next(tokens, "line", 1);
  94. ensure_next(tokens, "next", 2);
  95. ensure_next(tokens, "line", 2);
  96. ensure_next(tokens, "fourth", 4);
  97. tokens = LLTemplateTokenizer("\n\t{ \t Test1 Fixed \n 523 }\n\n");
  98. ensure(tokens.want("{"));
  99. ensure_next(tokens, "Test1", 2);
  100. ensure_next(tokens, "Fixed", 2);
  101. ensure_next(tokens, "523", 3);
  102. ensure(tokens.want("}"));
  103. tokens = LLTemplateTokenizer("first line\nnext\t line\n\nfourth");
  104. ensure(tokens.want("first"));
  105. ensure_next(tokens, "line", 1);
  106. ensure_next(tokens, "next", 2);
  107. ensure_next(tokens, "line", 2);
  108. ensure(tokens.want("fourth"));
  109. }
  110. template<> template<>
  111. void LLMessageTemplateParserTestObject::test<2>()
  112. // tests tokenizer want method
  113. {
  114. // *NOTE: order matters
  115. LLTemplateTokenizer tokens("first line\nnext\t line\n\nfourth");
  116. ensure_equals("wants first token", tokens.want("first"), true);
  117. ensure_equals("doesn't want blar token", tokens.want("blar"), false);
  118. ensure_equals("wants line token", tokens.want("line"), true);
  119. }
  120. template<> template<>
  121. void LLMessageTemplateParserTestObject::test<3>()
  122. // tests tokenizer eof methods
  123. {
  124. LLTemplateTokenizer tokens("single\n\n");
  125. ensure_equals("is not at eof at beginning", tokens.atEOF(), false);
  126. ensure_equals("doesn't want eof", tokens.wantEOF(), false);
  127. ensure_equals("wants the first token just to consume it",
  128. tokens.want("single"), true);
  129. ensure_equals("is not at eof in middle", tokens.atEOF(), false);
  130. ensure_equals("wants eof", tokens.wantEOF(), true);
  131. ensure_equals("is at eof at end", tokens.atEOF(), true);
  132. }
  133. template<> template<>
  134. void LLMessageTemplateParserTestObject::test<4>()
  135. // tests variable parsing method
  136. {
  137. LLTemplateTokenizer tokens(std::string("{ Test0 \n\t\n U32 \n\n }"));
  138. LLMessageVariable * var = LLTemplateParser::parseVariable(tokens);
  139. ensure("test0 var parsed", var != 0);
  140. ensure_equals("name of variable", std::string(var->getName()), std::string("Test0"));
  141. ensure_equals("type of variable is U32", var->getType(), MVT_U32);
  142. ensure_equals("size of variable", var->getSize(), 4);
  143. delete var;
  144. std::string message_string("\n\t{ \t Test1 Fixed \n 523 }\n\n");
  145. tokens = LLTemplateTokenizer(message_string);
  146. var = LLTemplateParser::parseVariable(tokens);
  147. ensure("test1 var parsed", var != 0);
  148. ensure_equals("name of variable", std::string(var->getName()), std::string("Test1"));
  149. ensure_equals("type of variable is Fixed", var->getType(), MVT_FIXED);
  150. ensure_equals("size of variable", var->getSize(), 523);
  151. delete var;
  152. // *NOTE: the parsers call llerrs on invalid input, so we can't really
  153. // test that :-(
  154. }
  155. template<> template<>
  156. void LLMessageTemplateParserTestObject::test<5>()
  157. // tests block parsing method
  158. {
  159. LLTemplateTokenizer tokens("{ BlockA Single { VarX F32 } }");
  160. LLMessageBlock * block = LLTemplateParser::parseBlock(tokens);
  161. ensure("blockA block parsed", block != 0);
  162. ensure_equals("name of block", std::string(block->mName), std::string("BlockA"));
  163. ensure_equals("type of block is Single", block->mType, MBT_SINGLE);
  164. ensure_equals("total size of block", block->mTotalSize, 4);
  165. ensure_equals("number of block defaults to 1", block->mNumber, 1);
  166. ensure_equals("variable type of VarX is F32",
  167. block->getVariableType(prehash("VarX")), MVT_F32);
  168. ensure_equals("variable size of VarX",
  169. block->getVariableSize(prehash("VarX")), 4);
  170. delete block;
  171. tokens = LLTemplateTokenizer("{ Stuff Variable { Id LLUUID } }");
  172. block = LLTemplateParser::parseBlock(tokens);
  173. ensure("stuff block parsed", block != 0);
  174. ensure_equals("name of block", std::string(block->mName), std::string("Stuff"));
  175. ensure_equals("type of block is Multiple", block->mType, MBT_VARIABLE);
  176. ensure_equals("total size of block", block->mTotalSize, 16);
  177. ensure_equals("number of block defaults to 1", block->mNumber, 1);
  178. ensure_equals("variable type of Id is LLUUID",
  179. block->getVariableType(prehash("Id")), MVT_LLUUID);
  180. ensure_equals("variable size of Id",
  181. block->getVariableSize(prehash("Id")), 16);
  182. delete block;
  183. tokens = LLTemplateTokenizer("{ Stuff2 Multiple 45 { Shid LLVector3d } }");
  184. block = LLTemplateParser::parseBlock(tokens);
  185. ensure("stuff2 block parsed", block != 0);
  186. ensure_equals("name of block", std::string(block->mName), std::string("Stuff2"));
  187. ensure_equals("type of block is Multiple", block->mType, MBT_MULTIPLE);
  188. ensure_equals("total size of block", block->mTotalSize, 24);
  189. ensure_equals("number of blocks", block->mNumber, 45);
  190. ensure_equals("variable type of Shid is Vector3d",
  191. block->getVariableType(prehash("Shid")), MVT_LLVector3d);
  192. ensure_equals("variable size of Shid",
  193. block->getVariableSize(prehash("Shid")), 24);
  194. delete block;
  195. }
  196. template<> template<>
  197. void LLMessageTemplateParserTestObject::test<6>()
  198. // tests message parsing method on a simple message
  199. {
  200. std::string message_skel(
  201. "{\n"
  202. "TestMessage Low 1 NotTrusted Zerocoded\n"
  203. "// comment \n"
  204. " {\n"
  205. "TestBlock1 Single\n"
  206. " { Test1 U32 }\n"
  207. " }\n"
  208. " {\n"
  209. " NeighborBlock Multiple 4\n"
  210. " { Test0 U32 }\n"
  211. " { Test1 U32 }\n"
  212. " { Test2 U32 }\n"
  213. " }\n"
  214. "}");
  215. LLTemplateTokenizer tokens(message_skel);
  216. LLMessageTemplate * message = LLTemplateParser::parseMessage(tokens);
  217. ensure("simple message parsed", message != 0);
  218. ensure_equals("name of message", std::string(message->mName), std::string("TestMessage"));
  219. ensure_equals("frequency is Low", message->mFrequency, MFT_LOW);
  220. ensure_equals("trust is untrusted", message->mTrust, MT_NOTRUST);
  221. ensure_equals("message number", message->mMessageNumber, (U32)((255 << 24) | (255 << 16) | 1));
  222. ensure_equals("message encoding is zerocoded", message->mEncoding, ME_ZEROCODED);
  223. ensure_equals("message deprecation is notdeprecated", message->mDeprecation, MD_NOTDEPRECATED);
  224. LLMessageBlock * block = message->getBlock(prehash("NonexistantBlock"));
  225. ensure("Nonexistant block does not exist", block == 0);
  226. delete message;
  227. }
  228. template<> template<>
  229. void LLMessageTemplateParserTestObject::test<7>()
  230. // tests message parsing method on a deprecated message
  231. {
  232. std::string message_skel(
  233. "{\n"
  234. "TestMessageDeprecated High 34 Trusted Unencoded Deprecated\n"
  235. " {\n"
  236. "TestBlock2 Single\n"
  237. " { Test2 S32 }\n"
  238. " }\n"
  239. "}");
  240. LLTemplateTokenizer tokens(message_skel);
  241. LLMessageTemplate * message = LLTemplateParser::parseMessage(tokens);
  242. ensure("deprecated message parsed", message != 0);
  243. ensure_equals("name of message", std::string(message->mName), std::string("TestMessageDeprecated"));
  244. ensure_equals("frequency is High", message->mFrequency, MFT_HIGH);
  245. ensure_equals("trust is trusted", message->mTrust, MT_TRUST);
  246. ensure_equals("message number", message->mMessageNumber, (U32)34);
  247. ensure_equals("message encoding is unencoded", message->mEncoding, ME_UNENCODED);
  248. ensure_equals("message deprecation is deprecated", message->mDeprecation, MD_DEPRECATED);
  249. delete message;
  250. }
  251. template<> template<> void LLMessageTemplateParserTestObject::test<8>()
  252. // tests message parsing on RezMultipleAttachmentsFromInv, a possibly-faulty message
  253. {
  254. std::string message_skel(
  255. "{\n\
  256. RezMultipleAttachmentsFromInv Low 452 NotTrusted Zerocoded\n\
  257. {\n\
  258. AgentData Single\n\
  259. { AgentID LLUUID }\n\
  260. { SessionID LLUUID }\n\
  261. } \n\
  262. {\n\
  263. HeaderData Single\n\
  264. { CompoundMsgID LLUUID } // All messages a single \"compound msg\" must have the same id\n\
  265. { TotalObjects U8 }\n\
  266. { FirstDetachAll BOOL }\n\
  267. }\n\
  268. {\n\
  269. ObjectData Variable // 1 to 4 of these per packet\n\
  270. { ItemID LLUUID }\n\
  271. { OwnerID LLUUID }\n\
  272. { AttachmentPt U8 } // 0 for default\n\
  273. { ItemFlags U32 }\n\
  274. { GroupMask U32 }\n\
  275. { EveryoneMask U32 }\n\
  276. { NextOwnerMask U32 }\n\
  277. { Name Variable 1 }\n\
  278. { Description Variable 1 }\n\
  279. }\n\
  280. }\n\
  281. ");
  282. LLTemplateTokenizer tokens(message_skel);
  283. LLMessageTemplate * message = LLTemplateParser::parseMessage(tokens);
  284. ensure("RezMultipleAttachmentsFromInv message parsed", message != 0);
  285. ensure_equals("name of message", message->mName, prehash("RezMultipleAttachmentsFromInv"));
  286. ensure_equals("frequency is low", message->mFrequency, MFT_LOW);
  287. ensure_equals("trust is not trusted", message->mTrust, MT_NOTRUST);
  288. ensure_equals("message number", message->mMessageNumber, (U32)((255 << 24) | (255 << 16) | 452));
  289. ensure_equals("message encoding is zerocoded", message->mEncoding, ME_ZEROCODED);
  290. ensure_block_attributes(
  291. "RMAFI", message, "AgentData", MBT_SINGLE, 1, 16+16);
  292. LLMessageBlock * block = message->getBlock(prehash("AgentData"));
  293. ensure_variable_attributes("RMAFI",
  294. block, "AgentID", MVT_LLUUID, 16);
  295. ensure_variable_attributes("RMAFI",
  296. block, "SessionID", MVT_LLUUID, 16);
  297. ensure_block_attributes(
  298. "RMAFI", message, "HeaderData", MBT_SINGLE, 1, 16+1+1);
  299. block = message->getBlock(prehash("HeaderData"));
  300. ensure_variable_attributes(
  301. "RMAFI", block, "CompoundMsgID", MVT_LLUUID, 16);
  302. ensure_variable_attributes(
  303. "RMAFI", block, "TotalObjects", MVT_U8, 1);
  304. ensure_variable_attributes(
  305. "RMAFI", block, "FirstDetachAll", MVT_BOOL, 1);
  306. ensure_block_attributes(
  307. "RMAFI", message, "ObjectData", MBT_VARIABLE, 1, -1);
  308. block = message->getBlock(prehash("ObjectData"));
  309. ensure_variable_attributes("RMAFI", block, "ItemID", MVT_LLUUID, 16);
  310. ensure_variable_attributes("RMAFI", block, "OwnerID", MVT_LLUUID, 16);
  311. ensure_variable_attributes("RMAFI", block, "AttachmentPt", MVT_U8, 1);
  312. ensure_variable_attributes("RMAFI", block, "ItemFlags", MVT_U32, 4);
  313. ensure_variable_attributes("RMAFI", block, "GroupMask", MVT_U32, 4);
  314. ensure_variable_attributes("RMAFI", block, "EveryoneMask", MVT_U32, 4);
  315. ensure_variable_attributes("RMAFI", block, "NextOwnerMask", MVT_U32, 4);
  316. ensure_variable_attributes("RMAFI", block, "Name", MVT_VARIABLE, 1);
  317. ensure_variable_attributes("RMAFI", block, "Description", MVT_VARIABLE, 1);
  318. delete message;
  319. }
  320. }