ESC-110 ESC-111
Cleanup passes on the two threaded collectors with better comments and more complete unit tests.meow-7.2.2
parent
1ed9d997a6
commit
fd2d4dc1b1
|
|
@ -47,7 +47,7 @@
|
|||
* <TBD>
|
||||
*
|
||||
* Unit Tests:
|
||||
* <TBD>
|
||||
* indra/newview/tests/llviewerassetstats_test.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -55,7 +55,8 @@
|
|||
// ------------------------------------------------------
|
||||
// Global data definitions
|
||||
// ------------------------------------------------------
|
||||
LLViewerAssetStats * gViewerAssetStats = NULL;
|
||||
LLViewerAssetStats * gViewerAssetStatsMain(0);
|
||||
LLViewerAssetStats * gViewerAssetStatsThread1(0);
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
|
|
@ -69,6 +70,21 @@ asset_type_to_category(const LLViewerAssetType::EType at, bool with_http, bool i
|
|||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------
|
||||
// LLViewerAssetStats::PerRegionStats struct definition
|
||||
// ------------------------------------------------------
|
||||
void
|
||||
LLViewerAssetStats::PerRegionStats::reset()
|
||||
{
|
||||
for (int i(0); i < LL_ARRAY_SIZE(mRequests); ++i)
|
||||
{
|
||||
mRequests[i].mEnqueued.reset();
|
||||
mRequests[i].mDequeued.reset();
|
||||
mRequests[i].mResponse.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
// LLViewerAssetStats class definition
|
||||
// ------------------------------------------------------
|
||||
|
|
@ -81,20 +97,55 @@ LLViewerAssetStats::LLViewerAssetStats()
|
|||
void
|
||||
LLViewerAssetStats::reset()
|
||||
{
|
||||
for (int i = 0; i < LL_ARRAY_SIZE(mRequests); ++i)
|
||||
// Empty the map of all region stats
|
||||
mRegionStats.clear();
|
||||
|
||||
// If we have a current stats, reset it, otherwise, as at construction,
|
||||
// create a new one.
|
||||
if (mCurRegionStats)
|
||||
{
|
||||
mRequests[i].mEnqueued.reset();
|
||||
mRequests[i].mDequeued.reset();
|
||||
mRequests[i].mResponse.reset();
|
||||
mCurRegionStats->reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
mCurRegionStats = new PerRegionStats(mRegionID);
|
||||
}
|
||||
|
||||
// And add reference to map
|
||||
mRegionStats[mRegionID] = mCurRegionStats;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LLViewerAssetStats::setRegionID(const LLUUID & region_id)
|
||||
{
|
||||
if (region_id == mRegionID)
|
||||
{
|
||||
// Already active, ignore.
|
||||
return;
|
||||
}
|
||||
|
||||
PerRegionContainer::iterator new_stats = mRegionStats.find(region_id);
|
||||
if (mRegionStats.end() == new_stats)
|
||||
{
|
||||
// Haven't seen this region_id before, create a new block make it current.
|
||||
mCurRegionStats = new PerRegionStats(region_id);
|
||||
mRegionStats[region_id] = mCurRegionStats;
|
||||
}
|
||||
else
|
||||
{
|
||||
mCurRegionStats = new_stats->second;
|
||||
}
|
||||
mRegionID = region_id;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LLViewerAssetStats::recordGetEnqueued(LLViewerAssetType::EType at, bool with_http, bool is_temp)
|
||||
{
|
||||
const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp));
|
||||
|
||||
++mRequests[int(eac)].mEnqueued;
|
||||
++(mCurRegionStats->mRequests[int(eac)].mEnqueued);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -102,7 +153,7 @@ LLViewerAssetStats::recordGetDequeued(LLViewerAssetType::EType at, bool with_htt
|
|||
{
|
||||
const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp));
|
||||
|
||||
++mRequests[int(eac)].mDequeued;
|
||||
++(mCurRegionStats->mRequests[int(eac)].mDequeued);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -110,7 +161,7 @@ LLViewerAssetStats::recordGetServiced(LLViewerAssetType::EType at, bool with_htt
|
|||
{
|
||||
const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp));
|
||||
|
||||
mRequests[int(eac)].mResponse.record(duration);
|
||||
mCurRegionStats->mRequests[int(eac)].mResponse.record(duration);
|
||||
}
|
||||
|
||||
const LLSD
|
||||
|
|
@ -139,16 +190,33 @@ LLViewerAssetStats::asLLSD() const
|
|||
|
||||
LLSD ret = LLSD::emptyMap();
|
||||
|
||||
for (int i = 0; i < EVACCount; ++i)
|
||||
for (PerRegionContainer::const_iterator it = mRegionStats.begin();
|
||||
mRegionStats.end() != it;
|
||||
++it)
|
||||
{
|
||||
LLSD & slot = ret[tags[i]];
|
||||
slot = LLSD::emptyMap();
|
||||
slot[enq_tag] = LLSD(S32(mRequests[i].mEnqueued.getCount()));
|
||||
slot[deq_tag] = LLSD(S32(mRequests[i].mDequeued.getCount()));
|
||||
slot[rcnt_tag] = LLSD(S32(mRequests[i].mResponse.getCount()));
|
||||
slot[rmin_tag] = LLSD(mRequests[i].mResponse.getMin());
|
||||
slot[rmax_tag] = LLSD(mRequests[i].mResponse.getMax());
|
||||
slot[rmean_tag] = LLSD(mRequests[i].mResponse.getMean());
|
||||
if (it->first.isNull())
|
||||
{
|
||||
// Never emit NULL UUID in results.
|
||||
continue;
|
||||
}
|
||||
|
||||
const PerRegionStats & stats = *it->second;
|
||||
|
||||
LLSD reg_stat = LLSD::emptyMap();
|
||||
|
||||
for (int i = 0; i < EVACCount; ++i)
|
||||
{
|
||||
LLSD & slot = reg_stat[tags[i]];
|
||||
slot = LLSD::emptyMap();
|
||||
slot[enq_tag] = LLSD(S32(stats.mRequests[i].mEnqueued.getCount()));
|
||||
slot[deq_tag] = LLSD(S32(stats.mRequests[i].mDequeued.getCount()));
|
||||
slot[rcnt_tag] = LLSD(S32(stats.mRequests[i].mResponse.getCount()));
|
||||
slot[rmin_tag] = LLSD(stats.mRequests[i].mResponse.getMin());
|
||||
slot[rmax_tag] = LLSD(stats.mRequests[i].mResponse.getMax());
|
||||
slot[rmean_tag] = LLSD(stats.mRequests[i].mResponse.getMean());
|
||||
}
|
||||
|
||||
ret[it->first.asString()] = reg_stat;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
@ -161,31 +229,81 @@ LLViewerAssetStats::asLLSD() const
|
|||
namespace LLViewerAssetStatsFF
|
||||
{
|
||||
|
||||
// Target thread is elaborated in the function name. This could
|
||||
// have been something 'templatey' like specializations iterated
|
||||
// over a set of constants but with so few, this is clearer I think.
|
||||
|
||||
void
|
||||
record_enqueue(LLViewerAssetType::EType at, bool with_http, bool is_temp)
|
||||
set_region_main(const LLUUID & region_id)
|
||||
{
|
||||
if (! gViewerAssetStats)
|
||||
if (! gViewerAssetStatsMain)
|
||||
return;
|
||||
|
||||
gViewerAssetStats->recordGetEnqueued(at, with_http, is_temp);
|
||||
gViewerAssetStatsMain->setRegionID(region_id);
|
||||
}
|
||||
|
||||
void
|
||||
record_dequeue(LLViewerAssetType::EType at, bool with_http, bool is_temp)
|
||||
record_enqueue_main(LLViewerAssetType::EType at, bool with_http, bool is_temp)
|
||||
{
|
||||
if (! gViewerAssetStats)
|
||||
if (! gViewerAssetStatsMain)
|
||||
return;
|
||||
|
||||
gViewerAssetStats->recordGetDequeued(at, with_http, is_temp);
|
||||
gViewerAssetStatsMain->recordGetEnqueued(at, with_http, is_temp);
|
||||
}
|
||||
|
||||
void
|
||||
record_response(LLViewerAssetType::EType at, bool with_http, bool is_temp, F64 duration)
|
||||
record_dequeue_main(LLViewerAssetType::EType at, bool with_http, bool is_temp)
|
||||
{
|
||||
if (! gViewerAssetStats)
|
||||
if (! gViewerAssetStatsMain)
|
||||
return;
|
||||
|
||||
gViewerAssetStats->recordGetServiced(at, with_http, is_temp, duration);
|
||||
gViewerAssetStatsMain->recordGetDequeued(at, with_http, is_temp);
|
||||
}
|
||||
|
||||
void
|
||||
record_response_main(LLViewerAssetType::EType at, bool with_http, bool is_temp, F64 duration)
|
||||
{
|
||||
if (! gViewerAssetStatsMain)
|
||||
return;
|
||||
|
||||
gViewerAssetStatsMain->recordGetServiced(at, with_http, is_temp, duration);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
set_region_thread1(const LLUUID & region_id)
|
||||
{
|
||||
if (! gViewerAssetStatsThread1)
|
||||
return;
|
||||
|
||||
gViewerAssetStatsThread1->setRegionID(region_id);
|
||||
}
|
||||
|
||||
void
|
||||
record_enqueue_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp)
|
||||
{
|
||||
if (! gViewerAssetStatsThread1)
|
||||
return;
|
||||
|
||||
gViewerAssetStatsThread1->recordGetEnqueued(at, with_http, is_temp);
|
||||
}
|
||||
|
||||
void
|
||||
record_dequeue_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp)
|
||||
{
|
||||
if (! gViewerAssetStatsThread1)
|
||||
return;
|
||||
|
||||
gViewerAssetStatsThread1->recordGetDequeued(at, with_http, is_temp);
|
||||
}
|
||||
|
||||
void
|
||||
record_response_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp, F64 duration)
|
||||
{
|
||||
if (! gViewerAssetStatsThread1)
|
||||
return;
|
||||
|
||||
gViewerAssetStatsThread1->recordGetServiced(at, with_http, is_temp, duration);
|
||||
}
|
||||
|
||||
} // namespace LLViewerAssetStatsFF
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llpointer.h"
|
||||
#include "llrefcount.h"
|
||||
#include "llviewerassettype.h"
|
||||
#include "llviewerassetstorage.h"
|
||||
#include "llsimplestat.h"
|
||||
|
|
@ -43,50 +45,42 @@
|
|||
|
||||
/**
|
||||
* @class LLViewerAssetStats
|
||||
* @brief Records events and performance of asset put/get operations.
|
||||
* @brief Records performance aspects of asset access operations.
|
||||
*
|
||||
* The asset system is a combination of common code and server-
|
||||
* and viewer-overridden derivations. The common code is presented
|
||||
* in here as the 'front-end' and deriviations (really the server)
|
||||
* are presented as 'back-end'. The distinction isn't perfect as
|
||||
* there are legacy asset transfer systems which mostly appear
|
||||
* as front-end stats.
|
||||
* This facility is derived from a very similar simulator-based
|
||||
* one, LLSimAssetStats. It's function is to count asset access
|
||||
* operations and characterize response times. Collected data
|
||||
* are binned in several dimensions:
|
||||
*
|
||||
* - Asset types collapsed into a few aggregated categories
|
||||
* - By simulator UUID
|
||||
* - By transport mechanism (HTTP vs MessageSystem)
|
||||
* - By persistence (temp vs non-temp)
|
||||
*
|
||||
* Statistics collected are fairly basic at this point:
|
||||
*
|
||||
* Statistics collected are fairly basic:
|
||||
* - Counts of enqueue and dequeue operations
|
||||
* - Counts of duplicated request fetches
|
||||
* - Min/Max/Mean of asset transfer operations
|
||||
*
|
||||
* While the stats collection interfaces appear to be fairly
|
||||
* orthogonal across methods (GET, PUT) and asset types (texture,
|
||||
* bodypart, etc.), the actual internal collection granularity
|
||||
* varies greatly. GET's operations found in the cache are
|
||||
* treated as a single group as are duplicate requests. Non-
|
||||
* cached items are broken down into three groups: textures,
|
||||
* wearables (bodyparts, clothing) and the rest. PUT operations
|
||||
* are broken down into two categories: temporary assets and
|
||||
* non-temp. Back-end operations do not distinguish asset types,
|
||||
* only GET, PUT (temp) and PUT (non-temp).
|
||||
*
|
||||
* No coverage for Estate Assets or Inventory Item Assets which use
|
||||
* some different interface conventions. It could be expanded to cover
|
||||
* them.
|
||||
* This collector differs from the simulator-based on in a
|
||||
* number of ways:
|
||||
*
|
||||
* - The front-end/back-end distinction doesn't exist in viewer
|
||||
* code
|
||||
* - Multiple threads must be safely accomodated in the viewer
|
||||
*
|
||||
* Access to results is by conversion to an LLSD with some standardized
|
||||
* key names. The intent of this structure is to be emitted as
|
||||
* key names. The intent of this structure is that it be emitted as
|
||||
* standard syslog-based metrics formatting where it can be picked
|
||||
* up by interested parties.
|
||||
*
|
||||
* For convenience, a set of free functions in namespace LLAssetStatsFF
|
||||
* are provided which operate on various counters in a way that
|
||||
* is highly-compatible with the simulator code.
|
||||
* For convenience, a set of free functions in namespace
|
||||
* LLViewerAssetStatsFF is provided for conditional test-and-call
|
||||
* operations.
|
||||
*/
|
||||
class LLViewerAssetStats
|
||||
{
|
||||
public:
|
||||
LLViewerAssetStats();
|
||||
// Default destructor and assignment operator are correct.
|
||||
|
||||
enum EViewerAssetCategories
|
||||
{
|
||||
EVACTextureTempHTTPGet, //< Texture GETs
|
||||
|
|
@ -100,45 +94,109 @@ public:
|
|||
|
||||
EVACCount // Must be last
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Collected data for a single region visited by the avatar.
|
||||
*/
|
||||
class PerRegionStats : public LLRefCount
|
||||
{
|
||||
public:
|
||||
PerRegionStats(const LLUUID & region_id)
|
||||
: LLRefCount(),
|
||||
mRegionID(region_id)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset();
|
||||
|
||||
public:
|
||||
LLUUID mRegionID;
|
||||
struct
|
||||
{
|
||||
LLSimpleStatCounter mEnqueued;
|
||||
LLSimpleStatCounter mDequeued;
|
||||
LLSimpleStatMMM<> mResponse;
|
||||
} mRequests [EVACCount];
|
||||
};
|
||||
|
||||
public:
|
||||
LLViewerAssetStats();
|
||||
// Default destructor is correct.
|
||||
LLViewerAssetStats & operator=(const LLViewerAssetStats &); // Not defined
|
||||
|
||||
// Clear all metrics data. This leaves the currently-active region
|
||||
// in place but with zero'd data for all metrics. All other regions
|
||||
// are removed from the collection map.
|
||||
void reset();
|
||||
|
||||
// Set hidden region argument and establish context for subsequent
|
||||
// collection calls.
|
||||
void setRegionID(const LLUUID & region_id);
|
||||
|
||||
// Non-Cached GET Requests
|
||||
void recordGetEnqueued(LLViewerAssetType::EType at, bool with_http, bool is_temp);
|
||||
void recordGetDequeued(LLViewerAssetType::EType at, bool with_http, bool is_temp);
|
||||
void recordGetServiced(LLViewerAssetType::EType at, bool with_http, bool is_temp, F64 duration);
|
||||
|
||||
// Report Generation
|
||||
// Retrieve current metrics for all visited regions.
|
||||
const LLSD asLLSD() const;
|
||||
|
||||
protected:
|
||||
typedef std::map<LLUUID, LLPointer<PerRegionStats> > PerRegionContainer;
|
||||
|
||||
struct
|
||||
{
|
||||
LLSimpleStatCounter mEnqueued;
|
||||
LLSimpleStatCounter mDequeued;
|
||||
LLSimpleStatMMM<> mResponse;
|
||||
} mRequests [EVACCount];
|
||||
// Region of the currently-active region. Always valid but may
|
||||
// be a NULL UUID after construction or when explicitly set. Unchanged
|
||||
// by a reset() call.
|
||||
LLUUID mRegionID;
|
||||
|
||||
// Pointer to metrics collection for currently-active region. Always
|
||||
// valid and unchanged after reset() though contents will be changed.
|
||||
// Always points to a collection contained in mRegionStats.
|
||||
LLPointer<PerRegionStats> mCurRegionStats;
|
||||
|
||||
// Metrics data for all regions during one collection cycle
|
||||
PerRegionContainer mRegionStats;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Expectation is that the simulator and other asset-handling
|
||||
* code will create a single instance of the stats class and
|
||||
* make it available here. The free functions examine this
|
||||
* for non-zero and perform their functions conditionally. The
|
||||
* instance methods themselves make no assumption about this.
|
||||
* Global stats collectors one for each independent thread where
|
||||
* assets and other statistics are gathered. The globals are
|
||||
* expected to be created at startup time and then picked up by
|
||||
* their respective threads afterwards. A set of free functions
|
||||
* are provided to access methods behind the globals while both
|
||||
* minimally disrupting visual flow and supplying a description
|
||||
* of intent.
|
||||
*
|
||||
* Expected thread assignments:
|
||||
*
|
||||
* - Main: main() program execution thread
|
||||
* - Thread1: TextureFetch worker thread
|
||||
*/
|
||||
extern LLViewerAssetStats * gViewerAssetStats;
|
||||
extern LLViewerAssetStats * gViewerAssetStatsMain;
|
||||
|
||||
extern LLViewerAssetStats * gViewerAssetStatsThread1;
|
||||
|
||||
namespace LLViewerAssetStatsFF
|
||||
{
|
||||
|
||||
void record_enqueue(LLViewerAssetType::EType at, bool with_http, bool is_temp);
|
||||
void set_region_main(const LLUUID & region_id);
|
||||
|
||||
void record_dequeue(LLViewerAssetType::EType at, bool with_http, bool is_temp);
|
||||
void record_enqueue_main(LLViewerAssetType::EType at, bool with_http, bool is_temp);
|
||||
|
||||
void record_response(LLViewerAssetType::EType at, bool with_http, bool is_temp, F64 duration);
|
||||
void record_dequeue_main(LLViewerAssetType::EType at, bool with_http, bool is_temp);
|
||||
|
||||
void record_response_main(LLViewerAssetType::EType at, bool with_http, bool is_temp, F64 duration);
|
||||
|
||||
|
||||
void set_region_thread1(const LLUUID & region_id);
|
||||
|
||||
void record_enqueue_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp);
|
||||
|
||||
void record_dequeue_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp);
|
||||
|
||||
void record_response_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp, F64 duration);
|
||||
|
||||
} // namespace LLViewerAssetStatsFF
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
#include "lltut.h"
|
||||
#include "../llviewerassetstats.h"
|
||||
#include "lluuid.h"
|
||||
|
||||
static const char * all_keys[] =
|
||||
{
|
||||
|
|
@ -73,6 +74,27 @@ static const char * sub_keys[] =
|
|||
"resp_mean"
|
||||
};
|
||||
|
||||
static const LLUUID region1("4e2d81a3-6263-6ffe-ad5c-8ce04bee07e8");
|
||||
static const LLUUID region2("68762cc8-b68b-4e45-854b-e830734f2d4a");
|
||||
|
||||
static bool
|
||||
is_empty_map(const LLSD & sd)
|
||||
{
|
||||
return sd.isMap() && 0 == sd.size();
|
||||
}
|
||||
|
||||
static bool
|
||||
is_single_key_map(const LLSD & sd, const std::string & key)
|
||||
{
|
||||
return sd.isMap() && 1 == sd.size() && sd.has(key);
|
||||
}
|
||||
|
||||
static bool
|
||||
is_double_key_map(const LLSD & sd, const std::string & key1, const std::string & key2)
|
||||
{
|
||||
return sd.isMap() && 2 == sd.size() && sd.has(key1) && sd.has(key2);
|
||||
}
|
||||
|
||||
namespace tut
|
||||
{
|
||||
struct tst_viewerassetstats_index
|
||||
|
|
@ -86,29 +108,40 @@ namespace tut
|
|||
void tst_viewerassetstats_index_object_t::test<1>()
|
||||
{
|
||||
// Check that helpers aren't bothered by missing global stats
|
||||
ensure("Global gViewerAssetStats should be NULL", (NULL == gViewerAssetStats));
|
||||
ensure("Global gViewerAssetStatsMain should be NULL", (NULL == gViewerAssetStatsMain));
|
||||
|
||||
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false);
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false);
|
||||
|
||||
LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, false, false);
|
||||
LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false);
|
||||
|
||||
LLViewerAssetStatsFF::record_response(LLViewerAssetType::AT_GESTURE, false, false, 12.3);
|
||||
LLViewerAssetStatsFF::record_response_main(LLViewerAssetType::AT_GESTURE, false, false, 12.3);
|
||||
}
|
||||
|
||||
// Create a non-global instance and check the structure
|
||||
template<> template<>
|
||||
void tst_viewerassetstats_index_object_t::test<2>()
|
||||
{
|
||||
ensure("Global gViewerAssetStats should be NULL", (NULL == gViewerAssetStats));
|
||||
ensure("Global gViewerAssetStatsMain should be NULL", (NULL == gViewerAssetStatsMain));
|
||||
|
||||
LLViewerAssetStats * it = new LLViewerAssetStats();
|
||||
|
||||
ensure("Global gViewerAssetStats should still be NULL", (NULL == gViewerAssetStats));
|
||||
|
||||
LLSD sd = it->asLLSD();
|
||||
|
||||
delete it;
|
||||
ensure("Global gViewerAssetStatsMain should still be NULL", (NULL == gViewerAssetStatsMain));
|
||||
|
||||
LLSD sd_full = it->asLLSD();
|
||||
|
||||
// Default (NULL) region ID doesn't produce LLSD results so should
|
||||
// get an empty map back from output
|
||||
ensure("Null LLSD initially", is_empty_map(sd_full));
|
||||
|
||||
// Once the region is set, we will get a response even with no data collection
|
||||
it->setRegionID(region1);
|
||||
sd_full = it->asLLSD();
|
||||
ensure("Correct single-key LLSD map", is_single_key_map(sd_full, region1.asString()));
|
||||
|
||||
LLSD sd = sd_full[region1.asString()];
|
||||
|
||||
delete it;
|
||||
|
||||
// Check the structure of the LLSD
|
||||
for (int i = 0; i < LL_ARRAY_SIZE(all_keys); ++i)
|
||||
{
|
||||
|
|
@ -131,8 +164,11 @@ namespace tut
|
|||
void tst_viewerassetstats_index_object_t::test<3>()
|
||||
{
|
||||
LLViewerAssetStats * it = new LLViewerAssetStats();
|
||||
it->setRegionID(region1);
|
||||
|
||||
LLSD sd = it->asLLSD();
|
||||
ensure("Correct single-key LLSD map", is_single_key_map(sd, region1.asString()));
|
||||
sd = sd[region1.asString()];
|
||||
|
||||
delete it;
|
||||
|
||||
|
|
@ -145,15 +181,18 @@ namespace tut
|
|||
template<> template<>
|
||||
void tst_viewerassetstats_index_object_t::test<4>()
|
||||
{
|
||||
gViewerAssetStats = new LLViewerAssetStats();
|
||||
gViewerAssetStatsMain = new LLViewerAssetStats();
|
||||
LLViewerAssetStatsFF::set_region_main(region1);
|
||||
|
||||
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false);
|
||||
LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, false, false);
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false);
|
||||
LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false);
|
||||
|
||||
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false);
|
||||
LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false);
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false);
|
||||
LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false);
|
||||
|
||||
LLSD sd = gViewerAssetStats->asLLSD();
|
||||
LLSD sd = gViewerAssetStatsMain->asLLSD();
|
||||
ensure("Correct single-key LLSD map", is_single_key_map(sd, region1.asString()));
|
||||
sd = sd[region1.asString()];
|
||||
|
||||
// Check a few points on the tree for content
|
||||
ensure("sd[get_texture_non_temp_udp][enqueued] is 1", (1 == sd["get_texture_non_temp_udp"]["enqueued"].asInteger()));
|
||||
|
|
@ -163,11 +202,235 @@ namespace tut
|
|||
ensure("sd[get_gesture_udp][dequeued] is 0", (0 == sd["get_gesture_udp"]["dequeued"].asInteger()));
|
||||
|
||||
// Reset and check zeros...
|
||||
gViewerAssetStats->reset();
|
||||
sd = gViewerAssetStats->asLLSD();
|
||||
// Reset leaves current region in place
|
||||
gViewerAssetStatsMain->reset();
|
||||
sd = gViewerAssetStatsMain->asLLSD()[region1.asString()];
|
||||
|
||||
delete gViewerAssetStats;
|
||||
gViewerAssetStats = NULL;
|
||||
delete gViewerAssetStatsMain;
|
||||
gViewerAssetStatsMain = NULL;
|
||||
|
||||
ensure("sd[get_texture_non_temp_udp][enqueued] is reset", (0 == sd["get_texture_non_temp_udp"]["enqueued"].asInteger()));
|
||||
ensure("sd[get_gesture_udp][dequeued] is reset", (0 == sd["get_gesture_udp"]["dequeued"].asInteger()));
|
||||
}
|
||||
|
||||
// Create two global instances and verify no interactions
|
||||
template<> template<>
|
||||
void tst_viewerassetstats_index_object_t::test<5>()
|
||||
{
|
||||
gViewerAssetStatsThread1 = new LLViewerAssetStats();
|
||||
gViewerAssetStatsMain = new LLViewerAssetStats();
|
||||
LLViewerAssetStatsFF::set_region_main(region1);
|
||||
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false);
|
||||
LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false);
|
||||
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false);
|
||||
LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false);
|
||||
|
||||
LLSD sd = gViewerAssetStatsThread1->asLLSD();
|
||||
ensure("Other collector is empty", is_empty_map(sd));
|
||||
sd = gViewerAssetStatsMain->asLLSD();
|
||||
ensure("Correct single-key LLSD map", is_single_key_map(sd, region1.asString()));
|
||||
sd = sd[region1.asString()];
|
||||
|
||||
// Check a few points on the tree for content
|
||||
ensure("sd[get_texture_non_temp_udp][enqueued] is 1", (1 == sd["get_texture_non_temp_udp"]["enqueued"].asInteger()));
|
||||
ensure("sd[get_texture_temp_udp][enqueued] is 0", (0 == sd["get_texture_temp_udp"]["enqueued"].asInteger()));
|
||||
ensure("sd[get_texture_non_temp_http][enqueued] is 0", (0 == sd["get_texture_non_temp_http"]["enqueued"].asInteger()));
|
||||
ensure("sd[get_texture_temp_http][enqueued] is 0", (0 == sd["get_texture_temp_http"]["enqueued"].asInteger()));
|
||||
ensure("sd[get_gesture_udp][dequeued] is 0", (0 == sd["get_gesture_udp"]["dequeued"].asInteger()));
|
||||
|
||||
// Reset and check zeros...
|
||||
// Reset leaves current region in place
|
||||
gViewerAssetStatsMain->reset();
|
||||
sd = gViewerAssetStatsMain->asLLSD()[region1.asString()];
|
||||
|
||||
delete gViewerAssetStatsMain;
|
||||
gViewerAssetStatsMain = NULL;
|
||||
delete gViewerAssetStatsThread1;
|
||||
gViewerAssetStatsThread1 = NULL;
|
||||
|
||||
ensure("sd[get_texture_non_temp_udp][enqueued] is reset", (0 == sd["get_texture_non_temp_udp"]["enqueued"].asInteger()));
|
||||
ensure("sd[get_gesture_udp][dequeued] is reset", (0 == sd["get_gesture_udp"]["dequeued"].asInteger()));
|
||||
}
|
||||
|
||||
// Check multiple region collection
|
||||
template<> template<>
|
||||
void tst_viewerassetstats_index_object_t::test<6>()
|
||||
{
|
||||
gViewerAssetStatsMain = new LLViewerAssetStats();
|
||||
|
||||
LLViewerAssetStatsFF::set_region_main(region1);
|
||||
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false);
|
||||
LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false);
|
||||
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false);
|
||||
LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false);
|
||||
|
||||
LLViewerAssetStatsFF::set_region_main(region2);
|
||||
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
|
||||
|
||||
LLSD sd = gViewerAssetStatsMain->asLLSD();
|
||||
|
||||
ensure("Correct double-key LLSD map", is_double_key_map(sd, region1.asString(), region2.asString()));
|
||||
LLSD sd1 = sd[region1.asString()];
|
||||
LLSD sd2 = sd[region2.asString()];
|
||||
|
||||
// Check a few points on the tree for content
|
||||
ensure("sd1[get_texture_non_temp_udp][enqueued] is 1", (1 == sd1["get_texture_non_temp_udp"]["enqueued"].asInteger()));
|
||||
ensure("sd1[get_texture_temp_udp][enqueued] is 0", (0 == sd1["get_texture_temp_udp"]["enqueued"].asInteger()));
|
||||
ensure("sd1[get_texture_non_temp_http][enqueued] is 0", (0 == sd1["get_texture_non_temp_http"]["enqueued"].asInteger()));
|
||||
ensure("sd1[get_texture_temp_http][enqueued] is 0", (0 == sd1["get_texture_temp_http"]["enqueued"].asInteger()));
|
||||
ensure("sd1[get_gesture_udp][dequeued] is 0", (0 == sd1["get_gesture_udp"]["dequeued"].asInteger()));
|
||||
|
||||
// Check a few points on the tree for content
|
||||
ensure("sd2[get_gesture_udp][enqueued] is 4", (4 == sd2["get_gesture_udp"]["enqueued"].asInteger()));
|
||||
ensure("sd2[get_gesture_udp][dequeued] is 0", (0 == sd2["get_gesture_udp"]["dequeued"].asInteger()));
|
||||
ensure("sd2[get_texture_non_temp_udp][enqueued] is 0", (0 == sd2["get_texture_non_temp_udp"]["enqueued"].asInteger()));
|
||||
|
||||
// Reset and check zeros...
|
||||
// Reset leaves current region in place
|
||||
gViewerAssetStatsMain->reset();
|
||||
sd = gViewerAssetStatsMain->asLLSD();
|
||||
ensure("Correct single-key LLSD map", is_single_key_map(sd, region2.asString()));
|
||||
sd2 = sd[region2.asString()];
|
||||
|
||||
delete gViewerAssetStatsMain;
|
||||
gViewerAssetStatsMain = NULL;
|
||||
|
||||
ensure("sd2[get_texture_non_temp_udp][enqueued] is reset", (0 == sd2["get_texture_non_temp_udp"]["enqueued"].asInteger()));
|
||||
ensure("sd2[get_gesture_udp][enqueued] is reset", (0 == sd2["get_gesture_udp"]["enqueued"].asInteger()));
|
||||
}
|
||||
|
||||
// Check multiple region collection jumping back-and-forth between regions
|
||||
template<> template<>
|
||||
void tst_viewerassetstats_index_object_t::test<7>()
|
||||
{
|
||||
gViewerAssetStatsMain = new LLViewerAssetStats();
|
||||
|
||||
LLViewerAssetStatsFF::set_region_main(region1);
|
||||
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false);
|
||||
LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false);
|
||||
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false);
|
||||
LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false);
|
||||
|
||||
LLViewerAssetStatsFF::set_region_main(region2);
|
||||
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
|
||||
|
||||
LLViewerAssetStatsFF::set_region_main(region1);
|
||||
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, true, true);
|
||||
LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, true, true);
|
||||
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false);
|
||||
LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false);
|
||||
|
||||
LLViewerAssetStatsFF::set_region_main(region2);
|
||||
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
|
||||
|
||||
LLSD sd = gViewerAssetStatsMain->asLLSD();
|
||||
|
||||
ensure("Correct double-key LLSD map", is_double_key_map(sd, region1.asString(), region2.asString()));
|
||||
LLSD sd1 = sd[region1.asString()];
|
||||
LLSD sd2 = sd[region2.asString()];
|
||||
|
||||
// Check a few points on the tree for content
|
||||
ensure("sd1[get_texture_non_temp_udp][enqueued] is 1", (1 == sd1["get_texture_non_temp_udp"]["enqueued"].asInteger()));
|
||||
ensure("sd1[get_texture_temp_udp][enqueued] is 0", (0 == sd1["get_texture_temp_udp"]["enqueued"].asInteger()));
|
||||
ensure("sd1[get_texture_non_temp_http][enqueued] is 0", (0 == sd1["get_texture_non_temp_http"]["enqueued"].asInteger()));
|
||||
ensure("sd1[get_texture_temp_http][enqueued] is 1", (1 == sd1["get_texture_temp_http"]["enqueued"].asInteger()));
|
||||
ensure("sd1[get_gesture_udp][dequeued] is 0", (0 == sd1["get_gesture_udp"]["dequeued"].asInteger()));
|
||||
|
||||
// Check a few points on the tree for content
|
||||
ensure("sd2[get_gesture_udp][enqueued] is 8", (8 == sd2["get_gesture_udp"]["enqueued"].asInteger()));
|
||||
ensure("sd2[get_gesture_udp][dequeued] is 0", (0 == sd2["get_gesture_udp"]["dequeued"].asInteger()));
|
||||
ensure("sd2[get_texture_non_temp_udp][enqueued] is 0", (0 == sd2["get_texture_non_temp_udp"]["enqueued"].asInteger()));
|
||||
|
||||
// Reset and check zeros...
|
||||
// Reset leaves current region in place
|
||||
gViewerAssetStatsMain->reset();
|
||||
sd = gViewerAssetStatsMain->asLLSD();
|
||||
ensure("Correct single-key LLSD map", is_single_key_map(sd, region2.asString()));
|
||||
sd2 = sd[region2.asString()];
|
||||
|
||||
delete gViewerAssetStatsMain;
|
||||
gViewerAssetStatsMain = NULL;
|
||||
|
||||
ensure("sd2[get_texture_non_temp_udp][enqueued] is reset", (0 == sd2["get_texture_non_temp_udp"]["enqueued"].asInteger()));
|
||||
ensure("sd2[get_gesture_udp][enqueued] is reset", (0 == sd2["get_gesture_udp"]["enqueued"].asInteger()));
|
||||
}
|
||||
|
||||
// Non-texture assets ignore transport and persistence flags
|
||||
template<> template<>
|
||||
void tst_viewerassetstats_index_object_t::test<8>()
|
||||
{
|
||||
gViewerAssetStatsThread1 = new LLViewerAssetStats();
|
||||
gViewerAssetStatsMain = new LLViewerAssetStats();
|
||||
LLViewerAssetStatsFF::set_region_main(region1);
|
||||
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false);
|
||||
LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false);
|
||||
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false);
|
||||
LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false);
|
||||
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, true);
|
||||
LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, true);
|
||||
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, true, false);
|
||||
LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, true, false);
|
||||
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, true, true);
|
||||
LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, true, true);
|
||||
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_LSL_BYTECODE, false, false);
|
||||
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_LSL_BYTECODE, false, true);
|
||||
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_LSL_BYTECODE, true, false);
|
||||
|
||||
LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
|
||||
|
||||
LLSD sd = gViewerAssetStatsThread1->asLLSD();
|
||||
ensure("Other collector is empty", is_empty_map(sd));
|
||||
sd = gViewerAssetStatsMain->asLLSD();
|
||||
ensure("Correct single-key LLSD map", is_single_key_map(sd, region1.asString()));
|
||||
sd = sd[region1.asString()];
|
||||
|
||||
// Check a few points on the tree for content
|
||||
ensure("sd[get_gesture_udp][enqueued] is 0", (0 == sd["get_gesture_udp"]["enqueued"].asInteger()));
|
||||
ensure("sd[get_gesture_udp][dequeued] is 0", (0 == sd["get_gesture_udp"]["dequeued"].asInteger()));
|
||||
|
||||
ensure("sd[get_wearable_udp][enqueued] is 4", (4 == sd["get_wearable_udp"]["enqueued"].asInteger()));
|
||||
ensure("sd[get_wearable_udp][dequeued] is 4", (4 == sd["get_wearable_udp"]["dequeued"].asInteger()));
|
||||
|
||||
ensure("sd[get_other][enqueued] is 4", (4 == sd["get_other"]["enqueued"].asInteger()));
|
||||
ensure("sd[get_other][dequeued] is 0", (0 == sd["get_other"]["dequeued"].asInteger()));
|
||||
|
||||
// Reset and check zeros...
|
||||
// Reset leaves current region in place
|
||||
gViewerAssetStatsMain->reset();
|
||||
sd = gViewerAssetStatsMain->asLLSD()[region1.asString()];
|
||||
|
||||
delete gViewerAssetStatsMain;
|
||||
gViewerAssetStatsMain = NULL;
|
||||
delete gViewerAssetStatsThread1;
|
||||
gViewerAssetStatsThread1 = NULL;
|
||||
|
||||
ensure("sd[get_texture_non_temp_udp][enqueued] is reset", (0 == sd["get_texture_non_temp_udp"]["enqueued"].asInteger()));
|
||||
ensure("sd[get_gesture_udp][dequeued] is reset", (0 == sd["get_gesture_udp"]["dequeued"].asInteger()));
|
||||
|
|
|
|||
Loading…
Reference in New Issue