llmediadataclient_test.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:34k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llmediadataclient_test.cpp
  3.  * @brief LLMediaDatClient tests
  4.  *
  5.  * $LicenseInfo:firstyear=2001&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2001-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "linden_common.h"
  33. #include "../llviewerprecompiledheaders.h"
  34.  
  35. #include <iostream>
  36. #include "../test/lltut.h"
  37. #include "llsdserialize.h"
  38. #include "llsdutil.h"
  39. #include "llerrorcontrol.h"
  40. #include "llhttpstatuscodes.h"
  41. #include "../llmediadataclient.h"
  42. #include "../llvovolume.h"
  43. #include "../../llprimitive/llmediaentry.cpp"
  44. #include "../../llprimitive/lltextureentry.cpp"
  45. #include "../../llmessage/tests/llcurl_stub.cpp"
  46. #if LL_WINDOWS
  47. #pragma warning (push)
  48. #pragma warning (disable : 4702) // boost::lexical_cast generates this warning
  49. #endif
  50. #include <boost/lexical_cast.hpp>
  51. #if LL_WINDOWS
  52. #pragma warning (pop)
  53. #endif
  54. #define VALID_OBJECT_ID   "3607d5c4-644b-4a8a-871a-8b78471af2a2"
  55. #define VALID_OBJECT_ID_1 "11111111-1111-1111-1111-111111111111"
  56. #define VALID_OBJECT_ID_2 "22222222-2222-2222-2222-222222222222"
  57. #define VALID_OBJECT_ID_3 "33333333-3333-3333-3333-333333333333"
  58. #define VALID_OBJECT_ID_4 "44444444-4444-4444-4444-444444444444"
  59. #define FAKE_OBJECT_MEDIA_CAP_URL "foo_ObjectMedia"
  60. #define FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL "foo_ObjectMediaNavigate"
  61. #define FAKE_OBJECT_MEDIA_CAP_URL_503 "foo_ObjectMedia_503"
  62. #define FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL_ERROR "foo_ObjectMediaNavigate_ERROR"
  63. #define MEDIA_DATA "
  64. <array>
  65. <string>foo</string>
  66. <string>bar</string>
  67. <string>baz</string>
  68. </array>"
  69. #define _DATA_URLS(ID,INTEREST,NEW,URL1,URL2) "
  70. <llsd>
  71.   <map>
  72.     <key>uuid</key>
  73.     <string>" ID "</string>
  74.     <key>interest</key>
  75.     <real>" INTEREST "</real>
  76.     <key>cap_urls</key>
  77.     <map>
  78.       <key>ObjectMedia</key>
  79.       <string>" URL1 "</string>
  80.       <key>ObjectMediaNavigate</key>
  81.       <string>" URL2 "</string>
  82.     </map>
  83.     <key>media_data</key>                                       
  84. " MEDIA_DATA "
  85.     <key>is_dead</key>
  86. <boolean>false</boolean>
  87. <key>is_new</key>
  88. <boolean>" NEW "</boolean>
  89.   </map>
  90. </llsd>"
  91. #define _DATA(ID,INTEREST,NEW) _DATA_URLS(ID,INTEREST,NEW,FAKE_OBJECT_MEDIA_CAP_URL,FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL)
  92. const char *DATA = _DATA(VALID_OBJECT_ID,"1.0","true");
  93. #define STR(I) boost::lexical_cast<std::string>(I)
  94. #define LOG_TEST(N) LL_DEBUGS("LLMediaDataClient") << "n" <<
  95. "================================================================================n" << 
  96. "==================================== TEST " #N " ===================================n" << 
  97. "================================================================================n" << LL_ENDL;
  98. LLSD *gPostRecords = NULL;
  99. F64   gMinimumInterestLevel = (F64)0.0;
  100. // stubs:
  101. void LLHTTPClient::post(
  102. const std::string& url,
  103. const LLSD& body,
  104. LLHTTPClient::ResponderPtr responder,
  105. const LLSD& headers,
  106. const F32 timeout)
  107. {
  108. LLSD record;
  109. record["url"] = url;
  110. record["body"] = body;
  111. record["headers"] = headers;
  112. record["timeout"] = timeout;
  113. gPostRecords->append(record);
  114. // Magic URL that triggers a 503:
  115. LLSD result;
  116. result[LLTextureEntry::OBJECT_ID_KEY] = body[LLTextureEntry::OBJECT_ID_KEY];
  117. if ( url == FAKE_OBJECT_MEDIA_CAP_URL_503 )
  118. {
  119. responder->error(HTTP_SERVICE_UNAVAILABLE, "fake reason");
  120. return;
  121. }
  122. else if (url == FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL_ERROR) 
  123. {
  124. LLSD error;
  125. error["code"] = LLObjectMediaNavigateClient::ERROR_PERMISSION_DENIED_CODE;
  126. result["error"] = error;
  127. }
  128. responder->result(result);
  129. }
  130. const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f;
  131. class LLMediaDataClientObjectTest : public LLMediaDataClientObject
  132. {
  133. public:
  134. LLMediaDataClientObjectTest(const char *data) 
  135. {
  136. std::istringstream d(data);
  137. LLSDSerialize::fromXML(mRep, d);
  138. mNumBounceBacks = 0;
  139.             
  140.            // std::cout << ll_pretty_print_sd(mRep) << std::endl;
  141.            // std::cout << "ID: " << getID() << std::endl;
  142. }
  143. LLMediaDataClientObjectTest(const LLSD &rep) 
  144. : mRep(rep), mNumBounceBacks(0) {}
  145. ~LLMediaDataClientObjectTest()
  146. { LL_DEBUGS("LLMediaDataClient") << "~LLMediaDataClientObjectTest" << LL_ENDL; }
  147. virtual U8 getMediaDataCount() const 
  148. { return mRep["media_data"].size(); }
  149. virtual LLSD getMediaDataLLSD(U8 index) const
  150. { return mRep["media_data"][(LLSD::Integer)index]; }
  151. virtual LLUUID getID() const 
  152. { return mRep["uuid"]; }
  153. virtual void mediaNavigateBounceBack(U8 index)
  154. { mNumBounceBacks++; }
  155. virtual bool hasMedia() const
  156. { return mRep.has("media_data"); }
  157. virtual void updateObjectMediaData(LLSD const &media_data_array, const std::string &media_version)
  158. { mRep["media_data"] = media_data_array; mRep["media_version"] = media_version; }
  159. virtual F64 getMediaInterest() const
  160. { return (LLSD::Real)mRep["interest"]; }
  161. virtual bool isInterestingEnough() const
  162. { return getMediaInterest() > gMinimumInterestLevel; }
  163. virtual std::string getCapabilityUrl(const std::string &name) const 
  164. { return mRep["cap_urls"][name]; }
  165. virtual bool isDead() const
  166. { return mRep["is_dead"]; }
  167. virtual U32 getMediaVersion() const
  168. { return (LLSD::Integer)mRep["media_version"]; }
  169. virtual bool isNew() const
  170. { return mRep["is_new"]; }
  171. void setMediaInterest(F64 val)
  172. { mRep["interest"] = val; }
  173. int getNumBounceBacks() const
  174. { return mNumBounceBacks; }
  175. void markDead()
  176. { mRep["is_dead"] = true; }
  177. void markOld()
  178. { mRep["is_new"] = false; }
  179. private:
  180. LLSD mRep;
  181. int mNumBounceBacks;
  182. };
  183. // This special timer delay should ensure that the timer will fire on the very
  184. // next pump, no matter what (though this does make an assumption about the
  185. // implementation of LLEventTimer::updateClass()):
  186. const F32 NO_PERIOD = -1000.0f;
  187. static void pump_timers()
  188. {
  189. LLEventTimer::updateClass();
  190. }
  191. namespace tut
  192. {
  193.     struct mediadataclient
  194.     {
  195. mediadataclient() {
  196. gPostRecords = &mLLSD;
  197. gMinimumInterestLevel = (F64)0.0;
  198. //  LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
  199. //  LLError::setClassLevel("LLMediaDataClient", LLError::LEVEL_DEBUG);
  200. // LLError::setTagLevel("MediaOnAPrim", LLError::LEVEL_DEBUG);
  201. }
  202. LLSD mLLSD;
  203.     };
  204.     
  205. typedef test_group<mediadataclient> mediadataclient_t;
  206. typedef mediadataclient_t::object mediadataclient_object_t;
  207. tut::mediadataclient_t tut_mediadataclient("mediadataclient");
  208.     
  209.     void ensure(const std::string &msg, int value, int expected)
  210.     {
  211.         std::string m = msg;
  212.         m += " value: " + STR(value);
  213.         m += ", expected: " + STR(expected);
  214.         ensure(m, value == expected);
  215.     }
  216.     
  217.     void ensure(const std::string &msg, const std::string & value, const std::string & expected)
  218.     {
  219.         std::string m = msg;
  220.         m += " value: " + value;
  221.         m += ", expected: " + expected;
  222.         ensure(m, value == expected);
  223.     }
  224.     
  225.     void ensure(const std::string &msg, const LLUUID & value, const LLUUID & expected)
  226.     {
  227.         std::string m = msg;
  228.         m += " value: " + value.asString();
  229.         m += ", expected: " + expected.asString();
  230.         ensure(m, value == expected);
  231.     }
  232.     
  233.     void ensure_llsd(const std::string &msg, const LLSD & value, const char *expected)
  234.     {
  235.         LLSD expected_llsd;
  236.         std::istringstream e(expected);
  237.         LLSDSerialize::fromXML(expected_llsd, e);
  238.    
  239.         std::string value_str = ll_pretty_print_sd(value);
  240.         std::string expected_str = ll_pretty_print_sd(expected_llsd);
  241.         std::string m = msg;
  242.         m += " value: " + value_str;
  243.         m += ", expected: " + expected_str;
  244.         ensure(m, value_str == expected_str);
  245.     }
  246. //////////////////////////////////////////////////////////////////////////////////////////
  247. template<> template<>
  248. void mediadataclient_object_t::test<1>()
  249. {
  250. //
  251. // Test fetchMedia()
  252. //
  253. LOG_TEST(1);
  254. LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest(DATA);
  255. int num_refs_start = o->getNumRefs();
  256. {
  257. LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
  258. mdc->fetchMedia(o);
  259. // Make sure no posts happened yet...
  260. ensure("post records", gPostRecords->size(), 0);
  261. ::pump_timers();
  262. ensure("post records", gPostRecords->size(), 1);
  263. ensure("post url", (*gPostRecords)[0]["url"], FAKE_OBJECT_MEDIA_CAP_URL);
  264. ensure("post GET", (*gPostRecords)[0]["body"]["verb"], "GET");
  265. ensure("post object id", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID));
  266. ensure("queue empty", mdc->isEmpty());
  267. }
  268. // Make sure everyone's destroyed properly
  269. ensure("REF COUNT", o->getNumRefs(), num_refs_start);
  270.     }
  271. //////////////////////////////////////////////////////////////////////////////////////////
  272. template<> template<>
  273. void mediadataclient_object_t::test<2>()
  274. {
  275. //
  276. // Test updateMedia()
  277. //
  278. LOG_TEST(2);
  279. LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest(DATA);
  280. {
  281. // queue time w/ no delay ensures that ::pump_timers() will hit the tick()
  282. LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);  
  283. mdc->updateMedia(o);
  284. ensure("post records", gPostRecords->size(), 0);
  285. ::pump_timers();
  286. ensure("post records", gPostRecords->size(), 1);
  287. ensure("post url", (*gPostRecords)[0]["url"], FAKE_OBJECT_MEDIA_CAP_URL);
  288. ensure("post UPDATE", (*gPostRecords)[0]["body"]["verb"], "UPDATE");
  289. ensure("post object id", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID));
  290. ensure_llsd("post data llsd", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_MEDIA_DATA_KEY], 
  291. "<llsd>" MEDIA_DATA "</llsd>");
  292. ensure("queue empty", mdc->isEmpty());
  293. }
  294. ensure("REF COUNT", o->getNumRefs(), 1);
  295. }
  296. //////////////////////////////////////////////////////////////////////////////////////////
  297.     template<> template<>
  298.     void mediadataclient_object_t::test<3>()
  299.     {
  300. //
  301. // Test navigate()
  302. //
  303. LOG_TEST(3);
  304. LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest(DATA);
  305. {
  306. LLPointer<LLObjectMediaNavigateClient> mdc = new LLObjectMediaNavigateClient(NO_PERIOD,NO_PERIOD);
  307. const char *TEST_URL = "http://example.com";
  308. mdc->navigate(o, 0, TEST_URL);
  309. ensure("post records", gPostRecords->size(), 0);
  310. ::pump_timers();
  311. // ensure no bounce back
  312. ensure("bounce back", dynamic_cast<LLMediaDataClientObjectTest*>(static_cast<LLMediaDataClientObject*>(o))->getNumBounceBacks(), 0);
  313. ensure("post records", gPostRecords->size(), 1);
  314. ensure("post url", (*gPostRecords)[0]["url"], FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL);
  315. ensure("post object id", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID));
  316. ensure("post data", (*gPostRecords)[0]["body"][LLTextureEntry::TEXTURE_INDEX_KEY], 0);
  317. ensure("post data", (*gPostRecords)[0]["body"][LLMediaEntry::CURRENT_URL_KEY], TEST_URL);
  318. ensure("queue empty", mdc->isEmpty());
  319. }
  320. ensure("REF COUNT", o->getNumRefs(), 1);
  321.     }
  322. //////////////////////////////////////////////////////////////////////////////////////////
  323.     template<> template<>
  324.     void mediadataclient_object_t::test<4>()
  325.     {
  326. //
  327. // Test queue ordering
  328. //
  329. LOG_TEST(4);
  330. LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(
  331. _DATA(VALID_OBJECT_ID_1,"1.0","true"));
  332. LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(
  333. _DATA(VALID_OBJECT_ID_2,"3.0","true"));
  334. LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(
  335. _DATA(VALID_OBJECT_ID_3,"2.0","true"));
  336. {
  337. LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);  
  338. const char *ORDERED_OBJECT_IDS[] = { VALID_OBJECT_ID_2, VALID_OBJECT_ID_3, VALID_OBJECT_ID_1 };
  339. mdc->fetchMedia(o1);
  340. mdc->fetchMedia(o2);
  341. mdc->fetchMedia(o3);
  342. // Make sure no posts happened yet...
  343. ensure("post records", gPostRecords->size(), 0);
  344. // tick 3 times...
  345. ::pump_timers();
  346. ensure("post records", gPostRecords->size(), 1);
  347. ::pump_timers();
  348. ensure("post records", gPostRecords->size(), 2);
  349. ::pump_timers();
  350. ensure("post records", gPostRecords->size(), 3);
  351. for( int i=0; i < 3; i++ )
  352. {
  353. ensure("[" + STR(i) + "] post url", (*gPostRecords)[i]["url"], FAKE_OBJECT_MEDIA_CAP_URL);
  354. ensure("[" + STR(i) + "] post GET", (*gPostRecords)[i]["body"]["verb"], "GET");
  355. ensure("[" + STR(i) + "] post object id", (*gPostRecords)[i]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), 
  356.    LLUUID(ORDERED_OBJECT_IDS[i]));
  357. }
  358. ensure("queue empty", mdc->isEmpty());
  359. }
  360. ensure("refcount of o1", o1->getNumRefs(), 1);
  361. ensure("refcount of o2", o2->getNumRefs(), 1);
  362. ensure("refcount of o3", o3->getNumRefs(), 1);
  363.     }
  364. //////////////////////////////////////////////////////////////////////////////////////////
  365. template<> template<>
  366. void mediadataclient_object_t::test<5>()
  367. {
  368. //
  369. // Test fetchMedia() getting a 503 error
  370. //
  371. LOG_TEST(5);
  372. LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest(
  373. _DATA_URLS(VALID_OBJECT_ID,
  374.    "1.0","true",
  375.    FAKE_OBJECT_MEDIA_CAP_URL_503,
  376.    FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL));
  377. int num_refs_start = o->getNumRefs();
  378. {
  379. const int NUM_RETRIES = 5;
  380. LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD,NUM_RETRIES);
  381. // This should generate a retry
  382. mdc->fetchMedia(o);
  383. // Make sure no posts happened yet...
  384. ensure("post records before", gPostRecords->size(), 0);
  385. // Once, causes retry
  386. // Second, fires retry timer
  387. // Third, fires queue timer again
  388. for (int i=0; i<NUM_RETRIES; ++i)
  389. {
  390. ::pump_timers();  // Should pump (fire) the queue timer, causing a retry timer to be scheduled
  391. // XXX This ensure is not guaranteed, because scheduling a timer might actually get it pumped in the same loop
  392. //ensure("post records " + STR(i), gPostRecords->size(), i+1);
  393. ::pump_timers();  // Should pump (fire) the retry timer, scheduling the queue timer
  394. }
  395. // Do some extra pumps to make sure no other timer work occurs.
  396. ::pump_timers();
  397. ::pump_timers();
  398. ::pump_timers();
  399. // Make sure there were 2 posts
  400. ensure("post records after", gPostRecords->size(), NUM_RETRIES);
  401. for (int i=0; i<NUM_RETRIES; ++i)
  402. {
  403. ensure("[" + STR(i) + "] post url", (*gPostRecords)[i]["url"], FAKE_OBJECT_MEDIA_CAP_URL_503);
  404. ensure("[" + STR(i) + "] post GET", (*gPostRecords)[i]["body"]["verb"], "GET");
  405. ensure("[" + STR(i) + "] post object id", (*gPostRecords)[i]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID));
  406. }
  407. ensure("queue empty", mdc->isEmpty());
  408. }
  409. // Make sure everyone's destroyed properly
  410. ensure("REF COUNT", o->getNumRefs(), num_refs_start);
  411.     }
  412.     template<> template<>
  413.     void mediadataclient_object_t::test<6>()
  414.     {
  415. //
  416. // Test navigate() with a bounce back
  417. //
  418. LOG_TEST(6);
  419. LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest(
  420. _DATA_URLS(VALID_OBJECT_ID,
  421.    "1.0","true",
  422.    FAKE_OBJECT_MEDIA_CAP_URL,
  423.    FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL_ERROR));
  424. {
  425. LLPointer<LLObjectMediaNavigateClient> mdc = new LLObjectMediaNavigateClient(NO_PERIOD,NO_PERIOD);
  426. const char *TEST_URL = "http://example.com";
  427. mdc->navigate(o, 0, TEST_URL);
  428. ensure("post records", gPostRecords->size(), 0);
  429. ::pump_timers();
  430. // ensure bounce back
  431. ensure("bounce back", 
  432.    dynamic_cast<LLMediaDataClientObjectTest*>(static_cast<LLMediaDataClientObject*>(o))->getNumBounceBacks(),
  433.    1);
  434. ensure("post records", gPostRecords->size(), 1);
  435. ensure("post url", (*gPostRecords)[0]["url"], FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL_ERROR);
  436. ensure("post object id", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID));
  437. ensure("post data", (*gPostRecords)[0]["body"][LLTextureEntry::TEXTURE_INDEX_KEY], 0);
  438. ensure("post data", (*gPostRecords)[0]["body"][LLMediaEntry::CURRENT_URL_KEY], TEST_URL);
  439. ensure("queue empty", mdc->isEmpty());
  440. }
  441. ensure("REF COUNT", o->getNumRefs(), 1);
  442.     }
  443. template<> template<>
  444.     void mediadataclient_object_t::test<7>()
  445.     {
  446. // Test LLMediaDataClient::isInQueue()
  447. LOG_TEST(7);
  448. LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(
  449. _DATA(VALID_OBJECT_ID_1,"3.0","true"));
  450. LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(
  451. _DATA(VALID_OBJECT_ID_2,"1.0","true"));
  452. int num_refs_start = o1->getNumRefs();
  453. {
  454. LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
  455. ensure("not in queue yet 1", ! mdc->isInQueue(o1));
  456. ensure("not in queue yet 2", ! mdc->isInQueue(o2));
  457. mdc->fetchMedia(o1);
  458. ensure("is in queue", mdc->isInQueue(o1));
  459. ensure("is not in queue", ! mdc->isInQueue(o2));
  460. ::pump_timers();
  461. ensure("not in queue anymore", ! mdc->isInQueue(o1));
  462. ensure("still is not in queue", ! mdc->isInQueue(o2));
  463. ensure("queue empty", mdc->isEmpty());
  464. }
  465. // Make sure everyone's destroyed properly
  466. ensure("REF COUNT", o1->getNumRefs(), num_refs_start);
  467. }
  468. template<> template<>
  469.     void mediadataclient_object_t::test<8>()
  470.     {
  471. // Test queue handling of objects that are marked dead.
  472. LOG_TEST(8);
  473. LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"4.0","true"));
  474. LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_2,"3.0","true"));
  475. LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_3,"2.0","true"));
  476. LLMediaDataClientObject::ptr_t o4 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_4,"1.0","true"));
  477. {
  478. LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
  479. // queue up all 4 objects
  480. mdc->fetchMedia(o1);
  481. mdc->fetchMedia(o2);
  482. mdc->fetchMedia(o3);
  483. mdc->fetchMedia(o4);
  484. // and mark the second and fourth ones dead.
  485. dynamic_cast<LLMediaDataClientObjectTest*>(static_cast<LLMediaDataClientObject*>(o2))->markDead();
  486. dynamic_cast<LLMediaDataClientObjectTest*>(static_cast<LLMediaDataClientObject*>(o4))->markDead();
  487. ensure("is in queue 1", mdc->isInQueue(o1));
  488. ensure("is in queue 2", mdc->isInQueue(o2));
  489. ensure("is in queue 3", mdc->isInQueue(o3));
  490. ensure("is in queue 4", mdc->isInQueue(o4));
  491. ensure("post records", gPostRecords->size(), 0);
  492. ::pump_timers();
  493. // The first tick should remove the first one 
  494. ensure("is not in queue 1", !mdc->isInQueue(o1));
  495. ensure("is in queue 2", mdc->isInQueue(o2));
  496. ensure("is in queue 3", mdc->isInQueue(o3));
  497. ensure("is in queue 4", mdc->isInQueue(o4));
  498. ensure("post records", gPostRecords->size(), 1);
  499. ::pump_timers();
  500. // The second tick should skip the second and remove the third
  501. ensure("is not in queue 2", !mdc->isInQueue(o2));
  502. ensure("is not in queue 3", !mdc->isInQueue(o3));
  503. ensure("is in queue 4", mdc->isInQueue(o4));
  504. ensure("post records", gPostRecords->size(), 2);
  505. ::pump_timers();
  506. // The third tick should skip the fourth one and empty the queue.
  507. ensure("is not in queue 4", !mdc->isInQueue(o4));
  508. ensure("post records", gPostRecords->size(), 2);
  509. ensure("queue empty", mdc->isEmpty());
  510. }
  511. ensure("refcount of o1", o1->getNumRefs(), 1);
  512. ensure("refcount of o2", o2->getNumRefs(), 1);
  513. ensure("refcount of o3", o3->getNumRefs(), 1);
  514. ensure("refcount of o4", o4->getNumRefs(), 1);
  515. }
  516. //////////////////////////////////////////////////////////////////////////////////////////
  517.     template<> template<>
  518.     void mediadataclient_object_t::test<9>()
  519.     {
  520. //
  521. // Test queue re-ordering
  522. //
  523. LOG_TEST(9);
  524. LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"40.0","true"));
  525. LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_2,"30.0","true"));
  526. LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_3,"20.0","true"));
  527. LLMediaDataClientObjectTest *object4 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_4,"10.0","true"));
  528. LLMediaDataClientObject::ptr_t o4 = object4;
  529. {
  530. LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
  531. // queue up all 4 objects.  They should now be in the queue in
  532. // order 1 through 4, with 4 being at the front of the queue
  533. mdc->fetchMedia(o1);
  534. mdc->fetchMedia(o2);
  535. mdc->fetchMedia(o3);
  536. mdc->fetchMedia(o4);
  537. int tick_num = 0;
  538. ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
  539. ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
  540. ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
  541. ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
  542. ensure(STR(tick_num) + ". post records", gPostRecords->size(), 0);
  543. ::pump_timers();
  544. ++tick_num;
  545. // The first tick should remove the first one 
  546. ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1));
  547. ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
  548. ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
  549. ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
  550. ensure(STR(tick_num) + ". post records", gPostRecords->size(), 1);
  551. // Now, pretend that object 4 moved relative to the avatar such
  552. // that it is now closest
  553. object4->setMediaInterest(50.0);
  554. ::pump_timers();
  555. ++tick_num;
  556. // The second tick should still pick off item 2, but then re-sort
  557. // have picked off object 4
  558. ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
  559. ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
  560. ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
  561. ensure(STR(tick_num) + ". post records", gPostRecords->size(), 2);
  562. ::pump_timers();
  563. ++tick_num;
  564. // The third tick should pick off object 2
  565. ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2));
  566. ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
  567. ensure(STR(tick_num) + ". post records", gPostRecords->size(), 3);
  568. // The fourth tick should pick off object 3
  569. ::pump_timers();
  570. ++tick_num;
  571. ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
  572. ensure(STR(tick_num) + ". post records", gPostRecords->size(), 4);
  573. ensure("queue empty", mdc->isEmpty());
  574. }
  575. ensure("refcount of o1", o1->getNumRefs(), 1);
  576. ensure("refcount of o2", o2->getNumRefs(), 1);
  577. ensure("refcount of o3", o3->getNumRefs(), 1);
  578. ensure("refcount of o4", o4->getNumRefs(), 1);
  579.     }
  580. template<> template<>
  581.     void mediadataclient_object_t::test<10>()
  582.     {
  583. //
  584. // Test using the "round-robin" queue
  585. //
  586. LOG_TEST(10);
  587. LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"1.0","true"));
  588. LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_2,"2.0","true"));
  589. LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_3,"3.0","false"));
  590. LLMediaDataClientObject::ptr_t o4 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_4,"4.0","false"));
  591. {
  592. LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
  593. // queue up all 4 objects.  The first two should be in the sorted
  594. // queue [2 1], the second in the round-robin queue.  The queues
  595. // are serviced interleaved, so we should expect:
  596. // 2, 4, 1, 3
  597. mdc->fetchMedia(o1);
  598. mdc->fetchMedia(o2);
  599. mdc->fetchMedia(o3);
  600. mdc->fetchMedia(o4);
  601. int tick_num = 0;
  602. // 0
  603. ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
  604. ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
  605. ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
  606. ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
  607. ensure(STR(tick_num) + ". post records", gPostRecords->size(), 0);
  608. ::pump_timers();
  609. ++tick_num;
  610. // 1 The first tick should remove object 2
  611. ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2));
  612. ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
  613. ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
  614. ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
  615. ensure(STR(tick_num) + ". post records", gPostRecords->size(), 1);
  616. ensure(STR(tick_num) + ". post object id", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_2));
  617. ::pump_timers();
  618. ++tick_num;
  619. // 2 The second tick should send object 4, but it will still be
  620. // "in the queue"
  621. ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2));
  622. ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
  623. ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
  624. ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
  625. ensure(STR(tick_num) + ". post records", gPostRecords->size(), 2);
  626. ensure(STR(tick_num) + ". post object id", (*gPostRecords)[1]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_4));
  627. ::pump_timers();
  628. ++tick_num;
  629. // 3 The third tick should remove object 1
  630. ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2));
  631. ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1));
  632. ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
  633. ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
  634. ensure(STR(tick_num) + ". post records", gPostRecords->size(), 3);
  635. ensure(STR(tick_num) + ". post object id", (*gPostRecords)[2]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_1));
  636. ::pump_timers();
  637. ++tick_num;
  638. // 4 The fourth tick should send object 3, but it will still be
  639. // "in the queue"
  640. ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2));
  641. ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1));
  642. ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
  643. ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
  644. ensure(STR(tick_num) + ". post records", gPostRecords->size(), 4);
  645. ensure(STR(tick_num) + ". post object id", (*gPostRecords)[3]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_3));
  646. ::pump_timers();
  647. ++tick_num;
  648. // 5 The fifth tick should now identify objects 3 and 4 as no longer
  649. // needing "updating", and remove them from the queue
  650. ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2));
  651. ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1));
  652. ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
  653. ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
  654. ensure(STR(tick_num) + ". post records", gPostRecords->size(), 4);
  655. ::pump_timers();
  656. // Whew....better be empty
  657. ensure("queue empty", mdc->isEmpty());
  658. }
  659. ensure("refcount of o1", o1->getNumRefs(), 1);
  660. ensure("refcount of o2", o2->getNumRefs(), 1);
  661. ensure("refcount of o3", o3->getNumRefs(), 1);
  662. ensure("refcount of o4", o4->getNumRefs(), 1);
  663. }
  664. template<> template<>
  665. void mediadataclient_object_t::test<11>()
  666. {
  667. //
  668. // Test LLMediaDataClient's destructor
  669. //
  670. LOG_TEST(11);
  671. LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest(DATA);
  672. int num_refs_start = o->getNumRefs();
  673. {
  674. LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
  675. mdc->fetchMedia(o);
  676. // must tick enough times to clear refcount of mdc
  677. ::pump_timers();
  678. }
  679. // Make sure everyone's destroyed properly
  680. ensure("REF COUNT", o->getNumRefs(), num_refs_start);
  681. }
  682. template<> template<>
  683.     void mediadataclient_object_t::test<12>()
  684.     {
  685. //
  686. // Test the "not interesting enough" call
  687. //
  688. LOG_TEST(12);
  689. LLMediaDataClientObjectTest *object1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"1.0","true"));
  690. LLMediaDataClientObject::ptr_t o1 = object1;
  691. LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_2,"2.0","true"));
  692. LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_3,"3.0","true"));
  693. LLMediaDataClientObject::ptr_t o4 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_4,"4.0","true"));
  694. {
  695. LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
  696. // queue up all 4 objects.  The first two are "interesting enough".
  697. // Firing the timer 4 times should therefore leave them.
  698. // Note that they should be sorted 4,3,2,1
  699. // Then, we'll make one "interesting enough", fire the timer a few 
  700. // times, and make sure only it gets pulled off the queue
  701. gMinimumInterestLevel = 2.5;
  702. mdc->fetchMedia(o1);
  703. mdc->fetchMedia(o2);
  704. mdc->fetchMedia(o3);
  705. mdc->fetchMedia(o4);
  706. int tick_num = 0;
  707. // 0
  708. ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
  709. ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
  710. ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
  711. ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
  712. ensure(STR(tick_num) + ". post records", gPostRecords->size(), 0);
  713. ::pump_timers();
  714. ++tick_num;
  715. // 1 The first tick should remove object 4
  716. ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
  717. ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
  718. ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
  719. ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
  720. ensure(STR(tick_num) + ". post records", gPostRecords->size(), 1);
  721. ensure(STR(tick_num) + ". post object id", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_4));
  722. ::pump_timers();
  723. ++tick_num;
  724. // 2 The second tick should send object 3
  725. ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
  726. ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
  727. ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
  728. ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
  729. ensure(STR(tick_num) + ". post records", gPostRecords->size(), 2);
  730. ensure(STR(tick_num) + ". post object id", (*gPostRecords)[1]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_3));
  731. ::pump_timers();
  732. ++tick_num;
  733. // 3 The third tick should not pull off anything
  734. ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
  735. ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
  736. ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
  737. ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
  738. ensure(STR(tick_num) + ". post records", gPostRecords->size(), 2);
  739. ::pump_timers();
  740. ++tick_num;
  741. // 4 The fourth tick (for good measure) should not pull off anything
  742. ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
  743. ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
  744. ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
  745. ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
  746. ensure(STR(tick_num) + ". post records", gPostRecords->size(), 2);
  747. // Okay, now futz with object 1's interest, such that it is now 
  748. // "interesting enough"
  749. object1->setMediaInterest((F64)5.0);
  750. // This should sort so that the queue is now [1 2] 
  751. ::pump_timers();
  752. ++tick_num;
  753. // 5 The fifth tick should now identify objects 3 and 4 as no longer
  754. // needing "updating", and remove them from the queue
  755. ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1));
  756. ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
  757. ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
  758. ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
  759. ensure(STR(tick_num) + ". post records", gPostRecords->size(), 3);
  760. ensure(STR(tick_num) + ". post object id", (*gPostRecords)[2]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_1));
  761. ::pump_timers();
  762. ++tick_num;
  763. // 6 The sixth tick should not pull off anything
  764. ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1));
  765. ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
  766. ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
  767. ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
  768. ensure(STR(tick_num) + ". post records", gPostRecords->size(), 3);
  769. ::pump_timers();
  770. ++tick_num;
  771. // Whew....better NOT be empty ... o2 should still be there
  772. ensure("queue not empty", !mdc->isEmpty());
  773. // But, we need to clear the queue, or else we won't destroy MDC...
  774. // this is a strange interplay between the queue timer and the MDC
  775. ensure("o2 couldn't be removed from queue", mdc->removeFromQueue(o2));
  776. // tick
  777. ::pump_timers();
  778. }
  779. ensure("refcount of o1", o1->getNumRefs(), 1);
  780. ensure("refcount of o2", o2->getNumRefs(), 1);
  781. ensure("refcount of o3", o3->getNumRefs(), 1);
  782. ensure("refcount of o4", o4->getNumRefs(), 1);
  783. }
  784. }