Apertura del repositorio

This commit is contained in:
2025-05-24 18:09:39 -03:00
parent 76e6359dad
commit d883ddd0d0
35253 changed files with 2891973 additions and 2 deletions
+386
View File
@@ -0,0 +1,386 @@
/**
* @file cppfeatures_test
* @author Vir
* @date 2021-03
* @brief cpp features
*
* $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2021, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
// Tests related to newer C++ features, for verifying support across compilers and platforms
#include "linden_common.h"
#include "../test/lltut.h"
namespace tut
{
struct cpp_features_test {};
typedef test_group<cpp_features_test> cpp_features_test_t;
typedef cpp_features_test_t::object cpp_features_test_object_t;
tut::cpp_features_test_t tut_cpp_features_test("LLCPPFeatures");
// bracket initializers
// Can initialize containers or values using curly brackets
template<> template<>
void cpp_features_test_object_t::test<1>()
{
S32 explicit_val{3};
ensure(explicit_val==3);
S32 default_val{};
ensure(default_val==0);
std::vector<S32> fibs{1,1,2,3,5};
ensure(fibs[4]==5);
}
// auto
//
// https://en.cppreference.com/w/cpp/language/auto
//
// Can use auto in place of a more complex type specification, if the compiler can infer the type
template<> template<>
void cpp_features_test_object_t::test<2>()
{
std::vector<S32> numbers{3,6,9};
// auto element
auto& aval = numbers[1];
ensure("auto element", aval==6);
// auto iterator (non-const)
auto it = numbers.rbegin();
*it += 1;
S32 val = *it;
ensure("auto iterator", val==10);
}
// range for
//
// https://en.cppreference.com/w/cpp/language/range-for
//
// Can iterate over containers without explicit iterator
template<> template<>
void cpp_features_test_object_t::test<3>()
{
// Traditional iterator for with container
//
// Problems:
// * Have to create a new variable for the iterator, which is unrelated to the problem you're trying to solve.
// * Redundant and somewhat fragile. Have to make sure begin() and end() are both from the right container.
std::vector<S32> numbers{3,6,9};
for (auto it = numbers.begin(); it != numbers.end(); ++it)
{
auto& n = *it;
n *= 2;
}
ensure("iterator for vector", numbers[2]==18);
// Range for with container
//
// Under the hood, this is doing the same thing as the traditional
// for loop above. Still uses begin() and end() but you don't have
// to access them directly.
std::vector<S32> numbersb{3,6,9};
for (auto& n: numbersb)
{
n *= 2;
}
ensure("range for vector", numbersb[2]==18);
// Range for over a C-style array.
//
// This is handy because the language determines the range automatically.
// Getting this right manually is a little trickier.
S32 pows[] = {1,2,4,8,16};
S32 sum{};
for (const auto& v: pows)
{
sum += v;
}
ensure("for C-array", sum==31);
}
// override specifier
//
// https://en.cppreference.com/w/cpp/language/override
//
// Specify that a particular class function is an override of a virtual function.
// Benefits:
// * Makes code somewhat easier to read by showing intent.
// * Prevents mistakes where you think something is an override but it doesn't actually match the declaration in the parent class.
// Drawbacks:
// * Some compilers require that any class using override must use it consistently for all functions.
// This makes switching a class to use override a lot more work.
class Foo
{
public:
virtual bool is_happy() const = 0;
};
class Bar: public Foo
{
public:
bool is_happy() const override { return true; }
// Override would fail: non-const declaration doesn't match parent
// bool is_happy() override { return true; }
// Override would fail: wrong name
// bool is_happx() override { return true; }
};
template<> template<>
void cpp_features_test_object_t::test<4>()
{
Bar b;
ensure("override", b.is_happy());
}
// final
//
// https://en.cppreference.com/w/cpp/language/final: "Specifies that a
// virtual function cannot be overridden in a derived class or that a
// class cannot be inherited from."
class Vehicle
{
public:
virtual bool has_wheels() const = 0;
};
class WheeledVehicle: public Vehicle
{
public:
virtual bool has_wheels() const final override { return true; }
};
class Bicycle: public WheeledVehicle
{
public:
// Error: can't override final version in WheeledVehicle
// virtual bool has_wheels() override const { return true; }
};
template<> template<>
void cpp_features_test_object_t::test<5>()
{
Bicycle bi;
ensure("final", bi.has_wheels());
}
// deleted function declaration
//
// https://en.cppreference.com/w/cpp/language/function#Deleted_functions
//
// Typical case: copy constructor doesn't make sense for a particular class, so you want to make
// sure the no one tries to copy-construct an instance of the class, and that the
// compiler won't generate a copy constructor for you automatically.
// Traditional fix is to declare a
// copy constructor but never implement it, giving you a link-time error if anyone tries to use it.
// Now you can explicitly declare a function to be deleted, which has at least two advantages over
// the old way:
// * Makes the intention clear
// * Creates an error sooner, at compile time
class DoNotCopy
{
public:
DoNotCopy() {}
DoNotCopy(const DoNotCopy& ref) = delete;
};
template<> template<>
void cpp_features_test_object_t::test<6>()
{
DoNotCopy nc; // OK, default constructor
//DoNotCopy nc2(nc); // No, can't copy
//DoNotCopy nc3 = nc; // No, this also calls copy constructor (even though it looks like an assignment)
}
// defaulted function declaration
//
// https://en.cppreference.com/w/cpp/language/function#Function_definition
//
// What about the complementary case to the deleted function declaration, where you want a copy constructor
// and are happy with the default implementation the compiler will make (memberwise copy).
// Now you can explicitly declare that too.
// Usage: I guess it makes the intent clearer, but otherwise not obviously useful.
class DefaultCopyOK
{
public:
DefaultCopyOK(): mVal(123) {}
DefaultCopyOK(const DefaultCopyOK&) = default;
S32 val() const { return mVal; }
private:
S32 mVal;
};
template<> template<>
void cpp_features_test_object_t::test<7>()
{
DefaultCopyOK d; // OK
DefaultCopyOK d2(d); // OK
DefaultCopyOK d3 = d; // OK
ensure("default copy d", d.val()==123);
ensure("default copy d2", d.val()==d2.val());
ensure("default copy d3", d.val()==d3.val());
}
// initialize class members inline
//
// https://en.cppreference.com/w/cpp/language/data_members#Member_initialization
//
// Default class member values can be set where they are declared, using either brackets or =
// It is preferred to skip creating a constructor if all the work can be done by inline initialization:
// http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines.html#c45-dont-define-a-default-constructor-that-only-initializes-data-members-use-in-class-member-initializers-instead
//
class InitInline
{
public:
S32 mFoo{10};
};
class InitInlineWithConstructor
{
public:
// Here mFoo is not specified, so you will get the default value of 10.
// mBar is specified, so 25 will override the default value.
InitInlineWithConstructor():
mBar(25)
{}
// Default values set using two different styles, same effect.
S32 mFoo{10};
S32 mBar = 20;
};
template<> template<>
void cpp_features_test_object_t::test<8>()
{
InitInline ii;
ensure("init member inline 1", ii.mFoo==10);
InitInlineWithConstructor iici;
ensure("init member inline 2", iici.mFoo=10);
ensure("init member inline 3", iici.mBar==25);
}
// constexpr
//
// https://en.cppreference.com/w/cpp/language/constexpr
//
// Various things can be computed at compile time, and flagged as constexpr.
constexpr S32 compute2() { return 2; }
constexpr S32 ce_factorial(S32 n)
{
if (n<=0)
{
return 1;
}
else
{
return n*ce_factorial(n-1);
}
}
template<> template<>
void cpp_features_test_object_t::test<9>()
{
S32 val = compute2();
ensure("constexpr 1", val==2);
// Compile-time factorial. You used to need complex templates to do something this useless.
S32 fac5 = ce_factorial(5);
ensure("constexpr 2", fac5==120);
}
// static assert
//
// https://en.cppreference.com/w/cpp/language/static_assert
//
// You can add asserts to be checked at compile time. The thing to be checked must be a constexpr.
// There are two forms:
// * static_assert(expr);
// * static_assert(expr, message);
//
// Currently only the 2-parameter form works on windows. The 1-parameter form needs a flag we don't set.
template<> template<>
void cpp_features_test_object_t::test<10>()
{
// static_assert(ce_factorial(6)==720); No, needs a flag we don't currently set.
static_assert(ce_factorial(6)==720, "bad factorial"); // OK
}
// type aliases
//
// https://en.cppreference.com/w/cpp/language/type_alias
//
// You can use the "using" statement to create simpler templates that
// are aliases for more complex ones. "Template typedef"
// This makes stringmap<T> an alias for std::map<std::string, T>
template<typename T>
using stringmap = std::map<std::string, T>;
template<> template<>
void cpp_features_test_object_t::test<11>()
{
stringmap<S32> name_counts{ {"alice", 3}, {"bob", 2} };
ensure("type alias", name_counts["bob"]==2);
}
// Other possibilities:
// nullptr
// class enums
// std::unique_ptr and make_unique
// std::shared_ptr and make_shared
// lambdas
// perfect forwarding
// variadic templates
// std::thread
// std::mutex
// thread_local
// rvalue reference &&
// move semantics
// std::move
// string_view
} // namespace tut
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+9
View File
@@ -0,0 +1,9 @@
ATI NO MATCH
ATI Technologies NO MATCH
ATI Technologies Inc. NO MATCH
ATI Technologies Inc. (DNA-ATi 5.1.7.5x32) ATI Mobility Radeon HD 2 NO MATCH
ATI Technologies Inc. ATI Mobility Radeon Graphics NO MATCH
ATI Technologies Inc. ATI Radeon Graphics Processor NO MATCH
Intel NO MATCH
NVIDIA Corporation /PCI/SSE2 NO MATCH
NVIDIA Corporation Quadro PCI-E Series/PCI/SSE2 NO MATCH
+291
View File
@@ -0,0 +1,291 @@
/**
* @file llagentaccess_test.cpp
* @brief LLAgentAccess tests
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "../test/lltut.h"
#include "../llagentaccess.h"
#include "llcontrol.h"
#include "indra_constants.h"
#include <iostream>
//----------------------------------------------------------------------------
// Implementation of enough of LLControlGroup to support the tests:
static U32 test_preferred_maturity = SIM_ACCESS_PG;
LLControlGroup::LLControlGroup(const std::string& name)
: LLInstanceTracker<LLControlGroup, std::string>(name)
{
}
LLControlGroup::~LLControlGroup()
{
}
// Implementation of just the LLControlGroup methods we requre
LLControlVariable* LLControlGroup::declareU32(const std::string& name, U32 initial_val, const std::string& comment, LLControlVariable::ePersist persist)
{
test_preferred_maturity = initial_val;
return NULL;
}
void LLControlGroup::setU32(std::string_view name, U32 val)
{
test_preferred_maturity = val;
}
U32 LLControlGroup::getU32(std::string_view name)
{
return test_preferred_maturity;
}
//----------------------------------------------------------------------------
namespace tut
{
struct agentaccess
{
};
typedef test_group<agentaccess> agentaccess_t;
typedef agentaccess_t::object agentaccess_object_t;
tut::agentaccess_t tut_agentaccess("LLAgentAccess");
template<> template<>
void agentaccess_object_t::test<1>()
{
LLControlGroup cgr("test");
cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO);
LLAgentAccess aa(cgr);
cgr.setU32("PreferredMaturity", SIM_ACCESS_PG);
#ifndef HACKED_GODLIKE_VIEWER
ensure("1 prefersPG", aa.prefersPG());
ensure("1 prefersMature", !aa.prefersMature());
ensure("1 prefersAdult", !aa.prefersAdult());
#endif // HACKED_GODLIKE_VIEWER
cgr.setU32("PreferredMaturity", SIM_ACCESS_MATURE);
#ifndef HACKED_GODLIKE_VIEWER
ensure("2 prefersPG", !aa.prefersPG());
ensure("2 prefersMature", aa.prefersMature());
ensure("2 prefersAdult", !aa.prefersAdult());
#endif // HACKED_GODLIKE_VIEWER
cgr.setU32("PreferredMaturity", SIM_ACCESS_ADULT);
#ifndef HACKED_GODLIKE_VIEWER
ensure("3 prefersPG", !aa.prefersPG());
ensure("3 prefersMature", aa.prefersMature());
ensure("3 prefersAdult", aa.prefersAdult());
#endif // HACKED_GODLIKE_VIEWER
}
template<> template<>
void agentaccess_object_t::test<2>()
{
LLControlGroup cgr("test");
cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO);
LLAgentAccess aa(cgr);
// make sure default is PG
#ifndef HACKED_GODLIKE_VIEWER
ensure("1 isTeen", aa.isTeen());
ensure("1 isMature", !aa.isMature());
ensure("1 isAdult", !aa.isAdult());
#endif // HACKED_GODLIKE_VIEWER
// check the conversion routine
#ifndef HACKED_GODLIKE_VIEWER
ensure_equals("1 conversion", SIM_ACCESS_PG, aa.convertTextToMaturity('P'));
ensure_equals("2 conversion", SIM_ACCESS_MATURE, aa.convertTextToMaturity('M'));
ensure_equals("3 conversion", SIM_ACCESS_ADULT, aa.convertTextToMaturity('A'));
ensure_equals("4 conversion", SIM_ACCESS_MIN, aa.convertTextToMaturity('Q'));
#endif // HACKED_GODLIKE_VIEWER
// now try the other method of setting it - PG
aa.setMaturity('P');
ensure("2 isTeen", aa.isTeen());
#ifndef HACKED_GODLIKE_VIEWER
ensure("2 isMature", !aa.isMature());
ensure("2 isAdult", !aa.isAdult());
#endif // HACKED_GODLIKE_VIEWER
// Mature
aa.setMaturity('M');
#ifndef HACKED_GODLIKE_VIEWER
ensure("3 isTeen", !aa.isTeen());
ensure("3 isMature", aa.isMature());
ensure("3 isAdult", !aa.isAdult());
#endif // HACKED_GODLIKE_VIEWER
// Adult
aa.setMaturity('A');
#ifndef HACKED_GODLIKE_VIEWER
ensure("4 isTeen", !aa.isTeen());
ensure("4 isMature", aa.isMature());
ensure("4 isAdult", aa.isAdult());
#endif // HACKED_GODLIKE_VIEWER
}
template<> template<>
void agentaccess_object_t::test<3>()
{
LLControlGroup cgr("test");
cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO);
LLAgentAccess aa(cgr);
#ifndef HACKED_GODLIKE_VIEWER
ensure("starts normal", !aa.isGodlike());
#endif // HACKED_GODLIKE_VIEWER
aa.setGodLevel(GOD_NOT);
#ifndef HACKED_GODLIKE_VIEWER
ensure("stays normal", !aa.isGodlike());
#endif // HACKED_GODLIKE_VIEWER
aa.setGodLevel(GOD_FULL);
#ifndef HACKED_GODLIKE_VIEWER
ensure("sets full", aa.isGodlike());
#endif // HACKED_GODLIKE_VIEWER
aa.setGodLevel(GOD_NOT);
#ifndef HACKED_GODLIKE_VIEWER
ensure("resets normal", !aa.isGodlike());
#endif // HACKED_GODLIKE_VIEWER
aa.setAdminOverride(true);
#ifndef HACKED_GODLIKE_VIEWER
ensure("admin true", aa.getAdminOverride());
ensure("overrides 1", aa.isGodlike());
#endif // HACKED_GODLIKE_VIEWER
aa.setGodLevel(GOD_FULL);
#ifndef HACKED_GODLIKE_VIEWER
ensure("overrides 2", aa.isGodlike());
#endif // HACKED_GODLIKE_VIEWER
aa.setAdminOverride(false);
#ifndef HACKED_GODLIKE_VIEWER
ensure("admin false", !aa.getAdminOverride());
ensure("overrides 3", aa.isGodlike());
#endif // HACKED_GODLIKE_VIEWER
}
template<> template<>
void agentaccess_object_t::test<4>()
{
LLControlGroup cgr("test");
cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO);
LLAgentAccess aa(cgr);
#ifndef HACKED_GODLIKE_VIEWER
ensure("1 pg to start", aa.wantsPGOnly());
ensure("2 pg to start", !aa.canAccessMature());
ensure("3 pg to start", !aa.canAccessAdult());
#endif // HACKED_GODLIKE_VIEWER
aa.setGodLevel(GOD_FULL);
#ifndef HACKED_GODLIKE_VIEWER
ensure("1 full god", !aa.wantsPGOnly());
ensure("2 full god", aa.canAccessMature());
ensure("3 full god", aa.canAccessAdult());
#endif // HACKED_GODLIKE_VIEWER
aa.setGodLevel(GOD_NOT);
aa.setAdminOverride(true);
#ifndef HACKED_GODLIKE_VIEWER
ensure("1 admin mode", !aa.wantsPGOnly());
ensure("2 admin mode", aa.canAccessMature());
ensure("3 admin mode", aa.canAccessAdult());
#endif // HACKED_GODLIKE_VIEWER
aa.setAdminOverride(false);
aa.setMaturity('M');
// preferred is still pg by default
#ifndef HACKED_GODLIKE_VIEWER
ensure("1 mature pref pg", aa.wantsPGOnly());
ensure("2 mature pref pg", !aa.canAccessMature());
ensure("3 mature pref pg", !aa.canAccessAdult());
#endif // HACKED_GODLIKE_VIEWER
cgr.setU32("PreferredMaturity", SIM_ACCESS_MATURE);
#ifndef HACKED_GODLIKE_VIEWER
ensure("1 mature", !aa.wantsPGOnly());
ensure("2 mature", aa.canAccessMature());
ensure("3 mature", !aa.canAccessAdult());
#endif // HACKED_GODLIKE_VIEWER
cgr.setU32("PreferredMaturity", SIM_ACCESS_PG);
#ifndef HACKED_GODLIKE_VIEWER
ensure("1 mature pref pg", aa.wantsPGOnly());
ensure("2 mature pref pg", !aa.canAccessMature());
ensure("3 mature pref pg", !aa.canAccessAdult());
#endif // HACKED_GODLIKE_VIEWER
aa.setMaturity('A');
#ifndef HACKED_GODLIKE_VIEWER
ensure("1 adult pref pg", aa.wantsPGOnly());
ensure("2 adult pref pg", !aa.canAccessMature());
ensure("3 adult pref pg", !aa.canAccessAdult());
#endif // HACKED_GODLIKE_VIEWER
cgr.setU32("PreferredMaturity", SIM_ACCESS_ADULT);
#ifndef HACKED_GODLIKE_VIEWER
ensure("1 adult", !aa.wantsPGOnly());
ensure("2 adult", aa.canAccessMature());
ensure("3 adult", aa.canAccessAdult());
#endif // HACKED_GODLIKE_VIEWER
// make sure that even if pref is high, if access is low we block access
// this shouldn't occur in real life but we want to be safe
cgr.setU32("PreferredMaturity", SIM_ACCESS_ADULT);
aa.setMaturity('P');
#ifndef HACKED_GODLIKE_VIEWER
ensure("1 pref adult, actual pg", aa.wantsPGOnly());
ensure("2 pref adult, actual pg", !aa.canAccessMature());
ensure("3 pref adult, actual pg", !aa.canAccessAdult());
#endif // HACKED_GODLIKE_VIEWER
}
template<> template<>
void agentaccess_object_t::test<5>()
{
LLControlGroup cgr("test");
cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO);
LLAgentAccess aa(cgr);
cgr.setU32("PreferredMaturity", SIM_ACCESS_ADULT);
aa.setMaturity('M');
#ifndef HACKED_GODLIKE_VIEWER
ensure("1 preferred maturity pegged to M when maturity is M", cgr.getU32("PreferredMaturity") == SIM_ACCESS_MATURE);
#endif // HACKED_GODLIKE_VIEWER
aa.setMaturity('P');
#ifndef HACKED_GODLIKE_VIEWER
ensure("1 preferred maturity pegged to P when maturity is P", cgr.getU32("PreferredMaturity") == SIM_ACCESS_PG);
#endif // HACKED_GODLIKE_VIEWER
}
}
+201
View File
@@ -0,0 +1,201 @@
/**
* @file lldateutil_test.cpp
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "../test/lltut.h"
#include "../lldateutil.h"
#include "lldate.h"
#include "llstring.h" // LLStringUtil::format()
#include "lltrans.h"
#include "llui.h"
#include <map>
// Baked-in return values for getString()
std::map< std::string, std::string, std::less<>> gString;
// Baked-in return values for getCountString()
// map of pairs of input xml_desc and integer count
typedef std::pair< std::string, int > count_string_t;
std::map< count_string_t, std::string > gCountString;
std::string LLTrans::getString(const std::string_view xml_desc, const LLStringUtil::format_map_t& args, bool def_string)
{
auto it = gString.find(xml_desc);
if (it != gString.end())
{
std::string text = it->second;
LLStringUtil::format(text, args);
return text;
}
return {};
}
std::string LLTrans::getCountString(std::string_view language, std::string_view xml_desc, S32 count)
{
count_string_t key(xml_desc, count);
if (gCountString.find(key) == gCountString.end())
{
return std::string("Couldn't find ") + static_cast<std::string>(xml_desc);
}
return gCountString[ count_string_t(xml_desc, count) ];
}
std::string LLUI::getLanguage()
{
return "en";
}
namespace tut
{
struct dateutil
{
// Hard-code a "now" date so unit test doesn't change with
// current time. Because server strings are in Pacific time
// roll this forward 8 hours to compensate. This represents
// 2009-12-31T00:00:00Z UTC.
dateutil()
: mNow(std::string("2009-12-31T08:00:00Z"))
{
// copied from strings.xml
gString["YearsMonthsOld"] = "[AGEYEARS] [AGEMONTHS] old";
gString["YearsOld"] = "[AGEYEARS] old";
gString["MonthsOld"] = "[AGEMONTHS] old";
gString["WeeksOld"] = "[AGEWEEKS] old";
gString["DaysOld"] = "[AGEDAYS] old";
gString["TodayOld"] = "Joined today";
gCountString[ count_string_t("AgeYears", 1) ] = "1 year";
gCountString[ count_string_t("AgeYears", 2) ] = "2 years";
gCountString[ count_string_t("AgeMonths", 1) ] = "1 month";
gCountString[ count_string_t("AgeMonths", 2) ] = "2 months";
gCountString[ count_string_t("AgeMonths", 11) ]= "11 months";
gCountString[ count_string_t("AgeWeeks", 1) ] = "1 week";
gCountString[ count_string_t("AgeWeeks", 2) ] = "2 weeks";
gCountString[ count_string_t("AgeWeeks", 3) ] = "3 weeks";
gCountString[ count_string_t("AgeWeeks", 4) ] = "4 weeks";
gCountString[ count_string_t("AgeDays", 1) ] = "1 day";
gCountString[ count_string_t("AgeDays", 2) ] = "2 days";
}
LLDate mNow;
};
typedef test_group<dateutil> dateutil_t;
typedef dateutil_t::object dateutil_object_t;
tut::dateutil_t tut_dateutil("LLDateUtil");
template<> template<>
void dateutil_object_t::test<1>()
{
set_test_name("Years");
ensure_equals("years + months",
LLDateUtil::ageFromDate("10/30/2007", mNow),
"2 years 2 months old" );
ensure_equals("years",
LLDateUtil::ageFromDate("12/31/2007", mNow),
"2 years old" );
ensure_equals("years",
LLDateUtil::ageFromDate("1/1/2008", mNow),
"1 year 11 months old" );
ensure_equals("single year + one month",
LLDateUtil::ageFromDate("11/30/2008", mNow),
"1 year 1 month old" );
ensure_equals("single year + a bit",
LLDateUtil::ageFromDate("12/12/2008", mNow),
"1 year old" );
ensure_equals("single year",
LLDateUtil::ageFromDate("12/31/2008", mNow),
"1 year old" );
}
template<> template<>
void dateutil_object_t::test<2>()
{
set_test_name("Months");
ensure_equals("months",
LLDateUtil::ageFromDate("10/30/2009", mNow),
"2 months old" );
ensure_equals("months 2",
LLDateUtil::ageFromDate("10/31/2009", mNow),
"2 months old" );
ensure_equals("single month",
LLDateUtil::ageFromDate("11/30/2009", mNow),
"1 month old" );
}
template<> template<>
void dateutil_object_t::test<3>()
{
set_test_name("Weeks");
ensure_equals("4 weeks",
LLDateUtil::ageFromDate("12/1/2009", mNow),
"4 weeks old" );
ensure_equals("weeks",
LLDateUtil::ageFromDate("12/17/2009", mNow),
"2 weeks old" );
ensure_equals("single week",
LLDateUtil::ageFromDate("12/24/2009", mNow),
"1 week old" );
}
template<> template<>
void dateutil_object_t::test<4>()
{
set_test_name("Days");
ensure_equals("days",
LLDateUtil::ageFromDate("12/29/2009", mNow),
"2 days old" );
ensure_equals("single day",
LLDateUtil::ageFromDate("12/30/2009", mNow),
"1 day old" );
ensure_equals("today",
LLDateUtil::ageFromDate("12/31/2009", mNow),
"Joined today" );
}
template<> template<>
void dateutil_object_t::test<5>()
{
set_test_name("2010 rollover");
LLDate now(std::string("2010-01-04T12:00:00Z"));
ensure_equals("days",
LLDateUtil::ageFromDate("12/13/2009", now),
"3 weeks old" );
}
//template<> template<>
//void dateutil_object_t::test<6>()
//{
// set_test_name("ISO dates");
// LLDate now(std::string("2010-01-04T12:00:00Z"));
// ensure_equals("days",
// LLDateUtil::ageFromDateISO("2009-12-13", now),
// "3 weeks old" );
//}
}
+70
View File
@@ -0,0 +1,70 @@
/**
* @file lldir_stub.cpp
* @brief stub class to allow unit testing
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
// Use me only if you need to stub out some helper functions, not if you e.g. need sane numbers from countFilesInDir
LLDir::LLDir() {}
LLDir::~LLDir() {}
BOOL LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask) { return true; }
void LLDir::setChatLogsDir(const std::string &path) {}
void LLDir::setPerAccountChatLogsDir(const std::string &) {}
void LLDir::updatePerAccountChatLogsDir() {}
void LLDir::setLindenUserDir(const std::string &) {}
void LLDir::setSkinFolder(const std::string &skin_folder, const std::string& language) {}
bool LLDir::setCacheDir(const std::string &path) { return true; }
void LLDir::dumpCurrentDirectories(LLError::ELevel) {}
std::string LLDir::getSkinFolder() const { return ""; }
std::string LLDir::getLanguage() const { return ""; }
class LLDir_stub : public LLDir
{
public:
LLDir_stub() = default;
~LLDir_stub() = default;
void initAppDirs(const std::string &app_name, const std::string &) override {}
std::string getCurPath() override { return "CUR_PATH_FROM_LLDIR"; }
bool fileExists(const std::string &filename) const override { return false; }
std::string getLLPluginLauncher() override { return ""; }
std::string getLLPluginFilename(std::string base_name) override { return ""; }
};
LLDir_stub gDirUtil;
LLDir* gDirUtilp = &gDirUtil;
std::string LLDir::getExpandedFilename(ELLPath loc, const std::string& subdir, const std::string& filename) const
{
return subdir + " --- " + filename + " --- expanded!";
}
std::string LLDir::getExpandedFilename(ELLPath location, const std::string &filename) const
{
return filename + " --- expanded!";
}
+39
View File
@@ -0,0 +1,39 @@
/**
* @file llglslshader_stub.cpp
* @brief stub class to allow unit testing
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llglslshader.h"
void LLGLSLShader::uniform1f(const std::string& uniform, F32 num)
{
}
void LLGLSLShader::uniform3fv(const std::string& uniform, U32 count, const GLfloat *v)
{
}
void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v)
{
}
@@ -0,0 +1,328 @@
/**
* @file llhttpretrypolicy_test.cpp
* @brief Header tests to exercise the LLHTTPRetryPolicy classes.
*
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2013, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "../llviewerprecompiledheaders.h"
#include "../llhttpretrypolicy.h"
#include "lltut.h"
namespace tut
{
struct TestData
{
};
typedef test_group<TestData> RetryPolicyTestGroup;
typedef RetryPolicyTestGroup::object RetryPolicyTestObject;
RetryPolicyTestGroup retryPolicyTestGroup("retry_policy");
template<> template<>
void RetryPolicyTestObject::test<1>()
{
LLAdaptiveRetryPolicy never_retry(1.0,1.0,1.0,0);
LLSD headers;
F32 wait_seconds;
// No retry until we've failed a try.
ensure("never retry 0", !never_retry.shouldRetry(wait_seconds));
// 0 retries max.
never_retry.onFailure(500,headers);
ensure("never retry 1", !never_retry.shouldRetry(wait_seconds));
}
template<> template<>
void RetryPolicyTestObject::test<2>()
{
LLSD headers;
F32 wait_seconds;
// Normally only retry on server error (5xx)
LLAdaptiveRetryPolicy noRetry404(1.0,2.0,3.0,10);
noRetry404.onFailure(404,headers);
ensure("no retry on 404", !noRetry404.shouldRetry(wait_seconds));
// Can retry on 4xx errors if enabled by flag.
bool do_retry_4xx = true;
LLAdaptiveRetryPolicy doRetry404(1.0,2.0,3.0,10,do_retry_4xx);
doRetry404.onFailure(404,headers);
ensure("do retry on 404", doRetry404.shouldRetry(wait_seconds));
}
template<> template<>
void RetryPolicyTestObject::test<3>()
{
// Should retry after 1.0, 2.0, 3.0, 3.0 seconds.
LLAdaptiveRetryPolicy basic_retry(1.0,3.0,2.0,4);
LLSD headers;
F32 wait_seconds;
bool should_retry;
U32 frac_bits = 6;
// No retry until we've failed a try.
ensure("basic_retry 0", !basic_retry.shouldRetry(wait_seconds));
// Starting wait 1.0
basic_retry.onFailure(500,headers);
should_retry = basic_retry.shouldRetry(wait_seconds);
ensure("basic_retry 1", should_retry);
ensure_approximately_equals("basic_retry 1", wait_seconds, 1.0F, frac_bits);
// Double wait to 2.0
basic_retry.onFailure(500,headers);
should_retry = basic_retry.shouldRetry(wait_seconds);
ensure("basic_retry 2", should_retry);
ensure_approximately_equals("basic_retry 2", wait_seconds, 2.0F, frac_bits);
// Hit max wait of 3.0 (4.0 clamped to max 3)
basic_retry.onFailure(500,headers);
should_retry = basic_retry.shouldRetry(wait_seconds);
ensure("basic_retry 3", should_retry);
ensure_approximately_equals("basic_retry 3", wait_seconds, 3.0F, frac_bits);
// At max wait, should stay at 3.0
basic_retry.onFailure(500,headers);
should_retry = basic_retry.shouldRetry(wait_seconds);
ensure("basic_retry 4", should_retry);
ensure_approximately_equals("basic_retry 4", wait_seconds, 3.0F, frac_bits);
// Max retries, should fail now.
basic_retry.onFailure(500,headers);
should_retry = basic_retry.shouldRetry(wait_seconds);
ensure("basic_retry 5", !should_retry);
// Max retries, should fail now.
basic_retry.onFailure(500,headers);
should_retry = basic_retry.shouldRetry(wait_seconds);
ensure("basic_retry 5", !should_retry);
// After a success, should reset to the starting state.
basic_retry.onSuccess();
// No retry until we've failed a try.
ensure("basic_retry 6", !basic_retry.shouldRetry(wait_seconds));
// Starting wait 1.0
basic_retry.onFailure(500,headers);
should_retry = basic_retry.shouldRetry(wait_seconds);
ensure("basic_retry 7", should_retry);
ensure_approximately_equals("basic_retry 7", wait_seconds, 1.0F, frac_bits);
// Double wait to 2.0
basic_retry.onFailure(500,headers);
should_retry = basic_retry.shouldRetry(wait_seconds);
ensure("basic_retry 8", should_retry);
ensure_approximately_equals("basic_retry 8", wait_seconds, 2.0F, frac_bits);
}
// Retries should stop as soon as a non-5xx error is received.
template<> template<>
void RetryPolicyTestObject::test<4>()
{
// Should retry after 1.0, 2.0, 3.0, 3.0 seconds.
LLAdaptiveRetryPolicy killer404(1.0,3.0,2.0,4);
LLSD headers;
F32 wait_seconds;
bool should_retry;
U32 frac_bits = 6;
// Starting wait 1.0
killer404.onFailure(500,headers);
should_retry = killer404.shouldRetry(wait_seconds);
ensure("killer404 1", should_retry);
ensure_approximately_equals("killer404 1", wait_seconds, 1.0F, frac_bits);
// Double wait to 2.0
killer404.onFailure(500,headers);
should_retry = killer404.shouldRetry(wait_seconds);
ensure("killer404 2", should_retry);
ensure_approximately_equals("killer404 2", wait_seconds, 2.0F, frac_bits);
// Should fail on non-5xx
killer404.onFailure(404,headers);
should_retry = killer404.shouldRetry(wait_seconds);
ensure("killer404 3", !should_retry);
// After a non-5xx, should keep failing.
killer404.onFailure(500,headers);
should_retry = killer404.shouldRetry(wait_seconds);
ensure("killer404 4", !should_retry);
}
// Test handling of "retry-after" header. If present, this header
// value overrides the computed delay, but does not affect the
// progression of delay values. For example, if the normal
// progression of delays would be 1,2,4,8..., but the 2nd and 3rd calls
// get a retry header of 33, the pattern would become 1,33,33,8...
template<> template<>
void RetryPolicyTestObject::test<5>()
{
LLAdaptiveRetryPolicy policy(1.0,25.0,2.0,6);
LLSD headers_with_retry;
headers_with_retry[HTTP_IN_HEADER_RETRY_AFTER] = "666";
LLSD headers_without_retry;
F32 wait_seconds;
bool should_retry;
U32 frac_bits = 6;
policy.onFailure(500,headers_without_retry);
should_retry = policy.shouldRetry(wait_seconds);
ensure("retry header 1", should_retry);
ensure_approximately_equals("retry header 1", wait_seconds, 1.0F, frac_bits);
policy.onFailure(500,headers_without_retry);
should_retry = policy.shouldRetry(wait_seconds);
ensure("retry header 2", should_retry);
ensure_approximately_equals("retry header 2", wait_seconds, 2.0F, frac_bits);
policy.onFailure(500,headers_with_retry);
should_retry = policy.shouldRetry(wait_seconds);
ensure("retry header 3", should_retry);
// 4.0 overrides by header -> 666.0
ensure_approximately_equals("retry header 3", wait_seconds, 666.0F, frac_bits);
policy.onFailure(500,headers_with_retry);
should_retry = policy.shouldRetry(wait_seconds);
ensure("retry header 4", should_retry);
// 8.0 overrides by header -> 666.0
ensure_approximately_equals("retry header 4", wait_seconds, 666.0F, frac_bits);
policy.onFailure(500,headers_without_retry);
should_retry = policy.shouldRetry(wait_seconds);
ensure("retry header 5", should_retry);
ensure_approximately_equals("retry header 5", wait_seconds, 16.0F, frac_bits);
policy.onFailure(500,headers_without_retry);
should_retry = policy.shouldRetry(wait_seconds);
ensure("retry header 6", should_retry);
ensure_approximately_equals("retry header 6", wait_seconds, 25.0F, frac_bits);
policy.onFailure(500,headers_with_retry);
should_retry = policy.shouldRetry(wait_seconds);
ensure("retry header 7", !should_retry);
}
// Test getSecondsUntilRetryAfter(const std::string& retry_after, F32& seconds_to_wait),
// used by header parsing of the retry policy.
template<> template<>
void RetryPolicyTestObject::test<6>()
{
F32 seconds_to_wait;
bool success;
std::string str1("0");
seconds_to_wait = F32_MAX;
success = LLAdaptiveRetryPolicy::getSecondsUntilRetryAfter(str1, seconds_to_wait);
ensure("parse 1", success);
ensure_equals("parse 1", seconds_to_wait, 0.0);
std::string str2("999.9");
seconds_to_wait = F32_MAX;
success = LLAdaptiveRetryPolicy::getSecondsUntilRetryAfter(str2, seconds_to_wait);
ensure("parse 2", success);
ensure_approximately_equals("parse 2", seconds_to_wait, 999.9F, 8);
time_t nowseconds;
time(&nowseconds);
std::string str3 = LLDate((F64)(nowseconds+44)).asRFC1123();
seconds_to_wait = F32_MAX;
success = LLAdaptiveRetryPolicy::getSecondsUntilRetryAfter(str3, seconds_to_wait);
std::cerr << " str3 [" << str3 << "]" << std::endl;
ensure("parse 3", success);
ensure_approximately_equals_range("parse 3", seconds_to_wait, 44.0F, 2.0F);
}
// Test retry-after field in both llmessage and CoreHttp headers.
template<> template<>
void RetryPolicyTestObject::test<7>()
{
std::cerr << "7 starts" << std::endl;
LLSD sd_headers;
time_t nowseconds;
time(&nowseconds);
LLAdaptiveRetryPolicy policy(17.0,644.0,3.0,5);
F32 seconds_to_wait;
bool should_retry;
// No retry until we've failed a try.
ensure("header 0", !policy.shouldRetry(seconds_to_wait));
// no retry header, use default.
policy.onFailure(500,LLSD());
should_retry = policy.shouldRetry(seconds_to_wait);
ensure("header 1", should_retry);
ensure_approximately_equals("header 1", seconds_to_wait, 17.0F, 6);
// retry header should override, give delay of 0
std::string date_string = LLDate((F64)(nowseconds+7)).asRFC1123();
sd_headers[HTTP_IN_HEADER_RETRY_AFTER] = date_string;
policy.onFailure(503,sd_headers);
should_retry = policy.shouldRetry(seconds_to_wait);
ensure("header 2", should_retry);
ensure_approximately_equals_range("header 2", seconds_to_wait, 7.0F, 2.0F);
LLCore::HttpResponse *response;
LLCore::HttpHeaders::ptr_t headers;
response = new LLCore::HttpResponse();
headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders());
response->setStatus(503);
response->setHeaders(headers);
headers->append(HTTP_IN_HEADER_RETRY_AFTER, std::string("600"));
policy.onFailure(response);
should_retry = policy.shouldRetry(seconds_to_wait);
ensure("header 3",should_retry);
ensure_approximately_equals("header 3", seconds_to_wait, 600.0F, 6);
response->release();
response = new LLCore::HttpResponse();
headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders());
response->setStatus(503);
response->setHeaders(headers);
time(&nowseconds);
date_string = LLDate((F64)(nowseconds+77)).asRFC1123();
std::cerr << "date_string [" << date_string << "]" << std::endl;
headers->append(HTTP_IN_HEADER_RETRY_AFTER,date_string);
policy.onFailure(response);
should_retry = policy.shouldRetry(seconds_to_wait);
ensure("header 4",should_retry);
ensure_approximately_equals_range("header 4", seconds_to_wait, 77.0F, 2.0F);
response->release();
// Timeout should be clamped at max.
policy.onFailure(500,LLSD());
should_retry = policy.shouldRetry(seconds_to_wait);
ensure("header 5", should_retry);
ensure_approximately_equals("header 5", seconds_to_wait, 644.0F, 6);
// No more retries.
policy.onFailure(500,LLSD());
should_retry = policy.shouldRetry(seconds_to_wait);
ensure("header 6", !should_retry);
}
}
@@ -0,0 +1,511 @@
/**
* @file lllogininstance_test.cpp
* @brief Test for lllogininstance.cpp.
*
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
// Precompiled header
#include "../llviewerprecompiledheaders.h"
// Own header
#include "../llsecapi.h"
#include "../llviewernetwork.h"
#include "../lllogininstance.h"
// Needed for Auth Test
#include "../llhasheduniqueid.h"
// STL headers
// std headers
// external library headers
// other Linden headers
#include "../test/lltut.h"
#include "llevents.h"
#include "llnotificationsutil.h"
#include "lltrans.h"
#if defined(LL_WINDOWS)
#pragma warning(disable: 4355) // using 'this' in base-class ctor initializer expr
#pragma warning(disable: 4702) // disable 'unreachable code' so we can safely use skip().
#endif
// Constants
const std::string VIEWERLOGIN_URI("viewerlogin_uri");
const std::string VIEWERLOGIN_GRIDLABEL("viewerlogin_grid");
const std::string APPVIEWER_SERIALNUMBER("appviewer_serialno");
const std::string VIEWERLOGIN_CHANNEL("invalid_channel");
const std::string VIEWERLOGIN_VERSION("invalid_version");
// Link seams.
//-----------------------------------------------------------------------------
static LLEventStream gTestPump("test_pump");
#include "../llslurl.h"
#include "../llstartup.h"
LLSLURL LLStartUp::sStartSLURL;
LLSLURL& LLStartUp::getStartSLURL() { return sStartSLURL; }
#include "lllogin.h"
static std::string gLoginURI;
static LLSD gLoginCreds;
static bool gDisconnectCalled = false;
#include "../llviewerwindow.h"
void LLViewerWindow::setShowProgress(bool show) {}
LLProgressView * LLViewerWindow::getProgressView(void) const { return 0; }
LLViewerWindow* gViewerWindow;
std::string LLTrans::getString(std::string_view xml_desc, const LLStringUtil::format_map_t& args, bool def_string)
{
return std::string("test_trans");
}
class LLLogin::Impl
{
};
LLLogin::LLLogin() {}
LLLogin::~LLLogin() {}
LLEventPump& LLLogin::getEventPump() { return gTestPump; }
void LLLogin::connect(const std::string& uri, const LLSD& credentials)
{
gLoginURI = uri;
gLoginCreds = credentials;
}
void LLLogin::disconnect()
{
gDisconnectCalled = true;
}
LLSD LLCredential::getLoginParams()
{
LLSD result = LLSD::emptyMap();
// legacy credential
result["passwd"] = "$1$testpasssd";
result["first"] = "myfirst";
result["last"] ="mylast";
return result;
}
void LLCredential::identifierType(std::string &idType)
{
}
void LLCredential::authenticatorType(std::string &idType)
{
}
LLNotificationPtr LLNotificationsUtil::add(const std::string& name,
const LLSD& substitutions,
const LLSD& payload,
boost::function<void (const LLSD&, const LLSD&)> functor)
{
return LLNotificationPtr((LLNotification*)NULL);
}
LLNotificationPtr LLNotificationsUtil::add(const std::string& name, const LLSD& args)
{
return LLNotificationPtr((LLNotification*)NULL);
}
//-----------------------------------------------------------------------------
#include "../llviewernetwork.h"
LLGridManager::~LLGridManager()
{
}
bool LLGridManager::addGrid(LLSD& grid_data)
{
return true;
}
LLGridManager::LLGridManager()
:
mIsInProductionGrid(false)
{
}
void LLGridManager::getLoginURIs(std::vector<std::string>& uris)
{
uris.push_back(VIEWERLOGIN_URI);
}
void LLGridManager::addSystemGrid(const std::string& label,
const std::string& name,
const std::string& login,
const std::string& helper,
const std::string& login_page,
const std::string& update_url_base,
const std::string& web_profile_url,
const std::string& login_id)
{
}
std::map<std::string, std::string> LLGridManager::getKnownGrids()
{
std::map<std::string, std::string> result;
return result;
}
void LLGridManager::setGridChoice(const std::string& grid_name)
{
}
bool LLGridManager::isInSLMain()
{
return false;
}
bool LLGridManager::isInSLBeta()
{
return false;
}
// <FS:CR>
bool LLGridManager::isInSecondlife()
{
return false;
}
#ifdef OPENSIM
bool LLGridManager::isInOpenSim()
{
return false;
}
bool LLGridManager::isInAuroraSim()
{
return false;
}
#endif // OPENSIM
// </FS:CR>
std::string LLGridManager::getSLURLBase(const std::string& grid_name)
{
return "myslurl";
}
std::string LLGridManager::getAppSLURLBase(const std::string& grid_name)
{
return "myappslurl";
}
std::string LLGridManager::getGridId(const std::string& grid)
{
return std::string();
}
//-----------------------------------------------------------------------------
#include "../llviewercontrol.h"
LLControlGroup gSavedSettings("Global");
LLControlGroup::LLControlGroup(const std::string& name) :
LLInstanceTracker<LLControlGroup, std::string>(name){}
LLControlGroup::~LLControlGroup() {}
void LLControlGroup::setBOOL(std::string_view name, bool val) {}
bool LLControlGroup::getBOOL(std::string_view name) { return false; }
F32 LLControlGroup::getF32(std::string_view name) { return 0.0f; }
U32 LLControlGroup::saveToFile(const std::string& filename, bool nondefault_only) { return 1; }
void LLControlGroup::setString(std::string_view name, const std::string& val) {}
std::string LLControlGroup::getString(std::string_view name) { return "test_string"; }
LLControlVariable* LLControlGroup::declareBOOL(const std::string& name, bool initial_val, const std::string& comment, LLControlVariable::ePersist persist) { return NULL; }
LLControlVariable* LLControlGroup::declareString(const std::string& name, const std::string &initial_val, const std::string& comment, LLControlVariable::ePersist persist) { return NULL; }
#include "lluicolortable.h"
void LLUIColorTable::saveUserSettings(void)const {}
//-----------------------------------------------------------------------------
#include "../llversioninfo.h"
bool llHashedUniqueID(unsigned char* id)
{
memcpy( id, "66666666666666666666666666666666", MD5HEX_STR_SIZE );
return true;
}
//-----------------------------------------------------------------------------
#include "../llappviewer.h"
void LLAppViewer::forceQuit(void) {}
bool LLAppViewer::isUpdaterMissing() { return true; }
bool LLAppViewer::waitForUpdater() { return false; }
LLAppViewer * LLAppViewer::sInstance = 0;
//-----------------------------------------------------------------------------
#include "llnotifications.h"
#include "llfloaterreg.h"
static std::string gTOSType;
static LLEventPump * gTOSReplyPump = NULL;
LLPointer<LLSecAPIHandler> gSecAPIHandler;
//static
LLFloater* LLFloaterReg::showInstance(std::string_view name, const LLSD& key, bool focus)
{
gTOSType = name;
gTOSReplyPump = &LLEventPumps::instance().obtain(key["reply_pump"]);
return NULL;
}
//----------------------------------------------------------------------------
#include "../llprogressview.h"
void LLProgressView::setText(std::string const &){}
void LLProgressView::setPercent(float){}
void LLProgressView::setMessage(std::string const &){}
//-----------------------------------------------------------------------------
// LLNotifications
class MockNotifications : public LLNotificationsInterface
{
boost::function<void (const LLSD&, const LLSD&)> mResponder;
int mAddedCount;
public:
MockNotifications() :
mResponder(0),
mAddedCount(0)
{
}
virtual ~MockNotifications() {}
/* virtual */ LLNotificationPtr add(
const std::string& name,
const LLSD& substitutions,
const LLSD& payload,
LLNotificationFunctorRegistry::ResponseFunctor functor)
{
mResponder = functor;
mAddedCount++;
return LLNotificationPtr((LLNotification*)NULL);
}
void sendYesResponse()
{
LLSD notification;
LLSD response;
response = 1;
mResponder(notification, response);
}
void sendNoResponse()
{
LLSD notification;
LLSD response;
response = 2;
mResponder(notification, response);
}
void sendBogusResponse()
{
LLSD notification;
LLSD response;
response = 666;
mResponder(notification, response);
}
int addedCount() { return mAddedCount; }
};
S32 LLNotification::getSelectedOption(const LLSD& notification, const LLSD& response)
{
return response.asInteger();
}
//-----------------------------------------------------------------------------
#include "../llmachineid.h"
unsigned char gMACAddress[MAC_ADDRESS_BYTES] = {77,21,46,31,89,2};
S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len)
{
memcpy(unique_id, gMACAddress, len);
return 1;
}
S32 LLMachineID::getLegacyID(unsigned char *unique_id, size_t len)
{
return 0;
}
//-----------------------------------------------------------------------------
// misc
std::string xml_escape_string(const std::string& in)
{
return in;
}
/*****************************************************************************
* TUT
*****************************************************************************/
namespace tut
{
struct lllogininstance_data
{
lllogininstance_data() : logininstance(LLLoginInstance::getInstance())
{
// Global initialization
gLoginURI.clear();
gLoginCreds.clear();
gDisconnectCalled = false;
gTOSType = ""; // Set to invalid value.
gTOSReplyPump = 0; // clear the callback.
gSavedSettings.declareBOOL("NoInventoryLibrary", false, "", LLControlVariable::PERSIST_NO);
gSavedSettings.declareBOOL("ConnectAsGod", false, "", LLControlVariable::PERSIST_NO);
gSavedSettings.declareBOOL("UseDebugMenus", false, "", LLControlVariable::PERSIST_NO);
gSavedSettings.declareString("ClientSettingsFile", "test_settings.xml", "", LLControlVariable::PERSIST_NO);
gSavedSettings.declareString("NextLoginLocation", "", "", LLControlVariable::PERSIST_NO);
gSavedSettings.declareBOOL("LoginLastLocation", false, "", LLControlVariable::PERSIST_NO);
gSavedSettings.declareBOOL("CmdLineSkipUpdater", true, "", LLControlVariable::PERSIST_NO);
LLSD authenticator = LLSD::emptyMap();
LLSD identifier = LLSD::emptyMap();
identifier["type"] = "agent";
identifier["first_name"] = "testfirst";
identifier["last_name"] = "testlast";
authenticator["passwd"] = "testpass";
agentCredential = new LLCredential();
agentCredential->setCredentialData(identifier, authenticator);
authenticator = LLSD::emptyMap();
identifier = LLSD::emptyMap();
identifier["type"] = "account";
identifier["username"] = "testuser";
authenticator["secret"] = "testsecret";
accountCredential = new LLCredential();
accountCredential->setCredentialData(identifier, authenticator);
logininstance->setNotificationsInterface(&notifications);
logininstance->setPlatformInfo("win", "1.3.5", "Windows Bogus Version 100.6.6.6");
}
LLLoginInstance* logininstance;
LLPointer<LLCredential> agentCredential;
LLPointer<LLCredential> accountCredential;
MockNotifications notifications;
};
typedef test_group<lllogininstance_data> lllogininstance_group;
typedef lllogininstance_group::object lllogininstance_object;
lllogininstance_group llsdmgr("LLLoginInstance");
template<> template<>
void lllogininstance_object::test<1>()
{
set_test_name("Test Simple Success And Disconnect");
// Test default connect.
logininstance->connect(agentCredential);
ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI);
// Dummy success response.
LLSD response;
response["state"] = "online";
response["change"] = "connect";
response["progress"] = 1.0;
response["transfer_rate"] = 7;
response["data"] = "test_data";
gTestPump.post(response);
ensure("Success response", logininstance->authSuccess());
ensure_equals("Test Response Data", logininstance->getResponse().asString(), "test_data");
logininstance->disconnect();
ensure_equals("Called Login Module Disconnect", gDisconnectCalled, true);
response.clear();
response["state"] = "offline";
response["change"] = "disconnect";
response["progress"] = 0.0;
response["transfer_rate"] = 0;
response["data"] = "test_data";
gTestPump.post(response);
ensure("Disconnected", !(logininstance->authSuccess()));
}
template<> template<>
void lllogininstance_object::test<2>()
{
set_test_name("Test User TOS/Critical message Interaction");
const std::string test_uri = "testing-uri";
// Test default connect.
logininstance->connect(test_uri, agentCredential);
// connect should call LLLogin::connect to init gLoginURI and gLoginCreds.
ensure_equals("Default connect uri", gLoginURI, "testing-uri");
ensure_equals("Default for agree to tos", gLoginCreds["params"]["agree_to_tos"].asBoolean(), false);
ensure_equals("Default for read critical", gLoginCreds["params"]["read_critical"].asBoolean(), false);
// TOS failure response.
LLSD response;
response["state"] = "offline";
response["change"] = "fail.login";
response["progress"] = 0.0;
response["transfer_rate"] = 7;
response["data"]["reason"] = "tos";
gTestPump.post(response);
ensure_equals("TOS Dialog type", gTOSType, "message_tos");
ensure("TOS callback given", gTOSReplyPump != 0);
gTOSReplyPump->post(false); // Call callback denying TOS.
ensure("No TOS, failed auth", logininstance->authFailure());
// Start again.
logininstance->connect(test_uri, agentCredential);
gTestPump.post(response); // Fail for tos again.
gTOSReplyPump->post(true); // Accept tos, should reconnect w/ agree_to_tos.
ensure_equals("Accepted agree to tos", gLoginCreds["params"]["agree_to_tos"].asBoolean(), true);
ensure("Incomplete login status", !logininstance->authFailure() && !logininstance->authSuccess());
// Fail connection, attempt connect again.
// The new request should have reset agree to tos to default.
response["data"]["reason"] = "key"; // bad creds.
gTestPump.post(response);
ensure("TOS auth failure", logininstance->authFailure());
logininstance->connect(test_uri, agentCredential);
ensure_equals("Reset to default for agree to tos", gLoginCreds["params"]["agree_to_tos"].asBoolean(), false);
// Critical Message failure response.
logininstance->connect(test_uri, agentCredential);
response["data"]["reason"] = "critical"; // Change response to "critical message"
gTestPump.post(response);
ensure_equals("TOS Dialog type", gTOSType, "message_critical");
ensure("TOS callback given", gTOSReplyPump != 0);
gTOSReplyPump->post(true);
ensure_equals("Accepted read critical message", gLoginCreds["params"]["read_critical"].asBoolean(), true);
ensure("Incomplete login status", !logininstance->authFailure() && !logininstance->authSuccess());
// Fail then attempt new connection
response["data"]["reason"] = "key"; // bad creds.
gTestPump.post(response);
ensure("TOS auth failure", logininstance->authFailure());
logininstance->connect(test_uri, agentCredential);
ensure_equals("Default for agree to tos", gLoginCreds["params"]["read_critical"].asBoolean(), false);
}
}
@@ -0,0 +1,973 @@
/**
* @file llmediadataclient_test.cpp
* @brief LLMediaDatClient tests
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "../llviewerprecompiledheaders.h"
#include <iostream>
#include "../test/lltut.h"
#include "llsdserialize.h"
#include "llsdutil.h"
#include "llerrorcontrol.h"
#include "llhttpconstants.h"
#include "../llmediadataclient.h"
#include "../llvovolume.h"
#include "../../llprimitive/llmediaentry.cpp"
#include "../../llprimitive/llmaterialid.cpp"
#include "../../llprimitive/lltextureentry.cpp"
#include "../../llmessage/tests/llcurl_stub.cpp"
#if LL_WINDOWS
#pragma warning (push)
#pragma warning (disable : 4702) // boost::lexical_cast generates this warning
#endif
#include <boost/lexical_cast.hpp>
#if LL_WINDOWS
#pragma warning (pop)
#endif
#define VALID_OBJECT_ID "3607d5c4-644b-4a8a-871a-8b78471af2a2"
#define VALID_OBJECT_ID_1 "11111111-1111-1111-1111-111111111111"
#define VALID_OBJECT_ID_2 "22222222-2222-2222-2222-222222222222"
#define VALID_OBJECT_ID_3 "33333333-3333-3333-3333-333333333333"
#define VALID_OBJECT_ID_4 "44444444-4444-4444-4444-444444444444"
#define FAKE_OBJECT_MEDIA_CAP_URL "foo_ObjectMedia"
#define FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL "foo_ObjectMediaNavigate"
#define FAKE_OBJECT_MEDIA_CAP_URL_503 "foo_ObjectMedia_503"
#define FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL_ERROR "foo_ObjectMediaNavigate_ERROR"
#define MEDIA_DATA "\
<array> \
<string>http://foo.example.com</string> \
<string>http://bar.example.com</string> \
<string>baz</string> \
</array>"
#define _DATA_URLS(ID,INTEREST,NEW,URL1,URL2) " \
<llsd> \
<map> \
<key>uuid</key> \
<string>" ID "</string> \
<key>interest</key> \
<real>" INTEREST "</real> \
<key>cap_urls</key> \
<map> \
<key>ObjectMedia</key> \
<string>" URL1 "</string> \
<key>ObjectMediaNavigate</key> \
<string>" URL2 "</string> \
</map> \
<key>media_data</key> \
" MEDIA_DATA " \
<key>is_dead</key> \
<boolean>false</boolean> \
<key>is_new</key> \
<boolean>" NEW "</boolean> \
</map> \
</llsd>"
#define _DATA(ID,INTEREST,NEW) _DATA_URLS(ID,INTEREST,NEW,FAKE_OBJECT_MEDIA_CAP_URL,FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL)
const char *DATA = _DATA(VALID_OBJECT_ID,"1.0","true");
#define STR(I) boost::lexical_cast<std::string>(I)
#define LOG_TEST(N) LL_DEBUGS("LLMediaDataClient") << "\n" << \
"================================================================================\n" << \
"==================================== TEST " #N " ===================================\n" << \
"================================================================================\n" << LL_ENDL;
LLSD *gPostRecords = NULL;
F64 gMinimumInterestLevel = (F64)0.0;
#if 0
// stubs:
void LLHTTPClient::post(
const std::string& url,
const LLSD& body,
LLHTTPClient::ResponderPtr responder,
const LLSD& headers,
const F32 timeout)
{
LLSD record;
record["url"] = url;
record["body"] = body;
record["headers"] = headers;
record["timeout"] = timeout;
gPostRecords->append(record);
// Magic URL that triggers a 503:
LLSD result;
result[LLTextureEntry::OBJECT_ID_KEY] = body[LLTextureEntry::OBJECT_ID_KEY];
if ( url == FAKE_OBJECT_MEDIA_CAP_URL_503 )
{
LLSD content;
content["reason"] = "fake reason";
responder->failureResult(HTTP_SERVICE_UNAVAILABLE, "fake reason", content);
return;
}
else if (url == FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL_ERROR)
{
LLSD error;
error["code"] = LLObjectMediaNavigateClient::ERROR_PERMISSION_DENIED_CODE;
result["error"] = error;
}
responder->successResult(result);
}
#endif
const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f;
class LLMediaDataClientObjectTest : public LLMediaDataClientObject
{
public:
LLMediaDataClientObjectTest(const char *data)
{
std::istringstream d(data);
LLSDSerialize::fromXML(mRep, d);
mNumBounceBacks = 0;
// std::cout << ll_pretty_print_sd(mRep) << std::endl;
// std::cout << "ID: " << getID() << std::endl;
}
LLMediaDataClientObjectTest(const LLSD &rep)
: mRep(rep), mNumBounceBacks(0) {}
~LLMediaDataClientObjectTest()
{ LL_DEBUGS("LLMediaDataClient") << "~LLMediaDataClientObjectTest" << LL_ENDL; }
virtual U8 getMediaDataCount() const
{ return mRep["media_data"].size(); }
virtual LLSD getMediaDataLLSD(U8 index) const
{ return mRep["media_data"][(LLSD::Integer)index]; }
virtual bool isCurrentMediaUrl(U8 index, const std::string &url) const
{ return (mRep["media_data"][(LLSD::Integer)index].asString() == url); }
virtual LLUUID getID() const
{ return mRep["uuid"]; }
virtual void mediaNavigateBounceBack(U8 index)
{ mNumBounceBacks++; }
virtual bool hasMedia() const
{ return mRep.has("media_data"); }
virtual void updateObjectMediaData(LLSD const &media_data_array, const std::string &media_version)
{ mRep["media_data"] = media_data_array; mRep["media_version"] = media_version; }
virtual F64 getMediaInterest() const
{ return (LLSD::Real)mRep["interest"]; }
virtual bool isInterestingEnough() const
{ return getMediaInterest() > gMinimumInterestLevel; }
virtual std::string getCapabilityUrl(const std::string &name) const
{ return mRep["cap_urls"][name]; }
virtual bool isDead() const
{ return mRep["is_dead"]; }
virtual U32 getMediaVersion() const
{ return (LLSD::Integer)mRep["media_version"]; }
virtual bool isNew() const
{ return mRep["is_new"]; }
void setMediaInterest(F64 val)
{ mRep["interest"] = val; }
int getNumBounceBacks() const
{ return mNumBounceBacks; }
void markDead()
{ mRep["is_dead"] = true; }
void markOld()
{ mRep["is_new"] = false; }
private:
LLSD mRep;
int mNumBounceBacks;
};
// This special timer delay should ensure that the timer will fire on the very
// next pump, no matter what (though this does make an assumption about the
// implementation of LLEventTimer::updateClass()):
const F32 NO_PERIOD = -1000.0f;
static void pump_timers()
{
LLEventTimer::updateClass();
}
namespace tut
{
struct mediadataclient
{
mediadataclient() {
gPostRecords = &mLLSD;
gMinimumInterestLevel = (F64)0.0;
// LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
// LLError::setClassLevel("LLMediaDataClient", LLError::LEVEL_DEBUG);
// LLError::setTagLevel("MediaOnAPrim", LLError::LEVEL_DEBUG);
}
LLSD mLLSD;
};
typedef test_group<mediadataclient> mediadataclient_t;
typedef mediadataclient_t::object mediadataclient_object_t;
tut::mediadataclient_t tut_mediadataclient("LLMediaDataClient");
void ensure(const std::string &msg, int value, int expected)
{
std::string m = msg;
m += " value: " + STR(value);
m += ", expected: " + STR(expected);
ensure(m, value == expected);
}
void ensure(const std::string &msg, const std::string & value, const std::string & expected)
{
std::string m = msg;
m += " value: " + value;
m += ", expected: " + expected;
ensure(m, value == expected);
}
void ensure(const std::string &msg, const LLUUID & value, const LLUUID & expected)
{
std::string m = msg;
m += " value: " + value.asString();
m += ", expected: " + expected.asString();
ensure(m, value == expected);
}
void ensure_llsd(const std::string &msg, const LLSD & value, const char *expected)
{
LLSD expected_llsd;
std::istringstream e(expected);
LLSDSerialize::fromXML(expected_llsd, e);
std::string value_str = ll_pretty_print_sd(value);
std::string expected_str = ll_pretty_print_sd(expected_llsd);
std::string m = msg;
m += " value: " + value_str;
m += ", expected: " + expected_str;
ensure(m, value_str == expected_str);
}
//////////////////////////////////////////////////////////////////////////////////////////
template<> template<>
void mediadataclient_object_t::test<1>()
{
//
// Test fetchMedia()
//
LOG_TEST(1);
LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest(DATA);
int num_refs_start = o->getNumRefs();
{
LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
mdc->fetchMedia(o);
// Make sure no posts happened yet...
ensure("post records", gPostRecords->size(), 0);
::pump_timers();
ensure("post records", gPostRecords->size(), 1);
ensure("post url", (*gPostRecords)[0]["url"], FAKE_OBJECT_MEDIA_CAP_URL);
ensure("post GET", (*gPostRecords)[0]["body"]["verb"], "GET");
ensure("post object id", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID));
ensure("queue empty", mdc->isEmpty());
}
// Make sure everyone's destroyed properly
ensure("REF COUNT", o->getNumRefs(), num_refs_start);
}
//////////////////////////////////////////////////////////////////////////////////////////
template<> template<>
void mediadataclient_object_t::test<2>()
{
//
// Test updateMedia()
//
LOG_TEST(2);
LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest(DATA);
{
// queue time w/ no delay ensures that ::pump_timers() will hit the tick()
LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
mdc->updateMedia(o);
ensure("post records", gPostRecords->size(), 0);
::pump_timers();
ensure("post records", gPostRecords->size(), 1);
ensure("post url", (*gPostRecords)[0]["url"], FAKE_OBJECT_MEDIA_CAP_URL);
ensure("post UPDATE", (*gPostRecords)[0]["body"]["verb"], "UPDATE");
ensure("post object id", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID));
ensure_llsd("post data llsd", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_MEDIA_DATA_KEY],
"<llsd>" MEDIA_DATA "</llsd>");
ensure("queue empty", mdc->isEmpty());
}
ensure("REF COUNT", o->getNumRefs(), 1);
}
//////////////////////////////////////////////////////////////////////////////////////////
template<> template<>
void mediadataclient_object_t::test<3>()
{
//
// Test navigate()
//
LOG_TEST(3);
LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest(DATA);
{
LLPointer<LLObjectMediaNavigateClient> mdc = new LLObjectMediaNavigateClient(NO_PERIOD,NO_PERIOD);
const char *TEST_URL = "http://example.com";
mdc->navigate(o, 0, TEST_URL);
ensure("post records", gPostRecords->size(), 0);
::pump_timers();
// ensure no bounce back
ensure("bounce back", dynamic_cast<LLMediaDataClientObjectTest*>(static_cast<LLMediaDataClientObject*>(o))->getNumBounceBacks(), 0);
ensure("post records", gPostRecords->size(), 1);
ensure("post url", (*gPostRecords)[0]["url"], FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL);
ensure("post object id", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID));
ensure("post data", (*gPostRecords)[0]["body"][LLTextureEntry::TEXTURE_INDEX_KEY], 0);
ensure("post data", (*gPostRecords)[0]["body"][LLMediaEntry::CURRENT_URL_KEY], TEST_URL);
ensure("queue empty", mdc->isEmpty());
}
ensure("REF COUNT", o->getNumRefs(), 1);
}
//////////////////////////////////////////////////////////////////////////////////////////
template<> template<>
void mediadataclient_object_t::test<4>()
{
//
// Test queue ordering
//
LOG_TEST(4);
LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(
_DATA(VALID_OBJECT_ID_1,"1.0","true"));
LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(
_DATA(VALID_OBJECT_ID_2,"3.0","true"));
LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(
_DATA(VALID_OBJECT_ID_3,"2.0","true"));
{
LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
const char *ORDERED_OBJECT_IDS[] = { VALID_OBJECT_ID_2, VALID_OBJECT_ID_3, VALID_OBJECT_ID_1 };
mdc->fetchMedia(o1);
mdc->fetchMedia(o2);
mdc->fetchMedia(o3);
// Make sure no posts happened yet...
ensure("post records", gPostRecords->size(), 0);
// tick 3 times...
::pump_timers();
ensure("post records", gPostRecords->size(), 1);
::pump_timers();
ensure("post records", gPostRecords->size(), 2);
::pump_timers();
ensure("post records", gPostRecords->size(), 3);
for( int i=0; i < 3; i++ )
{
ensure("[" + STR(i) + "] post url", (*gPostRecords)[i]["url"], FAKE_OBJECT_MEDIA_CAP_URL);
ensure("[" + STR(i) + "] post GET", (*gPostRecords)[i]["body"]["verb"], "GET");
ensure("[" + STR(i) + "] post object id", (*gPostRecords)[i]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(),
LLUUID(ORDERED_OBJECT_IDS[i]));
}
ensure("queue empty", mdc->isEmpty());
}
ensure("refcount of o1", o1->getNumRefs(), 1);
ensure("refcount of o2", o2->getNumRefs(), 1);
ensure("refcount of o3", o3->getNumRefs(), 1);
}
//////////////////////////////////////////////////////////////////////////////////////////
template<> template<>
void mediadataclient_object_t::test<5>()
{
//
// Test fetchMedia() getting a 503 error
//
LOG_TEST(5);
LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest(
_DATA_URLS(VALID_OBJECT_ID,
"1.0","true",
FAKE_OBJECT_MEDIA_CAP_URL_503,
FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL));
int num_refs_start = o->getNumRefs();
{
const int NUM_RETRIES = 5;
LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD,NUM_RETRIES);
// This should generate a retry
mdc->fetchMedia(o);
// Make sure no posts happened yet...
ensure("post records before", gPostRecords->size(), 0);
// Once, causes retry
// Second, fires retry timer
// Third, fires queue timer again
for (int i=0; i<NUM_RETRIES; ++i)
{
::pump_timers(); // Should pump (fire) the queue timer, causing a retry timer to be scheduled
// XXX This ensure is not guaranteed, because scheduling a timer might actually get it pumped in the same loop
//ensure("post records " + STR(i), gPostRecords->size(), i+1);
::pump_timers(); // Should pump (fire) the retry timer, scheduling the queue timer
}
// Do some extra pumps to make sure no other timer work occurs.
::pump_timers();
::pump_timers();
::pump_timers();
// Make sure there were 2 posts
ensure("post records after", gPostRecords->size(), NUM_RETRIES);
for (int i=0; i<NUM_RETRIES; ++i)
{
ensure("[" + STR(i) + "] post url", (*gPostRecords)[i]["url"], FAKE_OBJECT_MEDIA_CAP_URL_503);
ensure("[" + STR(i) + "] post GET", (*gPostRecords)[i]["body"]["verb"], "GET");
ensure("[" + STR(i) + "] post object id", (*gPostRecords)[i]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID));
}
ensure("queue empty", mdc->isEmpty());
}
// Make sure everyone's destroyed properly
ensure("REF COUNT", o->getNumRefs(), num_refs_start);
}
template<> template<>
void mediadataclient_object_t::test<6>()
{
//
// Test navigate() with a bounce back
//
LOG_TEST(6);
LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest(
_DATA_URLS(VALID_OBJECT_ID,
"1.0","true",
FAKE_OBJECT_MEDIA_CAP_URL,
FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL_ERROR));
{
LLPointer<LLObjectMediaNavigateClient> mdc = new LLObjectMediaNavigateClient(NO_PERIOD,NO_PERIOD);
const char *TEST_URL = "http://example.com";
mdc->navigate(o, 0, TEST_URL);
ensure("post records", gPostRecords->size(), 0);
::pump_timers();
// ensure bounce back
ensure("bounce back",
dynamic_cast<LLMediaDataClientObjectTest*>(static_cast<LLMediaDataClientObject*>(o))->getNumBounceBacks(),
1);
ensure("post records", gPostRecords->size(), 1);
ensure("post url", (*gPostRecords)[0]["url"], FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL_ERROR);
ensure("post object id", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID));
ensure("post data", (*gPostRecords)[0]["body"][LLTextureEntry::TEXTURE_INDEX_KEY], 0);
ensure("post data", (*gPostRecords)[0]["body"][LLMediaEntry::CURRENT_URL_KEY], TEST_URL);
ensure("queue empty", mdc->isEmpty());
}
ensure("REF COUNT", o->getNumRefs(), 1);
}
template<> template<>
void mediadataclient_object_t::test<7>()
{
// Test LLMediaDataClient::isInQueue()
LOG_TEST(7);
LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(
_DATA(VALID_OBJECT_ID_1,"3.0","true"));
LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(
_DATA(VALID_OBJECT_ID_2,"1.0","true"));
int num_refs_start = o1->getNumRefs();
{
LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
ensure("not in queue yet 1", ! mdc->isInQueue(o1));
ensure("not in queue yet 2", ! mdc->isInQueue(o2));
mdc->fetchMedia(o1);
ensure("is in queue", mdc->isInQueue(o1));
ensure("is not in queue", ! mdc->isInQueue(o2));
::pump_timers();
ensure("not in queue anymore", ! mdc->isInQueue(o1));
ensure("still is not in queue", ! mdc->isInQueue(o2));
ensure("queue empty", mdc->isEmpty());
}
// Make sure everyone's destroyed properly
ensure("REF COUNT", o1->getNumRefs(), num_refs_start);
}
template<> template<>
void mediadataclient_object_t::test<8>()
{
// Test queue handling of objects that are marked dead.
LOG_TEST(8);
LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"4.0","true"));
LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_2,"3.0","true"));
LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_3,"2.0","true"));
LLMediaDataClientObject::ptr_t o4 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_4,"1.0","true"));
{
LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
// queue up all 4 objects
mdc->fetchMedia(o1);
mdc->fetchMedia(o2);
mdc->fetchMedia(o3);
mdc->fetchMedia(o4);
ensure("is in queue 1", mdc->isInQueue(o1));
ensure("is in queue 2", mdc->isInQueue(o2));
ensure("is in queue 3", mdc->isInQueue(o3));
ensure("is in queue 4", mdc->isInQueue(o4));
ensure("post records", gPostRecords->size(), 0);
// and mark the second and fourth ones dead. Call removeFromQueue when marking dead, since this is what LLVOVolume will do.
dynamic_cast<LLMediaDataClientObjectTest*>(static_cast<LLMediaDataClientObject*>(o2))->markDead();
mdc->removeFromQueue(o2);
dynamic_cast<LLMediaDataClientObjectTest*>(static_cast<LLMediaDataClientObject*>(o4))->markDead();
mdc->removeFromQueue(o4);
// The removeFromQueue calls should remove the second and fourth ones
ensure("is in queue 1", mdc->isInQueue(o1));
ensure("is not in queue 2", !mdc->isInQueue(o2));
ensure("is in queue 3", mdc->isInQueue(o3));
ensure("is not in queue 4", !mdc->isInQueue(o4));
ensure("post records", gPostRecords->size(), 0);
::pump_timers();
// The first tick should process the first item
ensure("is not in queue 1", !mdc->isInQueue(o1));
ensure("is not in queue 2", !mdc->isInQueue(o2));
ensure("is in queue 3", mdc->isInQueue(o3));
ensure("is not in queue 4", !mdc->isInQueue(o4));
ensure("post records", gPostRecords->size(), 1);
::pump_timers();
// The second tick should process the third, emptying the queue
ensure("is not in queue 3", !mdc->isInQueue(o3));
ensure("post records", gPostRecords->size(), 2);
ensure("queue empty", mdc->isEmpty());
}
ensure("refcount of o1", o1->getNumRefs(), 1);
ensure("refcount of o2", o2->getNumRefs(), 1);
ensure("refcount of o3", o3->getNumRefs(), 1);
ensure("refcount of o4", o4->getNumRefs(), 1);
}
//////////////////////////////////////////////////////////////////////////////////////////
template<> template<>
void mediadataclient_object_t::test<9>()
{
//
// Test queue re-ordering
//
LOG_TEST(9);
LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"40.0","true"));
LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_2,"30.0","true"));
LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_3,"20.0","true"));
LLMediaDataClientObjectTest *object4 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_4,"10.0","true"));
LLMediaDataClientObject::ptr_t o4 = object4;
{
LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
// queue up all 4 objects. They should now be in the queue in
// order 1 through 4, with 4 being at the front of the queue
mdc->fetchMedia(o1);
mdc->fetchMedia(o2);
mdc->fetchMedia(o3);
mdc->fetchMedia(o4);
int tick_num = 0;
ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
ensure(STR(tick_num) + ". post records", gPostRecords->size(), 0);
::pump_timers();
++tick_num;
// The first tick should remove the first one
ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1));
ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
ensure(STR(tick_num) + ". post records", gPostRecords->size(), 1);
// Now, pretend that object 4 moved relative to the avatar such
// that it is now closest
object4->setMediaInterest(50.0);
::pump_timers();
++tick_num;
// The second tick should still pick off item 2, but then re-sort
// have picked off object 4
ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
ensure(STR(tick_num) + ". post records", gPostRecords->size(), 2);
::pump_timers();
++tick_num;
// The third tick should pick off object 2
ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2));
ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
ensure(STR(tick_num) + ". post records", gPostRecords->size(), 3);
// The fourth tick should pick off object 3
::pump_timers();
++tick_num;
ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
ensure(STR(tick_num) + ". post records", gPostRecords->size(), 4);
ensure("queue empty", mdc->isEmpty());
}
ensure("refcount of o1", o1->getNumRefs(), 1);
ensure("refcount of o2", o2->getNumRefs(), 1);
ensure("refcount of o3", o3->getNumRefs(), 1);
ensure("refcount of o4", o4->getNumRefs(), 1);
}
template<> template<>
void mediadataclient_object_t::test<10>()
{
//
// Test using the "round-robin" queue
//
LOG_TEST(10);
LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"1.0","true"));
LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_2,"2.0","true"));
LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_3,"3.0","false"));
LLMediaDataClientObject::ptr_t o4 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_4,"4.0","false"));
{
LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
// queue up all 4 objects. The first two should be in the sorted
// queue [2 1], the second in the round-robin queue. The queues
// are serviced interleaved, so we should expect:
// 2, 3, 1, 4
mdc->fetchMedia(o1);
mdc->fetchMedia(o2);
mdc->fetchMedia(o3);
mdc->fetchMedia(o4);
int tick_num = 0;
// 0
ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
ensure(STR(tick_num) + ". post records", gPostRecords->size(), 0);
::pump_timers();
++tick_num;
// 1 The first tick should remove object 2
ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2));
ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
ensure(STR(tick_num) + ". post records", gPostRecords->size(), 1);
ensure(STR(tick_num) + ". post object id", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_2));
::pump_timers();
++tick_num;
// 2 The second tick should send object 3
ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2));
ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
ensure(STR(tick_num) + ". post records", gPostRecords->size(), 2);
ensure(STR(tick_num) + ". post object id", (*gPostRecords)[1]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_3));
::pump_timers();
++tick_num;
// 3 The third tick should remove object 1
ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1));
ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2));
ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
ensure(STR(tick_num) + ". post records", gPostRecords->size(), 3);
ensure(STR(tick_num) + ". post object id", (*gPostRecords)[2]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_1));
::pump_timers();
++tick_num;
// 4 The fourth tick should send object 4
ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1));
ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2));
ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
ensure(STR(tick_num) + ". post records", gPostRecords->size(), 4);
ensure(STR(tick_num) + ". post object id", (*gPostRecords)[3]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_4));
::pump_timers();
++tick_num;
// 5 The fifth tick should not change the state of anything.
ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1));
ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2));
ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
ensure(STR(tick_num) + ". post records", gPostRecords->size(), 4);
::pump_timers();
// Whew....better be empty
ensure("queue empty", mdc->isEmpty());
}
ensure("refcount of o1", o1->getNumRefs(), 1);
ensure("refcount of o2", o2->getNumRefs(), 1);
ensure("refcount of o3", o3->getNumRefs(), 1);
ensure("refcount of o4", o4->getNumRefs(), 1);
}
template<> template<>
void mediadataclient_object_t::test<11>()
{
//
// Test LLMediaDataClient's destructor
//
LOG_TEST(11);
LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest(DATA);
int num_refs_start = o->getNumRefs();
{
LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
mdc->fetchMedia(o);
// must tick enough times to clear refcount of mdc
::pump_timers();
}
// Make sure everyone's destroyed properly
ensure("REF COUNT", o->getNumRefs(), num_refs_start);
}
template<> template<>
void mediadataclient_object_t::test<12>()
{
//
// Test the "not interesting enough" call
//
LOG_TEST(12);
LLMediaDataClientObjectTest *object1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"1.0","true"));
LLMediaDataClientObject::ptr_t o1 = object1;
LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_2,"2.0","true"));
LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_3,"3.0","true"));
LLMediaDataClientObject::ptr_t o4 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_4,"4.0","true"));
{
LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
// queue up all 4 objects. The first two are "interesting enough".
// Firing the timer 4 times should therefore leave them.
// Note that they should be sorted 4,3,2,1
// Then, we'll make one "interesting enough", fire the timer a few
// times, and make sure only it gets pulled off the queue
gMinimumInterestLevel = 2.5;
mdc->fetchMedia(o1);
mdc->fetchMedia(o2);
mdc->fetchMedia(o3);
mdc->fetchMedia(o4);
int tick_num = 0;
// 0
ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
ensure(STR(tick_num) + ". post records", gPostRecords->size(), 0);
::pump_timers();
++tick_num;
// 1 The first tick should remove object 4
ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
ensure(STR(tick_num) + ". post records", gPostRecords->size(), 1);
ensure(STR(tick_num) + ". post object id", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_4));
::pump_timers();
++tick_num;
// 2 The second tick should send object 3
ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
ensure(STR(tick_num) + ". post records", gPostRecords->size(), 2);
ensure(STR(tick_num) + ". post object id", (*gPostRecords)[1]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_3));
::pump_timers();
++tick_num;
// 3 The third tick should not pull off anything
ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
ensure(STR(tick_num) + ". post records", gPostRecords->size(), 2);
::pump_timers();
++tick_num;
// 4 The fourth tick (for good measure) should not pull off anything
ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
ensure(STR(tick_num) + ". post records", gPostRecords->size(), 2);
// Okay, now futz with object 1's interest, such that it is now
// "interesting enough"
object1->setMediaInterest((F64)5.0);
// This should sort so that the queue is now [1 2]
::pump_timers();
++tick_num;
// 5 The fifth tick should now identify objects 3 and 4 as no longer
// needing "updating", and remove them from the queue
ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1));
ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
ensure(STR(tick_num) + ". post records", gPostRecords->size(), 3);
ensure(STR(tick_num) + ". post object id", (*gPostRecords)[2]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_1));
::pump_timers();
++tick_num;
// 6 The sixth tick should not pull off anything
ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1));
ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
ensure(STR(tick_num) + ". post records", gPostRecords->size(), 3);
::pump_timers();
++tick_num;
// Whew....better NOT be empty ... o2 should still be there
ensure("queue not empty", !mdc->isEmpty());
// But, we need to clear the queue, or else we won't destroy MDC...
// this is a strange interplay between the queue timer and the MDC
mdc->removeFromQueue(o2);
// tick
::pump_timers();
}
ensure("refcount of o1", o1->getNumRefs(), 1);
ensure("refcount of o2", o2->getNumRefs(), 1);
ensure("refcount of o3", o3->getNumRefs(), 1);
ensure("refcount of o4", o4->getNumRefs(), 1);
}
template<> template<>
void mediadataclient_object_t::test<13>()
{
//
// Test supression of redundant navigates.
//
LOG_TEST(13);
LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"1.0","true"));
{
LLPointer<LLObjectMediaNavigateClient> mdc = new LLObjectMediaNavigateClient(NO_PERIOD,NO_PERIOD);
const char *TEST_URL = "http://foo.example.com";
const char *TEST_URL_2 = "http://example.com";
mdc->navigate(o1, 0, TEST_URL);
mdc->navigate(o1, 1, TEST_URL);
mdc->navigate(o1, 0, TEST_URL_2);
mdc->navigate(o1, 1, TEST_URL_2);
// This should add two requests to the queue, one for face 0 of the object and one for face 1.
ensure("before pump: 1 is in queue", mdc->isInQueue(o1));
::pump_timers();
ensure("after first pump: 1 is in queue", mdc->isInQueue(o1));
::pump_timers();
ensure("after second pump: 1 is not in queue", !mdc->isInQueue(o1));
ensure("first post has correct url", (*gPostRecords)[0]["body"][LLMediaEntry::CURRENT_URL_KEY].asString(), std::string(TEST_URL_2));
ensure("second post has correct url", (*gPostRecords)[1]["body"][LLMediaEntry::CURRENT_URL_KEY].asString(), std::string(TEST_URL_2));
}
}
}
+32
View File
@@ -0,0 +1,32 @@
/**
* @file llpipeline_stub.cpp
* @brief stub class to allow unit testing
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
class LLPipeline
{
public: BOOL canUseWindLightShaders() const;
};
BOOL LLPipeline::canUseWindLightShaders() const {return TRUE;}
LLPipeline gPipeline;
@@ -0,0 +1,139 @@
/**
* @file llremoteparcelrequest_test.cpp
* @author Brad Kittenbrink <brad@lindenlab.com>
*
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "../test/lltut.h"
#if 0
#include "../llremoteparcelrequest.h"
#include "../llagent.h"
#include "message.h"
#include "llurlentry.h"
#include "llpounceable.h"
namespace {
const LLUUID TEST_PARCEL_ID("11111111-1111-1111-1111-111111111111");
}
LLCurl::Responder::Responder() { }
LLCurl::Responder::~Responder() { }
void LLCurl::Responder::httpFailure() { }
void LLCurl::Responder::httpSuccess() { }
void LLCurl::Responder::httpCompleted() { }
void LLCurl::Responder::failureResult(S32 status, const std::string& reason, const LLSD& content) { }
void LLCurl::Responder::successResult(const LLSD& content) { }
void LLCurl::Responder::completeResult(S32 status, const std::string& reason, const LLSD& content) { }
std::string LLCurl::Responder::dumpResponse() const { return "(failure)"; }
void LLCurl::Responder::completedRaw(LLChannelDescriptors const &,std::shared_ptr<LLBufferArray> const &) { }
void LLMessageSystem::getF32(char const *,char const *,F32 &,S32) { }
void LLMessageSystem::getU8(char const *,char const *,U8 &,S32) { }
void LLMessageSystem::getS32(char const *,char const *,S32 &,S32) { }
void LLMessageSystem::getString(char const *,char const *, std::string &,S32) { }
void LLMessageSystem::getUUID(char const *,char const *, LLUUID & out_id,S32)
{
out_id = TEST_PARCEL_ID;
}
void LLMessageSystem::nextBlock(char const *) { }
void LLMessageSystem::addUUID(char const *,LLUUID const &) { }
void LLMessageSystem::addUUIDFast(char const *,LLUUID const &) { }
void LLMessageSystem::nextBlockFast(char const *) { }
void LLMessageSystem::newMessage(char const *) { }
LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem;
char const* const _PREHASH_AgentID = 0; // never dereferenced during this test
char const* const _PREHASH_AgentData = 0; // never dereferenced during this test
LLAgent gAgent;
LLAgent::LLAgent() : mAgentAccess(NULL) { }
LLAgent::~LLAgent() { }
void LLAgent::sendReliableMessage(void) { }
LLUUID gAgentSessionID;
LLUUID gAgentID;
LLUIColor::LLUIColor(void) { }
LLControlGroup::LLControlGroup(std::string const & name) : LLInstanceTracker<LLControlGroup, std::string>(name) { }
LLControlGroup::~LLControlGroup(void) { }
void LLUrlEntryParcel::processParcelInfo(const LLUrlEntryParcel::LLParcelData& parcel_data) { }
namespace tut
{
struct TestObserver : public LLRemoteParcelInfoObserver {
TestObserver() : mProcessed(false) { }
virtual void processParcelInfo(const LLParcelData& parcel_data)
{
mProcessed = true;
}
virtual void setParcelID(const LLUUID& parcel_id) { }
virtual void setErrorStatus(S32 status, const std::string& reason) { }
bool mProcessed;
};
struct RemoteParcelRequestData
{
RemoteParcelRequestData()
{
}
};
typedef test_group<RemoteParcelRequestData> remoteparcelrequest_t;
typedef remoteparcelrequest_t::object remoteparcelrequest_object_t;
tut::remoteparcelrequest_t tut_remoteparcelrequest("LLRemoteParcelRequest");
template<> template<>
void remoteparcelrequest_object_t::test<1>()
{
set_test_name("observer pointer");
std::unique_ptr<TestObserver> observer(new TestObserver());
LLRemoteParcelInfoProcessor & processor = LLRemoteParcelInfoProcessor::instance();
processor.addObserver(LLUUID(TEST_PARCEL_ID), observer.get());
processor.processParcelInfoReply(gMessageSystem, NULL);
ensure(observer->mProcessed);
}
template<> template<>
void remoteparcelrequest_object_t::test<2>()
{
set_test_name("CHOP-220: dangling observer pointer");
LLRemoteParcelInfoObserver * observer = new TestObserver();
LLRemoteParcelInfoProcessor & processor = LLRemoteParcelInfoProcessor::instance();
processor.addObserver(LLUUID(TEST_PARCEL_ID), observer);
delete observer;
observer = NULL;
processor.processParcelInfoReply(gMessageSystem, NULL);
}
}
#endif
+133
View File
@@ -0,0 +1,133 @@
/**
* @file llsecapi_test.cpp
* @author Roxie
* @date 2009-02-10
* @brief Test the sec api functionality
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "../llviewerprecompiledheaders.h"
#include "../llviewernetwork.h"
#include "../test/lltut.h"
#include "../llsecapi.h"
#include "../llsechandler_basic.h"
#include "../../llxml/llcontrol.h"
//----------------------------------------------------------------------------
// Mock objects for the dependencies of the code we're testing
LLControlGroup::LLControlGroup(const std::string& name)
: LLInstanceTracker<LLControlGroup, std::string>(name) {}
LLControlGroup::~LLControlGroup() {}
LLControlVariable* LLControlGroup::declareString(const std::string& name,
const std::string& initial_val,
const std::string& comment,
LLControlVariable::ePersist persist) {return NULL;}
void LLControlGroup::setString(std::string_view name, const std::string& val){}
std::string LLControlGroup::getString(std::string_view name)
{
return "";
}
LLControlGroup gSavedSettings("test");
LLSecAPIBasicHandler::LLSecAPIBasicHandler() {}
void LLSecAPIBasicHandler::init() {}
LLSecAPIBasicHandler::~LLSecAPIBasicHandler() {}
LLPointer<LLCertificate> LLSecAPIBasicHandler::getCertificate(const std::string& pem_cert) { return NULL; }
LLPointer<LLCertificate> LLSecAPIBasicHandler::getCertificate(X509* openssl_cert) { return NULL; }
LLPointer<LLCertificateChain> LLSecAPIBasicHandler::getCertificateChain(X509_STORE_CTX* chain) { return NULL; }
LLPointer<LLCertificateStore> LLSecAPIBasicHandler::getCertificateStore(const std::string& store_id) { return NULL; }
void LLSecAPIBasicHandler::setProtectedData(const std::string& data_type, const std::string& data_id, const LLSD& data) {}
void LLSecAPIBasicHandler::addToProtectedMap(const std::string& data_type, const std::string& data_id, const std::string& map_elem, const LLSD& data) {}
void LLSecAPIBasicHandler::removeFromProtectedMap(const std::string& data_type, const std::string& data_id, const std::string& map_elem) {}
void LLSecAPIBasicHandler::syncProtectedMap() {}
LLSD LLSecAPIBasicHandler::getProtectedData(const std::string& data_type, const std::string& data_id) { return LLSD(); }
void LLSecAPIBasicHandler::deleteProtectedData(const std::string& data_type, const std::string& data_id) {}
LLPointer<LLCredential> LLSecAPIBasicHandler::createCredential(const std::string& grid, const LLSD& identifier, const LLSD& authenticator) { return NULL; }
LLPointer<LLCredential> LLSecAPIBasicHandler::loadCredential(const std::string& grid) { return NULL; }
void LLSecAPIBasicHandler::saveCredential(LLPointer<LLCredential> cred, bool save_authenticator) {}
void LLSecAPIBasicHandler::deleteCredential(LLPointer<LLCredential> cred) {}
bool LLSecAPIBasicHandler::hasCredentialMap(const std::string& storage, const std::string& grid) { return false; }
bool LLSecAPIBasicHandler::emptyCredentialMap(const std::string& storage, const std::string& grid) { return false; }
void LLSecAPIBasicHandler::loadCredentialMap(const std::string& storage, const std::string& grid, credential_map_t& credential_map) {}
LLPointer<LLCredential> LLSecAPIBasicHandler::loadFromCredentialMap(const std::string& storage, const std::string& grid, const std::string& userkey) { return NULL; }
void LLSecAPIBasicHandler::addToCredentialMap(const std::string& storage, LLPointer<LLCredential> cred, bool save_authenticator) {}
void LLSecAPIBasicHandler::removeFromCredentialMap(const std::string& storage, LLPointer<LLCredential> cred) {}
void LLSecAPIBasicHandler::removeFromCredentialMap(const std::string& storage, const std::string& grid, const std::string& userkey) {}
void LLSecAPIBasicHandler::removeCredentialMap(const std::string& storage, const std::string& grid) {}
// -------------------------------------------------------------------------------------------
// TUT
// -------------------------------------------------------------------------------------------
namespace tut
{
// Test wrapper declaration : wrapping nothing for the moment
struct secapiTest
{
secapiTest()
{
}
~secapiTest()
{
}
};
// Tut templating thingamagic: test group, object and test instance
typedef test_group<secapiTest> secapiTestFactory;
typedef secapiTestFactory::object secapiTestObject;
tut::secapiTestFactory tut_test("LLSecAPI");
// ---------------------------------------------------------------------------------------
// Test functions
// ---------------------------------------------------------------------------------------
// registration
template<> template<>
void secapiTestObject::test<1>()
{
// retrieve an unknown handler
ensure("'Unknown' handler should be NULL", getSecHandler("unknown") == nullptr);
LLPointer<LLSecAPIHandler> test1_handler = new LLSecAPIBasicHandler();
registerSecHandler("sectest1", test1_handler);
ensure("'Unknown' handler should be NULL", getSecHandler("unknown") == nullptr);
LLPointer<LLSecAPIHandler> retrieved_test1_handler = getSecHandler("sectest1");
ensure("Retrieved sectest1 handler should be the same",
retrieved_test1_handler == test1_handler);
// insert a second handler
LLPointer<LLSecAPIHandler> test2_handler = new LLSecAPIBasicHandler();
registerSecHandler("sectest2", test2_handler);
ensure("'Unknown' handler should be NULL", getSecHandler("unknown") == nullptr);
retrieved_test1_handler = getSecHandler("sectest1");
ensure("Retrieved sectest1 handler should be the same",
retrieved_test1_handler == test1_handler);
LLPointer<LLSecAPIHandler> retrieved_test2_handler = getSecHandler("sectest2");
ensure("Retrieved sectest1 handler should be the same",
retrieved_test2_handler == test2_handler);
}
}
File diff suppressed because it is too large Load Diff
+37
View File
@@ -0,0 +1,37 @@
/**
* @file llsky_stub.cpp
* @brief stub class to allow unit testing
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
class LLSky
{
public:
void setOverrideSun(BOOL override);
void setSunDirection(const LLVector3 &sun_direction, const LLVector3 &sun_ang_velocity);
};
void LLSky::setOverrideSun(BOOL override) {}
void LLSky::setSunDirection(const LLVector3 &sun_direction, const LLVector3 &sun_ang_velocity) {}
LLSky gSky;
+368
View File
@@ -0,0 +1,368 @@
/**
* @file llsecapi_test.cpp
* @author Roxie
* @date 2009-02-10
* @brief Test the sec api functionality
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2014, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "../llviewerprecompiledheaders.h"
#include "../llviewernetwork.h"
#include "../test/lltut.h"
#include "../llslurl.h"
#include "../../llxml/llcontrol.h"
#include "llsdserialize.h"
namespace
{
// Should not collide with other test programs creating temp files.
static const char * const TEST_FILENAME("llslurl_test.xml");
}
//
// Stub implementation for LLTrans
//
class LLTrans
{
public:
static std::string getString(std::string_view xml_desc, const LLStringUtil::format_map_t& args, bool def_string = false);
};
std::string LLTrans::getString(std::string_view xml_desc, const LLStringUtil::format_map_t& args, bool def_string)
{
return std::string();
}
// [RLVa:KB] - Checked: 2010-11-12 (RLVa-1.2.2a) | Added: RLVa-1.2.2a
// Stub implementation to get the test to compile properly
#include "../rlvhandler.h"
const std::string& RlvStrings::getString(const std::string& strStringName)
{
static const std::string strMissing = "(Missing RLVa string)";
return strMissing;
}
bool RlvUtil::isNearbyRegion(const std::string& strRegion)
{
return false;
}
RlvHandler::RlvHandler() : m_pGCTimer(NULL), m_pWLSnapshot(NULL)
{
// Array auto-initialization to 0 is non-standard? (Compiler warning in VC-8.0)
memset(m_Behaviours, 0, sizeof(S16) * RLV_BHVR_COUNT);
}
RlvHandler::~RlvHandler()
{
}
RlvHandler gRlvHandler;
// [/RLVa:KB]
//----------------------------------------------------------------------------
// Mock objects for the dependencies of the code we're testing
LLControlGroup::LLControlGroup(const std::string& name)
: LLInstanceTracker<LLControlGroup, std::string>(name) {}
LLControlGroup::~LLControlGroup() {}
LLControlVariable* LLControlGroup::declareString(const std::string& name,
const std::string& initial_val,
const std::string& comment,
LLControlVariable::ePersist persist) {return NULL;}
void LLControlGroup::setString(std::string_view name, const std::string& val){}
std::string gCmdLineLoginURI;
std::string gCmdLineGridChoice;
std::string gCmdLineHelperURI;
std::string gLoginPage;
std::string gCurrentGrid;
std::string LLControlGroup::getString(std::string_view name)
{
if (name == "CmdLineGridChoice")
return gCmdLineGridChoice;
else if (name == "CmdLineHelperURI")
return gCmdLineHelperURI;
else if (name == "LoginPage")
return gLoginPage;
else if (name == "CurrentGrid")
return gCurrentGrid;
return "";
}
LLSD LLControlGroup::getLLSD(std::string_view name)
{
if (name == "CmdLineLoginURI")
{
if(!gCmdLineLoginURI.empty())
{
return LLSD(gCmdLineLoginURI);
}
}
return LLSD();
}
LLPointer<LLControlVariable> LLControlGroup::getControl(std::string_view name)
{
ctrl_name_table_t::iterator iter = mNameTable.find(name.data());
return iter == mNameTable.end() ? LLPointer<LLControlVariable>() : iter->second;
}
LLControlGroup gSavedSettings("test");
const char *gSampleGridFile =
"<?xml version=\"1.0\"?>"
"<llsd>"
" <map>"
" <key>foo.bar.com</key>"
" <map>"
" <key>helper_uri</key><string>https://foobar/helpers/</string>"
" <key>label</key><string>Foobar Grid</string>"
" <key>login_page</key><string>foobar/loginpage</string>"
" <key>login_uri</key>"
" <array>"
" <string>foobar/loginuri</string>"
" </array>"
" <key>keyname</key><string>foo.bar.com</string>"
" <key>credential_type</key><string>agent</string>"
" <key>grid_login_id</key><string>FooBar</string>"
" </map>"
" <key>my.grid.com</key>"
" <map>"
" <key>helper_uri</key><string>https://mygrid/helpers/</string>"
" <key>label</key><string>My Grid</string>"
" <key>login_page</key><string>mygrid/loginpage</string>"
" <key>login_uri</key>"
" <array>"
" <string>mygrid/loginuri</string>"
" </array>"
" <key>keyname</key><string>my.grid.com</string>"
" <key>credential_type</key><string>agent</string>"
" <key>grid_login_id</key><string>MyGrid</string>"
" </map>"
" </map>"
"</llsd>"
;
// -------------------------------------------------------------------------------------------
// TUT
// -------------------------------------------------------------------------------------------
namespace tut
{
// Test wrapper declaration : wrapping nothing for the moment
struct slurlTest
{
slurlTest()
{
LLGridManager::getInstance()->initialize(std::string(""));
}
~slurlTest()
{
}
};
// Tut templating thingamagic: test group, object and test instance
typedef test_group<slurlTest> slurlTestFactory;
typedef slurlTestFactory::object slurlTestObject;
tut::slurlTestFactory tut_test("LLSlurl");
// ---------------------------------------------------------------------------------------
// Test functions
// ---------------------------------------------------------------------------------------
// construction from slurl string
template<> template<>
void slurlTestObject::test<1>()
{
llofstream gridfile(TEST_FILENAME);
gridfile << gSampleGridFile;
gridfile.close();
LLGridManager::getInstance()->initialize(TEST_FILENAME);
LLGridManager::getInstance()->setGridChoice("util.agni.lindenlab.com");
LLSLURL slurl = LLSLURL("");
ensure_equals("null slurl", (int)slurl.getType(), LLSLURL::LAST_LOCATION);
slurl = LLSLURL("http://slurl.com/secondlife/myregion");
ensure_equals("slurl.com slurl, region only - type", slurl.getType(), LLSLURL::LOCATION);
ensure_equals("slurl.com slurl, region only", slurl.getSLURLString(),
"http://maps.secondlife.com/secondlife/myregion/128/128/0");
slurl = LLSLURL("http://maps.secondlife.com/secondlife/myregion/1/2/3");
ensure_equals("maps.secondlife.com slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION);
ensure_equals("maps.secondlife.com slurl, region + coords", slurl.getSLURLString(),
"http://maps.secondlife.com/secondlife/myregion/1/2/3");
slurl = LLSLURL("secondlife://");
ensure_equals("secondlife: slurl, empty - type", slurl.getType(), LLSLURL::EMPTY);
slurl = LLSLURL("secondlife:///");
ensure_equals("secondlife: slurl, root - type", slurl.getType(), LLSLURL::EMPTY);
slurl = LLSLURL("secondlife://myregion");
ensure_equals("secondlife: slurl, region only - type", slurl.getType(), LLSLURL::LOCATION);
ensure_equals("secondlife: slurl, region only", slurl.getSLURLString(),
"http://maps.secondlife.com/secondlife/myregion/128/128/0");
slurl = LLSLURL("secondlife://myregion/1/2/3");
ensure_equals("secondlife: slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION);
ensure_equals("secondlife slurl, region + coords", slurl.getSLURLString(),
"http://maps.secondlife.com/secondlife/myregion/1/2/3");
slurl = LLSLURL("/myregion");
ensure_equals("/region slurl, region- type", slurl.getType(), LLSLURL::LOCATION);
ensure_equals("/region slurl, region ", slurl.getSLURLString(),
"http://maps.secondlife.com/secondlife/myregion/128/128/0");
slurl = LLSLURL("/myregion/1/2/3");
ensure_equals("/: slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION);
ensure_equals("/ slurl, region + coords", slurl.getSLURLString(),
"http://maps.secondlife.com/secondlife/myregion/1/2/3");
slurl = LLSLURL("my region/1/2/3");
ensure_equals(" slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION);
ensure_equals(" slurl, region + coords", slurl.getSLURLString(),
"http://maps.secondlife.com/secondlife/my%20region/1/2/3");
LLGridManager::getInstance()->setGridChoice("my.grid.com");
slurl = LLSLURL("https://my.grid.com/region/my%20region/1/2/3");
ensure_equals("grid slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION);
ensure_equals("grid slurl, region + coords", slurl.getSLURLString(),
"https://my.grid.com/region/my%20region/1/2/3");
slurl = LLSLURL("https://my.grid.com/region/my region");
ensure_equals("grid slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION);
ensure_equals("grid slurl, region + coords", slurl.getSLURLString(),
"https://my.grid.com/region/my%20region/128/128/0");
LLGridManager::getInstance()->setGridChoice("foo.bar.com");
slurl = LLSLURL("/myregion/1/2/3");
ensure_equals("/: slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION);
ensure_equals("/ slurl, region + coords", slurl.getSLURLString(),
"https://foo.bar.com/region/myregion/1/2/3");
slurl = LLSLURL("myregion/1/2/3");
ensure_equals(": slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION);
ensure_equals(" slurl, region + coords", slurl.getSLURLString(),
"https://foo.bar.com/region/myregion/1/2/3");
slurl = LLSLURL(LLSLURL::SIM_LOCATION_HOME);
ensure_equals("home", slurl.getType(), LLSLURL::HOME_LOCATION);
slurl = LLSLURL(LLSLURL::SIM_LOCATION_LAST);
ensure_equals("last", slurl.getType(), LLSLURL::LAST_LOCATION);
slurl = LLSLURL("secondlife:///app/foo/bar?12345");
ensure_equals("app", slurl.getType(), LLSLURL::APP);
ensure_equals("appcmd", slurl.getAppCmd(), "foo");
ensure_equals("apppath", slurl.getAppPath().size(), 1);
ensure_equals("apppath2", slurl.getAppPath()[0].asString(), "bar");
ensure_equals("appquery", slurl.getAppQuery(), "12345");
ensure_equals("grid1", slurl.getGrid(), "FooBar");
slurl = LLSLURL("secondlife://Aditi/app/foo/bar?12345");
ensure_equals("app", slurl.getType(), LLSLURL::APP);
ensure_equals("appcmd", slurl.getAppCmd(), "foo");
ensure_equals("apppath", slurl.getAppPath().size(), 1);
ensure_equals("apppath2", slurl.getAppPath()[0].asString(), "bar");
ensure_equals("appquery", slurl.getAppQuery(), "12345");
ensure_equals("grid2", slurl.getGrid(), "Aditi");
LLGridManager::getInstance()->setGridChoice("foo.bar.com");
slurl = LLSLURL("secondlife:///secondlife/myregion/1/2/3");
ensure_equals("/: slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION);
ensure_equals("location", slurl.getType(), LLSLURL::LOCATION);
ensure_equals("region" , "myregion", slurl.getRegion());
ensure_equals("grid3", slurl.getGrid(), "util.agni.lindenlab.com");
slurl = LLSLURL("secondlife://Aditi/secondlife/myregion/1/2/3");
ensure_equals("/: slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION);
ensure_equals("location", slurl.getType(), LLSLURL::LOCATION);
ensure_equals("region" , "myregion", slurl.getRegion());
ensure_equals("grid4", slurl.getGrid(), "Aditi" );
LLGridManager::getInstance()->setGridChoice("my.grid.com");
slurl = LLSLURL("https://my.grid.com/app/foo/bar?12345");
ensure_equals("app", slurl.getType(), LLSLURL::APP);
ensure_equals("appcmd", slurl.getAppCmd(), "foo");
ensure_equals("apppath", slurl.getAppPath().size(), 1);
ensure_equals("apppath2", slurl.getAppPath()[0].asString(), "bar");
ensure_equals("appquery", slurl.getAppQuery(), "12345");
}
// construction from grid/region/vector combos
template<> template<>
void slurlTestObject::test<2>()
{
llofstream gridfile(TEST_FILENAME);
gridfile << gSampleGridFile;
gridfile.close();
LLGridManager::getInstance()->initialize(TEST_FILENAME);
LLSLURL slurl = LLSLURL("my.grid.com", "my region");
ensure_equals("grid/region - type", slurl.getType(), LLSLURL::LOCATION);
ensure_equals("grid/region", slurl.getSLURLString(),
"https://my.grid.com/region/my%20region/128/128/0");
slurl = LLSLURL("my.grid.com", "my region", LLVector3(1,2,3));
ensure_equals("grid/region/vector - type", slurl.getType(), LLSLURL::LOCATION);
ensure_equals(" grid/region/vector", slurl.getSLURLString(),
"https://my.grid.com/region/my%20region/1/2/3");
LLGridManager::getInstance()->setGridChoice("util.agni.lindenlab.com");
slurl = LLSLURL("my region", LLVector3(1,2,3));
ensure_equals("default grid/region/vector - type", slurl.getType(), LLSLURL::LOCATION);
ensure_equals(" default grid/region/vector", slurl.getSLURLString(),
"http://maps.secondlife.com/secondlife/my%20region/1/2/3");
LLGridManager::getInstance()->setGridChoice("MyGrid");
slurl = LLSLURL("my region", LLVector3(1,2,3));
ensure_equals("default grid/region/vector - type", slurl.getType(), LLSLURL::LOCATION);
ensure_equals(" default grid/region/vector", slurl.getSLURLString(),
"https://my.grid.com/region/my%20region/1/2/3");
}
// Accessors
template<> template<>
void slurlTestObject::test<3>()
{
llofstream gridfile(TEST_FILENAME);
gridfile << gSampleGridFile;
gridfile.close();
LLGridManager::getInstance()->initialize(TEST_FILENAME);
LLGridManager::getInstance()->setGridChoice("my.grid.com");
LLSLURL slurl = LLSLURL("https://my.grid.com/region/my%20region/1/2/3");
ensure_equals("login string", slurl.getLoginString(), "uri:my region&amp;1&amp;2&amp;3");
ensure_equals("location string", slurl.getLocationString(), "my region/1/2/3");
ensure_equals("grid", slurl.getGrid(), "my.grid.com");
ensure_equals("region", slurl.getRegion(), "my region");
ensure_equals("position", slurl.getPosition(), LLVector3(1, 2, 3));
}
}
+278
View File
@@ -0,0 +1,278 @@
/**
* @file llwtextureinfo_test.cpp
* @author Si & Gabriel
* @date 2009-03-30
*
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
// Precompiled header: almost always required for newview cpp files
#include "../llviewerprecompiledheaders.h"
// Class to test
#include "../lltextureinfo.h"
// Dependencies
#include "../lltextureinfodetails.cpp"
// Tut header
#include "../test/lltut.h"
// -------------------------------------------------------------------------------------------
// Stubbing: Declarations required to link and run the class being tested
// Notes:
// * Add here stubbed implementation of the few classes and methods used in the class to be tested
// * Add as little as possible (let the link errors guide you)
// * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code)
// * A simulator for a class can be implemented here. Please comment and document thoroughly.
// End Stubbing
// -------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------
// TUT
// -------------------------------------------------------------------------------------------
namespace tut
{
// Test wrapper declarations
struct textureinfo_test
{
// Constructor and destructor of the test wrapper
textureinfo_test()
{
}
~textureinfo_test()
{
}
};
// Tut templating thingamagic: test group, object and test instance
typedef test_group<textureinfo_test> textureinfo_t;
typedef textureinfo_t::object textureinfo_object_t;
tut::textureinfo_t tut_textureinfo("LLTectureInfo");
// ---------------------------------------------------------------------------------------
// Test functions
// Notes:
// * Test as many as you possibly can without requiring a full blown simulation of everything
// * The tests are executed in sequence so the test instance state may change between calls
// * Remember that you cannot test private methods with tut
// ---------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
// Test the LLTextureInfo
// ---------------------------------------------------------------------------------------
// Test instantiation
template<> template<>
void textureinfo_object_t::test<1>()
{
LLTextureInfo tex_info;
tex_info.setUpLogging(true, true);
ensure("have we crashed?", true);
}
// Check lltextureinfo does not contain UUIDs we haven't added
template<> template<>
void textureinfo_object_t::test<2>()
{
LLTextureInfo tex_info;
tex_info.setUpLogging(true, true);
LLUUID nonExistant("3a0efa3b-84dc-4e17-9b8c-79ea028850c1");
ensure(!tex_info.has(nonExistant));
}
// Check we can add a request time for a texture
template<> template<>
void textureinfo_object_t::test<3>()
{
LLTextureInfo tex_info;
tex_info.setUpLogging(true, true);
LLUUID id("10e65d70-46fd-429f-841a-bf698e9424d3");
tex_info.setRequestStartTime(id, 200);
ensure_equals(tex_info.getRequestStartTime(id), 200);
}
// Check time for non-existant texture
template<> template<>
void textureinfo_object_t::test<4>()
{
LLTextureInfo tex_info;
tex_info.setUpLogging(true, true);
LLUUID nonExistant("3a0efa3b-84dc-4e17-9b8c-79ea028850c1");
ensure_equals(tex_info.getRequestStartTime(nonExistant), 0);
}
// Check download complete time for non existant texture
template<> template<>
void textureinfo_object_t::test<5>()
{
LLTextureInfo tex_info;
tex_info.setUpLogging(true, true);
LLUUID nonExistant("3a0efa3b-84dc-4e17-9b8c-79ea028850c1");
ensure_equals(tex_info.getRequestCompleteTime(nonExistant), 0);
}
// requested size is passed in correctly
template<> template<>
void textureinfo_object_t::test<6>()
{
LLTextureInfo tex_info;
tex_info.setUpLogging(true, true);
LLUUID id("10e65d70-46fd-429f-841a-bf698e9424d3");
tex_info.setRequestSize(id, 600);
ensure_equals(tex_info.getRequestSize(id), 600);
}
// transport type is recorded correctly (http)
template<> template<>
void textureinfo_object_t::test<7>()
{
LLTextureInfo tex_info;
tex_info.setUpLogging(true, true);
LLUUID id("10e65d70-46fd-429f-841a-bf698e9424d3");
tex_info.setRequestType(id, LLTextureInfoDetails::REQUEST_TYPE_HTTP);
ensure_equals(tex_info.getRequestType(id), LLTextureInfoDetails::REQUEST_TYPE_HTTP);
}
// transport type is recorded correctly (udp)
template<> template<>
void textureinfo_object_t::test<8>()
{
LLTextureInfo tex_info;
tex_info.setUpLogging(true, true);
LLUUID id("10e65d70-46fd-429f-841a-bf698e9424d3");
tex_info.setRequestType(id, LLTextureInfoDetails::REQUEST_TYPE_UDP);
ensure_equals(tex_info.getRequestType(id), LLTextureInfoDetails::REQUEST_TYPE_UDP);
}
// request offset is recorded correctly
template<> template<>
void textureinfo_object_t::test<9>()
{
LLTextureInfo tex_info;
tex_info.setUpLogging(true, true);
LLUUID id("10e65d70-46fd-429f-841a-bf698e9424d3");
tex_info.setRequestOffset(id, 1234);
ensure_equals(tex_info.getRequestOffset(id), 1234);
}
// ask for averages gives us correct figure
template<> template<>
void textureinfo_object_t::test<10>()
{
LLTextureInfo tex_info;
tex_info.setUpLogging(true, true);
S32 requestStartTimeOne = 200;
S32 requestEndTimeOne = 400;
S32 requestSizeOne = 1024;
S32 requestSizeOneBits = requestSizeOne * 8;
LLUUID id1("10e65d70-46fd-429f-841a-bf698e9424d3");
tex_info.setRequestStartTime(id1, requestStartTimeOne);
tex_info.setRequestSize(id1, requestSizeOne);
tex_info.setRequestType(id1, LLTextureInfoDetails::REQUEST_TYPE_HTTP);
tex_info.setRequestCompleteTimeAndLog(id1, requestEndTimeOne);
U32 requestStartTimeTwo = 100;
U32 requestEndTimeTwo = 500;
U32 requestSizeTwo = 2048;
S32 requestSizeTwoBits = requestSizeTwo * 8;
LLUUID id2("10e65d70-46fd-429f-841a-bf698e9424d4");
tex_info.setRequestStartTime(id2, requestStartTimeTwo);
tex_info.setRequestSize(id2, requestSizeTwo);
tex_info.setRequestType(id2, LLTextureInfoDetails::REQUEST_TYPE_HTTP);
tex_info.setRequestCompleteTimeAndLog(id2, requestEndTimeTwo);
S32 averageBitRate = ((requestSizeOneBits/(requestEndTimeOne - requestStartTimeOne)) +
(requestSizeTwoBits/(requestEndTimeTwo - requestStartTimeTwo))) / 2;
S32 totalBytes = requestSizeOne + requestSizeTwo;
LLSD results = tex_info.getAverages();
ensure_equals("is average bits per second correct", results["bits_per_second"].asInteger(), averageBitRate);
ensure_equals("is total bytes is correct", results["bytes_downloaded"].asInteger(), totalBytes);
ensure_equals("is transport correct", results["transport"].asString(), std::string("HTTP"));
}
// make sure averages cleared when reset is called
template<> template<>
void textureinfo_object_t::test<11>()
{
LLTextureInfo tex_info;
tex_info.setUpLogging(true, true);
S32 requestStartTimeOne = 200;
S32 requestEndTimeOne = 400;
S32 requestSizeOne = 1024;
LLUUID id1("10e65d70-46fd-429f-841a-bf698e9424d3");
tex_info.setRequestStartTime(id1, requestStartTimeOne);
tex_info.setRequestSize(id1, requestSizeOne);
tex_info.setRequestType(id1, LLTextureInfoDetails::REQUEST_TYPE_HTTP);
tex_info.setRequestCompleteTimeAndLog(id1, requestEndTimeOne);
tex_info.getAverages();
tex_info.reset();
LLSD results = tex_info.getAverages();
ensure_equals("is average bits per second correct", results["bits_per_second"].asInteger(), 0);
ensure_equals("is total bytes is correct", results["bytes_downloaded"].asInteger(), 0);
ensure_equals("is transport correct", results["transport"].asString(), std::string("NONE"));
}
// make sure map item removed when expired
template<> template<>
void textureinfo_object_t::test<12>()
{
LLTextureInfo tex_info;
tex_info.setUpLogging(true, true);
S32 requestStartTimeOne = 200;
S32 requestEndTimeOne = 400;
S32 requestSizeOne = 1024;
LLUUID id1("10e65d70-46fd-429f-841a-bf698e9424d3");
tex_info.setRequestStartTime(id1, requestStartTimeOne);
tex_info.setRequestSize(id1, requestSizeOne);
tex_info.setRequestType(id1, LLTextureInfoDetails::REQUEST_TYPE_HTTP);
ensure_equals("map item created", tex_info.getTextureInfoMapSize(), 1);
tex_info.setRequestCompleteTimeAndLog(id1, requestEndTimeOne);
ensure_equals("map item removed when consumed", tex_info.getTextureInfoMapSize(), 0);
}
}
@@ -0,0 +1,92 @@
/**
* @file llwtextureinfodetails_test.cpp
* @author Si & Gabriel
* @date 2009-03-30
*
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
// Precompiled header: almost always required for newview cpp files
#include "../llviewerprecompiledheaders.h"
// Class to test
#include "../lltextureinfodetails.h"
// Dependencies
// Tut header
#include "../test/lltut.h"
// -------------------------------------------------------------------------------------------
// Stubbing: Declarations required to link and run the class being tested
// Notes:
// * Add here stubbed implementation of the few classes and methods used in the class to be tested
// * Add as little as possible (let the link errors guide you)
// * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code)
// * A simulator for a class can be implemented here. Please comment and document thoroughly.
// End Stubbing
// -------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------
// TUT
// -------------------------------------------------------------------------------------------
namespace tut
{
// Test wrapper declarations
struct textureinfodetails_test
{
// Constructor and destructor of the test wrapper
textureinfodetails_test()
{
}
~textureinfodetails_test()
{
}
};
// Tut templating thingamagic: test group, object and test instance
typedef test_group<textureinfodetails_test> textureinfodetails_t;
typedef textureinfodetails_t::object textureinfodetails_object_t;
tut::textureinfodetails_t tut_textureinfodetails("LLTextureInfoDetails");
// ---------------------------------------------------------------------------------------
// Test functions
// Notes:
// * Test as many as you possibly can without requiring a full blown simulation of everything
// * The tests are executed in sequence so the test instance state may change between calls
// * Remember that you cannot test private methods with tut
// ---------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
// Test the LLTextureInfo
// ---------------------------------------------------------------------------------------
// Test instantiation
template<> template<>
void textureinfodetails_object_t::test<1>()
{
ensure("have we crashed?", true);
}
}
@@ -0,0 +1,150 @@
/**
* @file lltexturestatsuploader_test.cpp
* @author Si
* @date 2009-05-27
*
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
// Precompiled header: almost always required for newview cpp files
#include "../llviewerprecompiledheaders.h"
// Class to test
#include "../lltexturestatsuploader.h"
// Dependencies
// Tut header
#include "../test/lltut.h"
// -------------------------------------------------------------------------------------------
// Stubbing: Declarations required to link and run the class being tested
// Notes:
// * Add here stubbed implementation of the few classes and methods used in the class to be tested
// * Add as little as possible (let the link errors guide you)
// * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code)
// * A simulator for a class can be implemented here. Please comment and document thoroughly.
#include "boost/intrusive_ptr.hpp"
void boost::intrusive_ptr_add_ref(LLCurl::Responder*){}
void boost::intrusive_ptr_release(LLCurl::Responder* p){}
const F32 HTTP_REQUEST_EXPIRY_SECS = 0.0f;
static std::string most_recent_url;
static LLSD most_recent_body;
void LLHTTPClient::post(
const std::string& url,
const LLSD& body,
ResponderPtr,
const LLSD& headers,
const F32 timeout)
{
// set some sensor code
most_recent_url = url;
most_recent_body = body;
return;
}
// End Stubbing
// -------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------
// TUT
// -------------------------------------------------------------------------------------------
namespace tut
{
// Test wrapper declarations
struct texturestatsuploader_test
{
// Constructor and destructor of the test wrapper
texturestatsuploader_test()
{
most_recent_url = "some sort of default text that should never match anything the tests are expecting!";
LLSD blank_llsd;
most_recent_body = blank_llsd;
}
~texturestatsuploader_test()
{
}
};
// Tut templating thingamagic: test group, object and test instance
typedef test_group<texturestatsuploader_test> texturestatsuploader_t;
typedef texturestatsuploader_t::object texturestatsuploader_object_t;
tut::texturestatsuploader_t tut_texturestatsuploader("LLTextureStatsUploader");
// ---------------------------------------------------------------------------------------
// Test functions
// Notes:
// * Test as many as you possibly can without requiring a full blown simulation of everything
// * The tests are executed in sequence so the test instance state may change between calls
// * Remember that you cannot test private methods with tut
// ---------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
// Test the LLTextureInfo
// ---------------------------------------------------------------------------------------
// Test instantiation
template<> template<>
void texturestatsuploader_object_t::test<1>()
{
LLTextureStatsUploader tsu;
LL_INFOS() << &tsu << LL_ENDL;
ensure("have we crashed?", true);
}
// does it call out to the provided url if we ask it to?
template<> template<>
void texturestatsuploader_object_t::test<2>()
{
LLTextureStatsUploader tsu;
std::string url = "http://blahblahblah";
LLSD texture_stats;
tsu.uploadStatsToSimulator(url, texture_stats);
ensure_equals("did the right url get called?", most_recent_url, url);
ensure_equals("did the right body get sent?", most_recent_body, texture_stats);
}
// does it not call out to the provided url if we send it an ungranted cap?
template<> template<>
void texturestatsuploader_object_t::test<3>()
{
LLTextureStatsUploader tsu;
// this url left intentionally blank to mirror
// not getting a cap in the caller.
std::string url_for_ungranted_cap = "";
LLSD texture_stats;
std::string most_recent_url_before_test = most_recent_url;
tsu.uploadStatsToSimulator(url_for_ungranted_cap, texture_stats);
ensure_equals("hopefully no url got called!", most_recent_url, most_recent_url_before_test);
}
// does it call out if the data is empty?
// should it even do that?
}
+121
View File
@@ -0,0 +1,121 @@
/**
* @file llversioninfo_test.cpp
*
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "../test/lltut.h"
#include "../llversioninfo.h"
#include <iostream>
// LL_VIEWER_CHANNEL is a macro defined on the compiler command line. The
// macro expands to the string name of the channel, but without quotes. We
// need to turn it into a quoted string. LL_TO_STRING() does that.
#define ll_viewer_channel LL_TO_STRING(LL_VIEWER_CHANNEL)
namespace tut
{
struct versioninfo
{
versioninfo()
: mResetChannel("Reset Channel")
{
std::ostringstream stream;
stream << LL_VIEWER_VERSION_MAJOR << "."
<< LL_VIEWER_VERSION_MINOR << "."
<< LL_VIEWER_VERSION_PATCH << "."
<< LL_VIEWER_VERSION_BUILD;
mVersion = stream.str();
stream.str("");
stream << LL_VIEWER_VERSION_MAJOR << "."
<< LL_VIEWER_VERSION_MINOR << "."
<< LL_VIEWER_VERSION_PATCH;
mShortVersion = stream.str();
stream.str("");
stream << ll_viewer_channel
<< " "
<< mVersion;
mVersionAndChannel = stream.str();
stream.str("");
stream << mResetChannel
<< " "
<< mVersion;
mResetVersionAndChannel = stream.str();
}
std::string mResetChannel;
std::string mVersion;
std::string mShortVersion;
std::string mVersionAndChannel;
std::string mResetVersionAndChannel;
};
typedef test_group<versioninfo> versioninfo_t;
typedef versioninfo_t::object versioninfo_object_t;
tut::versioninfo_t tut_versioninfo("LLVersionInfo");
template<> template<>
void versioninfo_object_t::test<1>()
{
std::cout << "What we parsed from CMake: " << LL_VIEWER_VERSION_BUILD << std::endl;
std::cout << "What we get from llversioninfo: " << LLVersionInfo::instance().getBuild() << std::endl;
ensure_equals("Major version",
LLVersionInfo::instance().getMajor(),
LL_VIEWER_VERSION_MAJOR);
ensure_equals("Minor version",
LLVersionInfo::instance().getMinor(),
LL_VIEWER_VERSION_MINOR);
ensure_equals("Patch version",
LLVersionInfo::instance().getPatch(),
LL_VIEWER_VERSION_PATCH);
ensure_equals("Build version",
LLVersionInfo::instance().getBuild(),
LL_VIEWER_VERSION_BUILD);
ensure_equals("Channel version",
LLVersionInfo::instance().getChannel(),
ll_viewer_channel);
ensure_equals("Version String",
LLVersionInfo::instance().getVersion(),
mVersion);
ensure_equals("Short Version String",
LLVersionInfo::instance().getShortVersion(),
mShortVersion);
ensure_equals("Version and channel String",
LLVersionInfo::instance().getChannelAndVersion(),
mVersionAndChannel);
LLVersionInfo::instance().resetChannel(mResetChannel);
ensure_equals("Reset channel version",
LLVersionInfo::instance().getChannel(),
mResetChannel);
ensure_equals("Reset Version and channel String",
LLVersionInfo::instance().getChannelAndVersion(),
mResetVersionAndChannel);
}
}
@@ -0,0 +1,575 @@
/**
* @file llviewerassetstats_tut.cpp
* @date 2010-10-28
* @brief Test cases for some of newview/llviewerassetstats.cpp
*
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include <tut/tut.hpp>
#include <iostream>
#include "lltut.h"
#include "../llviewerassetstats.h"
#include "lluuid.h"
#include "llsdutil.h"
#include "llregionhandle.h"
#include "lltracethreadrecorder.h"
#include "../llvoavatar.h"
namespace LLStatViewer
{
LLTrace::SampleStatHandle<> FPS_SAMPLE("fpssample");
}
void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_time, S32& cloud_avatars)
{
counts.resize(3);
counts[0] = 0;
counts[1] = 0;
counts[2] = 1;
}
// static
std::string LLVOAvatar::rezStatusToString(S32 rez_status)
{
if (rez_status==0) return "cloud";
if (rez_status==1) return "gray";
if (rez_status==2) return "textured";
return "unknown";
}
// static
LLViewerStats::StatsAccumulator& LLViewerStats::PhaseMap::getPhaseStats(const std::string& phase_name)
{
static LLViewerStats::StatsAccumulator junk;
return junk;
}
static const char * all_keys[] =
{
"duration",
"fps",
"get_other_http",
"get_other_udp",
"get_texture_temp_http",
"get_texture_temp_udp",
"get_texture_non_temp_http",
"get_texture_non_temp_udp",
"get_wearable_http",
"get_wearable_udp",
"get_sound_http",
"get_sound_udp",
"get_gesture_http",
"get_gesture_udp"
};
static const char * resp_keys[] =
{
"get_other_http",
"get_other_udp",
"get_texture_temp_http",
"get_texture_temp_udp",
"get_texture_non_temp_http",
"get_texture_non_temp_udp",
"get_wearable_http",
"get_wearable_udp",
"get_sound_http",
"get_sound_udp",
"get_gesture_http",
"get_gesture_udp"
};
static const char * sub_keys[] =
{
"dequeued",
"enqueued",
"resp_count",
"resp_max",
"resp_min",
"resp_mean"
};
static const char * mmm_resp_keys[] =
{
"fps"
};
static const char * mmm_sub_keys[] =
{
"count",
"max",
"min",
"mean"
};
static const LLUUID region1("4e2d81a3-6263-6ffe-ad5c-8ce04bee07e8");
static const LLUUID region2("68762cc8-b68b-4e45-854b-e830734f2d4a");
static const U64 region1_handle(0x0000040000003f00ULL);
static const U64 region2_handle(0x0000030000004200ULL);
static const std::string region1_handle_str("0000040000003f00");
static const std::string region2_handle_str("0000030000004200");
#if 0
static bool
is_empty_map(const LLSD & sd)
{
return sd.isMap() && 0 == sd.size();
}
#endif
#if 0
static bool
is_single_key_map(const LLSD & sd, const std::string & key)
{
return sd.isMap() && 1 == sd.size() && sd.has(key);
}
#endif
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);
}
#if 0
static bool
is_triple_key_map(const LLSD & sd, const std::string & key1, const std::string & key2, const std::string& key3)
{
return sd.isMap() && 3 == sd.size() && sd.has(key1) && sd.has(key2) && sd.has(key3);
}
#endif
static bool
is_no_stats_map(const LLSD & sd)
{
return is_double_key_map(sd, "duration", "regions");
}
static bool
is_single_slot_array(const LLSD & sd, U64 region_handle)
{
U32 grid_x(0), grid_y(0);
grid_from_region_handle(region_handle, &grid_x, &grid_y);
return (sd.isArray() &&
1 == sd.size() &&
sd[0].has("grid_x") &&
sd[0].has("grid_y") &&
sd[0]["grid_x"].isInteger() &&
sd[0]["grid_y"].isInteger() &&
grid_x == sd[0]["grid_x"].asInteger() &&
grid_y == sd[0]["grid_y"].asInteger());
}
static bool
is_double_slot_array(const LLSD & sd, U64 region_handle1, U64 region_handle2)
{
U32 grid_x1(0), grid_y1(0);
U32 grid_x2(0), grid_y2(0);
grid_from_region_handle(region_handle1, &grid_x1, &grid_y1);
grid_from_region_handle(region_handle2, &grid_x2, &grid_y2);
return (sd.isArray() &&
2 == sd.size() &&
sd[0].has("grid_x") &&
sd[0].has("grid_y") &&
sd[0]["grid_x"].isInteger() &&
sd[0]["grid_y"].isInteger() &&
sd[1].has("grid_x") &&
sd[1].has("grid_y") &&
sd[1]["grid_x"].isInteger() &&
sd[1]["grid_y"].isInteger() &&
((grid_x1 == sd[0]["grid_x"].asInteger() &&
grid_y1 == sd[0]["grid_y"].asInteger() &&
grid_x2 == sd[1]["grid_x"].asInteger() &&
grid_y2 == sd[1]["grid_y"].asInteger()) ||
(grid_x1 == sd[1]["grid_x"].asInteger() &&
grid_y1 == sd[1]["grid_y"].asInteger() &&
grid_x2 == sd[0]["grid_x"].asInteger() &&
grid_y2 == sd[0]["grid_y"].asInteger())));
}
static LLSD
get_region(const LLSD & sd, U64 region_handle1)
{
U32 grid_x(0), grid_y(0);
grid_from_region_handle(region_handle1, &grid_x, &grid_y);
for (LLSD::array_const_iterator it(sd["regions"].beginArray());
sd["regions"].endArray() != it;
++it)
{
if ((*it).has("grid_x") &&
(*it).has("grid_y") &&
(*it)["grid_x"].isInteger() &&
(*it)["grid_y"].isInteger() &&
(*it)["grid_x"].asInteger() == grid_x &&
(*it)["grid_y"].asInteger() == grid_y)
{
return *it;
}
}
return LLSD();
}
namespace tut
{
struct tst_viewerassetstats_index
{
tst_viewerassetstats_index()
{
LLTrace::set_master_thread_recorder(&mThreadRecorder);
}
~tst_viewerassetstats_index()
{
LLTrace::set_master_thread_recorder(NULL);
}
LLTrace::ThreadRecorder mThreadRecorder;
};
typedef test_group<tst_viewerassetstats_index> tst_viewerassetstats_index_t;
typedef tst_viewerassetstats_index_t::object tst_viewerassetstats_index_object_t;
tut::tst_viewerassetstats_index_t tut_tst_viewerassetstats_index("tst_viewerassetstats_test");
// Testing free functions without global stats allocated
template<> template<>
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));
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false);
LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, false, false);
LLViewerAssetStatsFF::record_response(LLViewerAssetType::AT_GESTURE, false, false, (U64Microseconds)12300000ULL);
}
// 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));
LLViewerAssetStats * it = new LLViewerAssetStats();
ensure("Global gViewerAssetStats should still be NULL", (NULL == gViewerAssetStats));
LLSD sd_full = it->asLLSD(false);
// Default (NULL) region ID doesn't produce LLSD results so should
// get an empty map back from output
ensure("Stat-less LLSD initially", is_no_stats_map(sd_full));
// Once the region is set, we will get a response even with no data collection
it->setRegion(region1_handle);
sd_full = it->asLLSD(false);
ensure("Correct single-key LLSD map root", is_double_key_map(sd_full, "duration", "regions"));
ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd_full["regions"], region1_handle));
LLSD sd = sd_full["regions"][0];
delete it;
// Check the structure of the LLSD
for (int i = 0; i < LL_ARRAY_SIZE(all_keys); ++i)
{
std::string line = llformat("Has '%s' key", all_keys[i]);
ensure(line, sd.has(all_keys[i]));
}
for (int i = 0; i < LL_ARRAY_SIZE(resp_keys); ++i)
{
for (int j = 0; j < LL_ARRAY_SIZE(sub_keys); ++j)
{
std::string line = llformat("Key '%s' has '%s' key", resp_keys[i], sub_keys[j]);
ensure(line, sd[resp_keys[i]].has(sub_keys[j]));
}
}
for (int i = 0; i < LL_ARRAY_SIZE(mmm_resp_keys); ++i)
{
for (int j = 0; j < LL_ARRAY_SIZE(mmm_sub_keys); ++j)
{
std::string line = llformat("Key '%s' has '%s' key", mmm_resp_keys[i], mmm_sub_keys[j]);
ensure(line, sd[mmm_resp_keys[i]].has(mmm_sub_keys[j]));
}
}
}
// Create a non-global instance and check some content
template<> template<>
void tst_viewerassetstats_index_object_t::test<3>()
{
LLViewerAssetStats * it = new LLViewerAssetStats();
it->setRegion(region1_handle);
LLSD sd = it->asLLSD(false);
ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));
sd = sd[0];
delete it;
// Check a few points on the tree for content
ensure("sd[get_texture_temp_http][dequeued] is 0", (0 == sd["get_texture_temp_http"]["dequeued"].asInteger()));
ensure("sd[get_sound_udp][resp_min] is 0", (0.0 == sd["get_sound_udp"]["resp_min"].asReal()));
}
// Create a global instance and verify free functions do something useful
template<> template<>
void tst_viewerassetstats_index_object_t::test<4>()
{
gViewerAssetStats = new LLViewerAssetStats();
LLViewerAssetStatsFF::set_region(region1_handle);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false);
LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, false, false);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false);
LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false);
LLSD sd = gViewerAssetStats->asLLSD(false);
ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));
sd = sd["regions"][0];
// 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
gViewerAssetStats->reset();
sd = gViewerAssetStats->asLLSD(false)["regions"][region1_handle_str];
delete gViewerAssetStats;
gViewerAssetStats = 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<5>()
{
gViewerAssetStats = new LLViewerAssetStats();
LLViewerAssetStatsFF::set_region(region1_handle);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false);
LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, false, false);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false);
LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false);
LLViewerAssetStatsFF::set_region(region2_handle);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
LLSD sd = gViewerAssetStats->asLLSD(false);
// std::cout << sd << std::endl;
ensure("Correct double-key LLSD map root", is_double_key_map(sd, "duration", "regions"));
ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle));
LLSD sd1 = get_region(sd, region1_handle);
LLSD sd2 = get_region(sd, region2_handle);
ensure("Region1 is present in results", sd1.isMap());
ensure("Region2 is present in results", sd2.isMap());
// Check a few points on the tree for content
ensure_equals("sd1[get_texture_non_temp_udp][enqueued] is 1", sd1["get_texture_non_temp_udp"]["enqueued"].asInteger(), 1);
ensure_equals("sd1[get_texture_temp_udp][enqueued] is 0", sd1["get_texture_temp_udp"]["enqueued"].asInteger(), 0);
ensure_equals("sd1[get_texture_non_temp_http][enqueued] is 0", sd1["get_texture_non_temp_http"]["enqueued"].asInteger(), 0);
ensure_equals("sd1[get_texture_temp_http][enqueued] is 0", sd1["get_texture_temp_http"]["enqueued"].asInteger(), 0);
ensure_equals("sd1[get_gesture_udp][dequeued] is 0", sd1["get_gesture_udp"]["dequeued"].asInteger(), 0);
// 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
gViewerAssetStats->reset();
sd = gViewerAssetStats->asLLSD(false);
ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle));
sd2 = sd["regions"][0];
delete gViewerAssetStats;
gViewerAssetStats = 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<6>()
{
gViewerAssetStats = new LLViewerAssetStats();
LLViewerAssetStatsFF::set_region(region1_handle);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false);
LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, false, false);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false);
LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false);
LLViewerAssetStatsFF::set_region(region2_handle);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
LLViewerAssetStatsFF::set_region(region1_handle);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, true, true);
LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, true, true);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false);
LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false);
LLViewerAssetStatsFF::set_region(region2_handle);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
LLSD sd = gViewerAssetStats->asLLSD(false);
ensure("Correct double-key LLSD map root", is_double_key_map(sd, "duration", "regions"));
ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle));
LLSD sd1 = get_region(sd, region1_handle);
LLSD sd2 = get_region(sd, region2_handle);
ensure("Region1 is present in results", sd1.isMap());
ensure("Region2 is present in results", sd2.isMap());
// 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
gViewerAssetStats->reset();
sd = gViewerAssetStats->asLLSD(false);
ensure("Correct single-key LLSD map root", is_double_key_map(sd, "duration", "regions"));
ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle));
sd2 = get_region(sd, region2_handle);
ensure("Region2 is present in results", sd2.isMap());
delete gViewerAssetStats;
gViewerAssetStats = NULL;
ensure_equals("sd2[get_texture_non_temp_udp][enqueued] is reset", sd2["get_texture_non_temp_udp"]["enqueued"].asInteger(), 0);
ensure_equals("sd2[get_gesture_udp][enqueued] is reset", sd2["get_gesture_udp"]["enqueued"].asInteger(), 0);
}
// Non-texture assets ignore transport and persistence flags
template<> template<>
void tst_viewerassetstats_index_object_t::test<7>()
{
gViewerAssetStats = new LLViewerAssetStats();
LLViewerAssetStatsFF::set_region(region1_handle);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false);
LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, false, false);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false);
LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, true);
LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, true);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, true, false);
LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, true, false);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, true, true);
LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, true, true);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_LSL_BYTECODE, false, false);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_LSL_BYTECODE, false, true);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_LSL_BYTECODE, true, false);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
LLSD sd = gViewerAssetStats->asLLSD(false);
ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));
sd = get_region(sd, region1_handle);
ensure("Region1 is present in results", sd.isMap());
// 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_http][enqueued] is 2", (2 == sd["get_wearable_http"]["enqueued"].asInteger()));
ensure("sd[get_wearable_http][dequeued] is 2", (2 == sd["get_wearable_http"]["dequeued"].asInteger()));
ensure("sd[get_wearable_udp][enqueued] is 2", (2 == sd["get_wearable_udp"]["enqueued"].asInteger()));
ensure("sd[get_wearable_udp][dequeued] is 2", (2 == sd["get_wearable_udp"]["dequeued"].asInteger()));
ensure("sd[get_other_http][enqueued] is 2", (2 == sd["get_other_http"]["enqueued"].asInteger()));
ensure("sd[get_other_http][dequeued] is 0", (0 == sd["get_other_http"]["dequeued"].asInteger()));
ensure("sd[get_other_udp][enqueued] is 2", (2 == sd["get_other_udp"]["enqueued"].asInteger()));
ensure("sd[get_other_udp][dequeued] is 0", (0 == sd["get_other_udp"]["dequeued"].asInteger()));
// Reset and check zeros...
// Reset leaves current region in place
gViewerAssetStats->reset();
sd = get_region(gViewerAssetStats->asLLSD(false), region1_handle);
ensure("Region1 is present in results", sd.isMap());
delete gViewerAssetStats;
gViewerAssetStats = NULL;
ensure_equals("sd[get_texture_non_temp_udp][enqueued] is reset", sd["get_texture_non_temp_udp"]["enqueued"].asInteger(), 0);
ensure_equals("sd[get_gesture_udp][dequeued] is reset", sd["get_gesture_udp"]["dequeued"].asInteger(), 0);
}
}
@@ -0,0 +1,173 @@
/**
* @file llviewercontrollistener_test.cpp
* @author Nat Goodspeed
* @date 2022-06-09
* @brief Test for llviewercontrollistener.
*
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Copyright (c) 2022, Linden Research, Inc.
* $/LicenseInfo$
*/
// Precompiled header
#include "../llviewerprecompiledheaders.h"
// associated header
#include "../llviewercontrollistener.h"
// STL headers
// std headers
// external library headers
// other Linden headers
#include "../test/lltut.h"
#include "../test/catch_and_store_what_in.h" // catch_what()
#include "commoncontrol.h"
#include "llcontrol.h" // LLControlGroup
/*****************************************************************************
* TUT
*****************************************************************************/
namespace tut
{
void ensure_contains(const std::string& msg, const std::string& substr)
{
ensure_contains("Exception does not contain " + substr, msg, substr);
}
struct llviewercontrollistener_data
{
LLControlGroup Global{"FakeGlobal"};
llviewercontrollistener_data()
{
Global.declareString("strvar", "woof", "string variable");
// together we will stroll the boolvar, ma cherie
Global.declareBOOL("boolvar", true, "bool variable");
}
};
typedef test_group<llviewercontrollistener_data> llviewercontrollistener_group;
typedef llviewercontrollistener_group::object object;
llviewercontrollistener_group llviewercontrollistenergrp("llviewercontrollistener");
template<> template<>
void object::test<1>()
{
set_test_name("CommonControl no listener");
// Not implemented: the linker drags in LLViewerControlListener when
// we bring in LLViewerControl.
}
template<> template<>
void object::test<2>()
{
set_test_name("CommonControl bad group");
std::string threw{ catch_what<LL::CommonControl::ParamError>(
[](){ LL::CommonControl::get("Nonexistent", "Variable"); }) };
ensure_contains(threw, "group");
ensure_contains(threw, "Nonexistent");
}
template<> template<>
void object::test<3>()
{
set_test_name("CommonControl bad variable");
std::string threw{ catch_what<LL::CommonControl::ParamError>(
[](){ LL::CommonControl::get("FakeGlobal", "Nonexistent"); }) };
ensure_contains(threw, "key");
ensure_contains(threw, "Nonexistent");
}
template<> template<>
void object::test<4>()
{
set_test_name("CommonControl toggle string");
std::string threw{ catch_what<LL::CommonControl::ParamError>(
[](){ LL::CommonControl::toggle("FakeGlobal", "strvar"); }) };
ensure_contains(threw, "non-boolean");
ensure_contains(threw, "strvar");
}
template<> template<>
void object::test<5>()
{
set_test_name("CommonControl list bad group");
std::string threw{ catch_what<LL::CommonControl::ParamError>(
[](){ LL::CommonControl::get_vars("Nonexistent"); }) };
ensure_contains(threw, "group");
ensure_contains(threw, "Nonexistent");
}
template<> template<>
void object::test<6>()
{
set_test_name("CommonControl get");
auto strvar{ LL::CommonControl::get("FakeGlobal", "strvar") };
ensure_equals(strvar, "woof");
auto boolvar{ LL::CommonControl::get("FakeGlobal", "boolvar") };
ensure(boolvar);
}
template<> template<>
void object::test<7>()
{
set_test_name("CommonControl set, set_default, toggle");
std::string newstr{ LL::CommonControl::set("FakeGlobal", "strvar", "mouse").asString() };
ensure_equals(newstr, "mouse");
ensure_equals(LL::CommonControl::get("FakeGlobal", "strvar").asString(), "mouse");
ensure_equals(LL::CommonControl::set_default("FakeGlobal", "strvar").asString(), "woof");
bool newbool{ LL::CommonControl::set("FakeGlobal", "boolvar", false) };
ensure(! newbool);
ensure(! LL::CommonControl::get("FakeGlobal", "boolvar").asBoolean());
ensure(LL::CommonControl::set_default("FakeGlobal", "boolvar").asBoolean());
ensure(! LL::CommonControl::toggle("FakeGlobal", "boolvar").asBoolean());
}
template<> template<>
void object::test<8>()
{
set_test_name("CommonControl get_def");
LLSD def{ LL::CommonControl::get_def("FakeGlobal", "strvar") };
ensure_equals(
def,
llsd::map("name", "strvar",
"type", "String",
"value", "woof",
"comment", "string variable"));
}
template<> template<>
void object::test<9>()
{
set_test_name("CommonControl get_groups");
std::vector<std::string> groups{ LL::CommonControl::get_groups() };
ensure_equals(groups.size(), 1);
ensure_equals(groups[0], "FakeGlobal");
}
template<> template<>
void object::test<10>()
{
set_test_name("CommonControl get_vars");
LLSD vars{ LL::CommonControl::get_vars("FakeGlobal") };
// convert from array (unpredictable order) to map
LLSD varsmap{ LLSD::emptyMap() };
for (auto& var : llsd::inArray(vars))
{
varsmap[var["name"].asString()] = var;
}
// comparing maps is order-insensitive
ensure_equals(
varsmap,
llsd::map(
"strvar",
llsd::map("name", "strvar",
"type", "String",
"value", "woof",
"comment", "string variable"),
"boolvar",
llsd::map("name", "boolvar",
"type", "Boolean",
"value", true,
"comment", "bool variable")));
}
} // namespace tut
@@ -0,0 +1,160 @@
/**
* @file llviewerhelputil_test.cpp
* @brief LLViewerHelpUtil tests
* @author Tofu Linden
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
// Precompiled header
#include "../llviewerprecompiledheaders.h"
#include "../test/lltut.h"
#include "../llviewerhelputil.h"
#include "../llweb.h"
#include "llcontrol.h"
#include <iostream>
// values for all of the supported substitutions parameters
static std::string gHelpURL;
static std::string gVersion;
static std::string gChannel;
static std::string gLanguage;
static std::string gGrid;
static std::string gOS;
//----------------------------------------------------------------------------
// Mock objects for the dependencies of the code we're testing
LLControlGroup::LLControlGroup(const std::string& name)
: LLInstanceTracker<LLControlGroup, std::string>(name) {}
LLControlGroup::~LLControlGroup() {}
LLControlVariable* LLControlGroup::declareString(const std::string& name,
const std::string& initial_val,
const std::string& comment,
LLControlVariable::ePersist persist) {return NULL;}
void LLControlGroup::setString(std::string_view name, const std::string& val){}
std::string LLControlGroup::getString(std::string_view name)
{
if (name == "HelpURLFormat")
return gHelpURL;
return "";
}
LLControlGroup gSavedSettings("test");
static void substitute_string(std::string &input, const std::string &search, const std::string &replace)
{
size_t pos = input.find(search);
while (pos != std::string::npos)
{
input = input.replace(pos, search.size(), replace);
pos = input.find(search);
}
}
#include "../llagent.h"
LLAgent::LLAgent() : mAgentAccess(NULL) { }
LLAgent::~LLAgent() { }
bool LLAgent::isGodlike() const { return false; }
LLAgent gAgent;
std::string LLWeb::expandURLSubstitutions(const std::string &url,
const LLSD &default_subs)
{
(void)gAgent.isGodlike(); // ref symbol to stop compiler from stripping it
std::string new_url = url;
substitute_string(new_url, "[TOPIC]", default_subs["TOPIC"].asString());
substitute_string(new_url, "[VERSION]", gVersion);
substitute_string(new_url, "[CHANNEL]", gChannel);
substitute_string(new_url, "[LANGUAGE]", gLanguage);
substitute_string(new_url, "[GRID]", gGrid);
substitute_string(new_url, "[OS]", gOS);
return new_url;
}
//----------------------------------------------------------------------------
namespace tut
{
struct viewerhelputil
{
};
typedef test_group<viewerhelputil> viewerhelputil_t;
typedef viewerhelputil_t::object viewerhelputil_object_t;
tut::viewerhelputil_t tut_viewerhelputil("LLViewerHelpUtil");
template<> template<>
void viewerhelputil_object_t::test<1>()
{
std::string topic("test_topic");
std::string subresult;
gHelpURL = "fooformat";
subresult = LLViewerHelpUtil::buildHelpURL(topic);
ensure_equals("no substitution tags", subresult, "fooformat");
gHelpURL = "";
subresult = LLViewerHelpUtil::buildHelpURL(topic);
ensure_equals("blank substitution format", subresult, "");
gHelpURL = "[TOPIC]";
subresult = LLViewerHelpUtil::buildHelpURL(topic);
ensure_equals("topic name", subresult, "test_topic");
gHelpURL = "[LANGUAGE]";
gLanguage = "";
subresult = LLViewerHelpUtil::buildHelpURL(topic);
ensure_equals("simple substitution with blank", subresult, "");
gHelpURL = "[LANGUAGE]";
gLanguage = "Esperanto";
subresult = LLViewerHelpUtil::buildHelpURL(topic);
ensure_equals("simple substitution", subresult, "Esperanto");
gHelpURL = "http://secondlife.com/[LANGUAGE]";
gLanguage = "Gaelic";
subresult = LLViewerHelpUtil::buildHelpURL(topic);
ensure_equals("simple substitution with url", subresult, "http://secondlife.com/Gaelic");
gHelpURL = "[XXX]";
subresult = LLViewerHelpUtil::buildHelpURL(topic);
ensure_equals("unknown substitution", subresult, "[XXX]");
gHelpURL = "[LANGUAGE]/[LANGUAGE]";
gLanguage = "Esperanto";
subresult = LLViewerHelpUtil::buildHelpURL(topic);
ensure_equals("multiple substitution", subresult, "Esperanto/Esperanto");
gHelpURL = "http://[CHANNEL]/[VERSION]/[LANGUAGE]/[OS]/[GRID]/[XXX]";
gChannel = "Second Life Test";
gVersion = "2.0";
gLanguage = "gaelic";
gOS = "AmigaOS 2.1";
gGrid = "mysim";
subresult = LLViewerHelpUtil::buildHelpURL(topic);
ensure_equals("complex substitution", subresult, "http://Second Life Test/2.0/gaelic/AmigaOS 2.1/mysim/[XXX]");
}
}
@@ -0,0 +1,450 @@
/**
* @file llviewernetwork_test.cpp
* @author Roxie
* @date 2009-03-9
* @brief Test the viewernetwork functionality
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2014, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "../llviewerprecompiledheaders.h"
#include "../llviewernetwork.h"
#include "../test/lltut.h"
#include "../../llxml/llcontrol.h"
#include "llfile.h"
namespace
{
// Should not collide with other test programs creating temp files.
static const char * const TEST_FILENAME("llviewernetwork_test.xml");
}
//
// Stub implementation for LLTrans
//
class LLTrans
{
public:
static std::string getString(std::string_view xml_desc, const LLStringUtil::format_map_t& args, bool def_string = false);
};
std::string LLTrans::getString(std::string_view xml_desc, const LLStringUtil::format_map_t& args, bool def_string)
{
std::string grid_label = std::string();
if(xml_desc == "AgniGridLabel")
{
grid_label = "Second Life Main Grid (Agni)";
}
else if(xml_desc == "AditiGridLabel")
{
grid_label = "Second Life Beta Test Grid (Aditi)";
}
return grid_label;
}
//----------------------------------------------------------------------------
// Mock objects for the dependencies of the code we're testing
LLControlGroup::LLControlGroup(const std::string& name)
: LLInstanceTracker<LLControlGroup, std::string>(name) {}
LLControlGroup::~LLControlGroup() {}
LLControlVariable* LLControlGroup::declareString(const std::string& name,
const std::string& initial_val,
const std::string& comment,
LLControlVariable::ePersist persist) {return NULL;}
void LLControlGroup::setString(std::string_view name, const std::string& val){}
std::string gCmdLineLoginURI;
std::string gCmdLineGridChoice;
std::string gCmdLineHelperURI;
std::string gLoginPage;
std::string gCurrentGrid;
std::string LLControlGroup::getString(std::string_view name)
{
if (name == "CmdLineGridChoice")
return gCmdLineGridChoice;
else if (name == "CmdLineHelperURI")
return gCmdLineHelperURI;
else if (name == "LoginPage")
return gLoginPage;
else if (name == "CurrentGrid")
return gCurrentGrid;
return "";
}
LLSD LLControlGroup::getLLSD(std::string_view name)
{
if (name == "CmdLineLoginURI")
{
if(!gCmdLineLoginURI.empty())
{
return LLSD(gCmdLineLoginURI);
}
}
return LLSD();
}
LLPointer<LLControlVariable> LLControlGroup::getControl(std::string_view name)
{
ctrl_name_table_t::iterator iter = mNameTable.find(name.data());
return iter == mNameTable.end() ? LLPointer<LLControlVariable>() : iter->second;
}
LLControlGroup gSavedSettings("test");
const char *gSampleGridFile =
"<?xml version=\"1.0\"?>"
"<llsd>"
" <map>"
" <key>altgrid.long.name</key>"
" <map>"
" <key>helper_uri</key><string>https://helper1/helpers/</string>"
" <key>label</key><string>Alternative Grid</string>"
" <key>login_page</key><string>altgrid/loginpage</string>"
" <key>login_uri</key>"
" <array>"
" <string>altgrid/myloginuri1</string>"
" <string>altgrid/myloginuri2</string>"
" </array>"
" <key>keyname</key><string>altgrid.long.name</string>"
" <key>credential_type</key><string>agent</string>"
" <key>grid_login_id</key><string>AltGrid</string>"
" </map>"
" <key>minimal.long.name</key>"
" <map>"
" <key>keyname</key><string>minimal.long.name</string>"
" </map>"
" <!-- Note that the values for agni and aditi below are deliberately"
" incorrect to test that they are not overwritten -->"
" <key>util.agni.lindenlab.com</key> <!-- conflict -->"
" <map>"
" <key>helper_uri</key><string>https://helper1/helpers/</string>"
" <key>grid_login_id</key><string>mylabel</string>"
" <key>label</key><string>mylabel</string>"
" <key>login_page</key><string>loginpage</string>"
" <key>login_uri</key>"
" <array>"
" <string>myloginuri</string>"
" </array>"
" <key>keyname</key><string>util.agni.lindenlab.com</string> <!-- conflict -->"
" </map>"
" <key>util.foobar.lindenlab.com</key>"
" <map>"
" <key>helper_uri</key><string>https://helper1/helpers/</string>"
" <key>grid_login_id</key><string>Aditi</string> <!-- conflict -->"
" <key>label</key><string>mylabel</string>"
" <key>login_page</key><string>loginpage</string>"
" <key>login_uri</key>"
" <array>"
" <string>myloginuri</string>"
" </array>"
" <key>update_query_url_base</key><string>https://update.secondlife.com/update</string>"
" <key>keyname</key><string>util.foobar.lindenlab.com</string>"
" </map>"
" </map>"
"</llsd>"
;
// -------------------------------------------------------------------------------------------
// TUT
// -------------------------------------------------------------------------------------------
namespace tut
{
// Test wrapper declaration : wrapping nothing for the moment
struct viewerNetworkTest
{
viewerNetworkTest()
{
LLFile::remove(TEST_FILENAME);
gCmdLineLoginURI.clear();
gCmdLineGridChoice.clear();
gCmdLineHelperURI.clear();
gLoginPage.clear();
gCurrentGrid.clear();
}
~viewerNetworkTest()
{
LLFile::remove(TEST_FILENAME);
}
};
// Tut templating thingamagic: test group, object and test instance
typedef test_group<viewerNetworkTest> viewerNetworkTestFactory;
typedef viewerNetworkTestFactory::object viewerNetworkTestObject;
tut::viewerNetworkTestFactory tut_test("LLViewerNetwork");
// ---------------------------------------------------------------------------------------
// Test functions
// ---------------------------------------------------------------------------------------
// initialization without a grid file
template<> template<>
void viewerNetworkTestObject::test<1>()
{
LLGridManager *manager = LLGridManager::getInstance();
// grid file doesn't exist
manager->initialize(TEST_FILENAME);
// validate that some of the defaults are available.
std::map<std::string, std::string> known_grids = manager->getKnownGrids();
ensure_equals("Known grids is a string-string map of size 2", known_grids.size(), 2);
ensure_equals("Agni has the right name and label",
known_grids[std::string("util.agni.lindenlab.com")],
std::string("Second Life Main Grid (Agni)"));
ensure_equals("Aditi has the right name and label",
known_grids[std::string("util.aditi.lindenlab.com")],
std::string("Second Life Beta Test Grid (Aditi)"));
ensure_equals("name for agni",
LLGridManager::getInstance()->getGrid("util.agni.lindenlab.com"),
std::string("util.agni.lindenlab.com"));
ensure_equals("id for agni",
std::string("Agni"),
LLGridManager::getInstance()->getGridId("util.agni.lindenlab.com"));
ensure_equals("update url base for Agni", // relies on agni being the default
std::string("https://update.secondlife.com/update"),
LLGridManager::getInstance()->getUpdateServiceURL());
ensure_equals("label for agni",
LLGridManager::getInstance()->getGridLabel("util.agni.lindenlab.com"),
std::string("Second Life Main Grid (Agni)"));
std::vector<std::string> login_uris;
LLGridManager::getInstance()->getLoginURIs(std::string("util.agni.lindenlab.com"), login_uris);
ensure_equals("Number of login uris for agni", 1, login_uris.size());
ensure_equals("Agni login uri",
login_uris[0],
std::string("https://login.agni.lindenlab.com/cgi-bin/login.cgi"));
ensure_equals("Agni helper uri",
LLGridManager::getInstance()->getHelperURI("util.agni.lindenlab.com"),
std::string("https://secondlife.com/helpers/"));
ensure_equals("Agni login page",
LLGridManager::getInstance()->getLoginPage("util.agni.lindenlab.com"),
std::string("https://viewer-splash.secondlife.com/"));
ensure("Agni is a system grid",
LLGridManager::getInstance()->isSystemGrid("util.agni.lindenlab.com"));
ensure_equals("name for aditi",
LLGridManager::getInstance()->getGrid("util.aditi.lindenlab.com"),
std::string("util.aditi.lindenlab.com"));
ensure_equals("id for aditi",
LLGridManager::getInstance()->getGridId("util.aditi.lindenlab.com"),
std::string("Aditi"));
ensure_equals("label for aditi",
LLGridManager::getInstance()->getGridLabel("util.aditi.lindenlab.com"),
std::string("Second Life Beta Test Grid (Aditi)"));
LLGridManager::getInstance()->getLoginURIs(std::string("util.aditi.lindenlab.com"), login_uris);
ensure_equals("Number of login uris for aditi", 1, login_uris.size());
ensure_equals("Aditi login uri",
login_uris[0],
std::string("https://login.aditi.lindenlab.com/cgi-bin/login.cgi"));
ensure_equals("Aditi helper uri",
LLGridManager::getInstance()->getHelperURI("util.aditi.lindenlab.com"),
std::string("https://secondlife.aditi.lindenlab.com/helpers/"));
ensure_equals("Aditi login page",
LLGridManager::getInstance()->getLoginPage("util.aditi.lindenlab.com"),
std::string("https://viewer-splash.secondlife.com/"));
ensure("Aditi is a system grid",
LLGridManager::getInstance()->isSystemGrid("util.aditi.lindenlab.com"));
}
// initialization with a grid file
template<> template<>
void viewerNetworkTestObject::test<2>()
{
llofstream gridfile(TEST_FILENAME);
gridfile << gSampleGridFile;
gridfile.close();
LLGridManager::getInstance()->initialize(TEST_FILENAME);
std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids();
ensure_equals("adding a grid via a grid file increases known grid size",4,
known_grids.size());
// Verify that Agni and Aditi were not overwritten
ensure_equals("Agni has the right name and label",
known_grids[std::string("util.agni.lindenlab.com")],
std::string("Second Life Main Grid (Agni)"));
ensure_equals("Aditi has the right name and label",
known_grids[std::string("util.aditi.lindenlab.com")],
std::string("Second Life Beta Test Grid (Aditi)"));
ensure_equals("name for agni",
LLGridManager::getInstance()->getGrid("util.agni.lindenlab.com"),
std::string("util.agni.lindenlab.com"));
ensure_equals("id for agni",
LLGridManager::getInstance()->getGridId("util.agni.lindenlab.com"),
std::string("Agni"));
ensure_equals("update url base for Agni", // relies on agni being the default
std::string("https://update.secondlife.com/update"),
LLGridManager::getInstance()->getUpdateServiceURL());
ensure_equals("label for agni",
LLGridManager::getInstance()->getGridLabel("util.agni.lindenlab.com"),
std::string("Second Life Main Grid (Agni)"));
std::vector<std::string> login_uris;
LLGridManager::getInstance()->getLoginURIs(std::string("util.agni.lindenlab.com"), login_uris);
ensure_equals("Number of login uris for agni", 1, login_uris.size());
ensure_equals("Agni login uri",
login_uris[0],
std::string("https://login.agni.lindenlab.com/cgi-bin/login.cgi"));
ensure_equals("Agni helper uri",
LLGridManager::getInstance()->getHelperURI("util.agni.lindenlab.com"),
std::string("https://secondlife.com/helpers/"));
ensure_equals("Agni login page",
LLGridManager::getInstance()->getLoginPage("util.agni.lindenlab.com"),
std::string("https://viewer-splash.secondlife.com/"));
ensure("Agni is a system grid",
LLGridManager::getInstance()->isSystemGrid("util.agni.lindenlab.com"));
ensure_equals("name for aditi",
LLGridManager::getInstance()->getGrid("util.aditi.lindenlab.com"),
std::string("util.aditi.lindenlab.com"));
ensure_equals("id for aditi",
LLGridManager::getInstance()->getGridId("util.aditi.lindenlab.com"),
std::string("Aditi"));
ensure_equals("label for aditi",
LLGridManager::getInstance()->getGridLabel("util.aditi.lindenlab.com"),
std::string("Second Life Beta Test Grid (Aditi)"));
LLGridManager::getInstance()->getLoginURIs(std::string("util.aditi.lindenlab.com"), login_uris);
ensure_equals("Number of login uris for aditi", 1, login_uris.size());
ensure_equals("Aditi login uri",
login_uris[0],
std::string("https://login.aditi.lindenlab.com/cgi-bin/login.cgi"));
ensure_equals("Aditi helper uri",
LLGridManager::getInstance()->getHelperURI("util.aditi.lindenlab.com"),
std::string("https://secondlife.aditi.lindenlab.com/helpers/"));
ensure_equals("Aditi login page",
LLGridManager::getInstance()->getLoginPage("util.aditi.lindenlab.com"),
std::string("https://viewer-splash.secondlife.com/"));
ensure("Aditi is a system grid",
LLGridManager::getInstance()->isSystemGrid("util.aditi.lindenlab.com"));
// Check the additional grid from the file
ensure_equals("alternative grid is in name<->label map",
known_grids["altgrid.long.name"],
std::string("Alternative Grid"));
ensure_equals("alternative grid name is set",
LLGridManager::getInstance()->getGrid("altgrid.long.name"),
std::string("altgrid.long.name"));
ensure_equals("alternative grid id",
LLGridManager::getInstance()->getGridId("altgrid.long.name"),
std::string("AltGrid"));
ensure_equals("alternative grid label",
LLGridManager::getInstance()->getGridLabel("altgrid.long.name"),
std::string("Alternative Grid"));
std::vector<std::string> alt_login_uris;
LLGridManager::getInstance()->getLoginURIs(std::string("altgrid.long.name"), alt_login_uris);
ensure_equals("Number of login uris for altgrid", 2, alt_login_uris.size());
ensure_equals("alternative grid first login uri",
alt_login_uris[0],
std::string("altgrid/myloginuri1"));
ensure_equals("alternative grid second login uri",
alt_login_uris[1],
std::string("altgrid/myloginuri2"));
ensure_equals("alternative grid helper uri",
LLGridManager::getInstance()->getHelperURI("altgrid.long.name"),
std::string("https://helper1/helpers/"));
ensure_equals("alternative grid login page",
LLGridManager::getInstance()->getLoginPage("altgrid.long.name"),
std::string("altgrid/loginpage"));
ensure("alternative grid is NOT a system grid",
! LLGridManager::getInstance()->isSystemGrid("altgrid.long.name"));
ensure_equals("minimal grid is in name<->label map",
known_grids["minimal.long.name"],
std::string("minimal.long.name"));
ensure_equals("minimal grid name is set",
LLGridManager::getInstance()->getGrid("minimal.long.name"),
std::string("minimal.long.name"));
ensure_equals("minimal grid id",
LLGridManager::getInstance()->getGridId("minimal.long.name"),
std::string("minimal.long.name"));
ensure_equals("minimal grid label",
LLGridManager::getInstance()->getGridLabel("minimal.long.name"),
std::string("minimal.long.name"));
LLGridManager::getInstance()->getLoginURIs(std::string("minimal.long.name"), alt_login_uris);
ensure_equals("Number of login uris for altgrid", 1, alt_login_uris.size());
ensure_equals("minimal grid login uri",
alt_login_uris[0],
std::string("https://minimal.long.name/cgi-bin/login.cgi"));
ensure_equals("minimal grid helper uri",
LLGridManager::getInstance()->getHelperURI("minimal.long.name"),
std::string("https://minimal.long.name/helpers/"));
ensure_equals("minimal grid login page",
LLGridManager::getInstance()->getLoginPage("minimal.long.name"),
std::string("http://minimal.long.name/app/login/"));
}
// validate grid selection
template<> template<>
void viewerNetworkTestObject::test<7>()
{
// adding a grid with simply a name will populate the values.
llofstream gridfile(TEST_FILENAME);
gridfile << gSampleGridFile;
gridfile.close();
LLGridManager::getInstance()->initialize(TEST_FILENAME);
LLGridManager::getInstance()->setGridChoice("util.agni.lindenlab.com");
ensure_equals("getGridLabel",
LLGridManager::getInstance()->getGridLabel(),
std::string("Second Life Main Grid (Agni)"));
ensure_equals("getGridId",
LLGridManager::getInstance()->getGridId(),
std::string("Agni"));
ensure_equals("getGrid",
LLGridManager::getInstance()->getGrid(),
std::string("util.agni.lindenlab.com"));
ensure_equals("getHelperURI",
LLGridManager::getInstance()->getHelperURI(),
std::string("https://secondlife.com/helpers/"));
ensure_equals("getLoginPage",
LLGridManager::getInstance()->getLoginPage(),
std::string("https://viewer-splash.secondlife.com/"));
ensure_equals("update url base for Agni", // relies on agni being the default
std::string("https://update.secondlife.com/update"),
LLGridManager::getInstance()->getUpdateServiceURL());
ensure("Is Agni a production grid", LLGridManager::getInstance()->isInProductionGrid());
std::vector<std::string> uris;
LLGridManager::getInstance()->getLoginURIs(uris);
ensure_equals("getLoginURIs size", 1, uris.size());
ensure_equals("getLoginURIs",
uris[0],
std::string("https://login.agni.lindenlab.com/cgi-bin/login.cgi"));
LLGridManager::getInstance()->setGridChoice("altgrid.long.name");
ensure_equals("getGridLabel",
LLGridManager::getInstance()->getGridLabel(),
std::string("Alternative Grid"));
ensure_equals("getGridId",
LLGridManager::getInstance()->getGridId(),
std::string("AltGrid"));
ensure("alternative grid is not a system grid",
!LLGridManager::getInstance()->isSystemGrid());
ensure("alternative grid is not a production grid",
!LLGridManager::getInstance()->isInProductionGrid());
}
}
@@ -0,0 +1,86 @@
/**
* @file llvieweroctree_stub.cpp
* @brief stub implementations to allow unit testing
*
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad) { return 0; }
void LLViewerOctreeCull::traverse(const LLOctreeNode<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry> >* node) { }
void LLViewerOctreeCull::visit(const LLOctreeNode<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry> >* node) { }
void LLViewerOctreeCull::preprocess(LLViewerOctreeGroup* group) {}
bool LLViewerOctreeCull::earlyFail(LLViewerOctreeGroup* group) { return false; }
bool LLViewerOctreeCull::checkProjectionArea(const LLVector4a& center, const LLVector4a& size, const LLVector3& shift, F32 pixel_threshold, F32 near_radius) { return false; }
bool LLViewerOctreeCull::checkObjects(const OctreeNode* branch, const LLViewerOctreeGroup* group) { return false; }
void LLViewerOctreeCull::processGroup(LLViewerOctreeGroup* group) {}
bool LLViewerOctreeGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut) { return false; }
void LLViewerOctreeGroup::unbound() {}
void LLViewerOctreeGroup::rebound() {}
void LLViewerOctreeGroup::handleInsertion(const TreeNode* node, LLViewerOctreeEntry* obj) {}
void LLViewerOctreeGroup::handleRemoval(const TreeNode* node, LLViewerOctreeEntry* obj) {}
void LLViewerOctreeGroup::handleDestruction(const TreeNode* node) {}
void LLViewerOctreeGroup::handleStateChange(const TreeNode* node) {}
void LLViewerOctreeGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child) {}
void LLViewerOctreeGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNode* child) {}
LLOcclusionCullingGroup::LLOcclusionCullingGroup(OctreeNode* node, LLViewerOctreePartition* part) :
LLViewerOctreeGroup(node),
mSpatialPartition(part)
{
}
LLOcclusionCullingGroup::~LLOcclusionCullingGroup() = default;
void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* shift) {}
void LLOcclusionCullingGroup::setOcclusionState(U32 state, S32 mode) {}
void LLOcclusionCullingGroup::clearOcclusionState(U32 state, S32 mode) {}
void LLOcclusionCullingGroup::handleChildAddition(const OctreeNode *parent, OctreeNode *child) {}
BOOL LLOcclusionCullingGroup::isRecentlyVisible() const { return FALSE; }
BOOL LLOcclusionCullingGroup::isAnyRecentlyVisible() const { return FALSE; }
LLViewerOctreeGroup::LLViewerOctreeGroup(OctreeNode* node) : mOctreeNode(node) {}
LLViewerOctreeGroup::~LLViewerOctreeGroup() = default;
LLViewerOctreeEntryData::LLViewerOctreeEntryData(LLViewerOctreeEntry::eEntryDataType_t) {}
LLViewerOctreeEntryData::~LLViewerOctreeEntryData() = default;
bool LLViewerOctreeEntryData::isVisible() const { return false; }
bool LLViewerOctreeEntryData::isRecentlyVisible() const { return false; }
void LLViewerOctreeEntryData::setVisible() const {}
void LLViewerOctreeEntryData::resetVisible() const {}
const LLVector4a& LLViewerOctreeEntryData::getPositionGroup() const { return LLVector4a::getZero(); }
const LLVector4a* LLViewerOctreeEntryData::getSpatialExtents() const { return nullptr; }
LLViewerOctreeGroup* LLViewerOctreeEntryData::getGroup() const { return nullptr; }
void LLViewerOctreeEntryData::setSpatialExtents(const LLVector4a& min, const LLVector4a& max) {}
void LLViewerOctreeEntryData::setPositionGroup(const LLVector4a& pos) {}
void LLViewerOctreeEntryData::setGroup(LLViewerOctreeGroup* group) {}
void LLViewerOctreeEntryData::setOctreeEntry(LLViewerOctreeEntry* entry) {}
U32 LLViewerOctreeEntryData::sCurVisible{};
LLViewerOctreePartition::LLViewerOctreePartition() = default;
LLViewerOctreePartition::~LLViewerOctreePartition() = default;
void LLViewerOctreePartition::cleanup() {}
BOOL LLViewerOctreeGroup::isRecentlyVisible() const { return FALSE; }
@@ -0,0 +1,50 @@
/**
* @file llglslshader_stub.cpp
* @brief stub class to allow unit testing
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "../llviewershadermgr.h"
LLShaderMgr::LLShaderMgr() {}
LLShaderMgr::~LLShaderMgr() {}
LLViewerShaderMgr::LLViewerShaderMgr() {}
LLViewerShaderMgr::~LLViewerShaderMgr() {}
LLViewerShaderMgr* stub_instance = NULL;
LLViewerShaderMgr* LLViewerShaderMgr::instance() {
if(NULL == stub_instance)
{
stub_instance = new LLViewerShaderMgr();
}
return stub_instance;
}
LLViewerShaderMgr::shader_iter fake_iter;
LLViewerShaderMgr::shader_iter LLViewerShaderMgr::beginShaders() const {return fake_iter;}
LLViewerShaderMgr::shader_iter LLViewerShaderMgr::endShaders() const {return fake_iter;}
void LLViewerShaderMgr::updateShaderUniforms(LLGLSLShader* shader) {return;}
std::string LLViewerShaderMgr::getShaderDirPrefix() {return "SHADER_DIR_PREFIX-";}
@@ -0,0 +1,34 @@
/**
* @file llviewertexture_stub.cpp
* @brief stub class to allow unit testing
*
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "../llviewertexture.h"
#include "../../llrender/llgltexture.h"
void LLViewerTexture::setBoostLevel(int level)
{
}
File diff suppressed because one or more lines are too long
+29
View File
@@ -0,0 +1,29 @@
/**
* @file llwlanimator_stub.cpp
* @brief stub class to allow unit testing
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
LLWLAnimator::LLWLAnimator(void) {}
void LLWLAnimator::update(LLWLParamSet& set) {}
void LLWLAnimator::setTrack(std::map<F32, LLWLParamKey>& track, F32 dayRate, F64 dayTime, bool run) {}
+52
View File
@@ -0,0 +1,52 @@
/**
* @file llwldaycycle_stub.cpp
* @brief stub class to allow unit testing
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
LLWLDayCycle::LLWLDayCycle(void)
{
}
LLWLDayCycle::~LLWLDayCycle(void)
{
}
bool LLWLDayCycle::getKeytime(LLWLParamKey keyFrame, F32& keyTime)
{
keyTime = 0.5;
return true;
}
bool LLWLDayCycle::removeKeyframe(F32 time)
{
return true;
}
void LLWLDayCycle::loadDayCycleFromFile(const std::string& fileName)
{
}
void LLWLDayCycle::removeReferencesTo(const LLWLParamKey &keyframe)
{
}
@@ -0,0 +1,271 @@
/**
* @file llwlparammanager_test.cpp
* @brief LLWLParamManager tests
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
// Precompiled headers
#include "../llviewerprecompiledheaders.h"
// Class to test
#include "../llwlparammanager.h"
// Dependencies
#include "linden_common.h"
// TUT header
#include "lltut.h"
// Stubs
#include "llwldaycycle_stub.cpp"
#include "llwlparamset_stub.cpp"
#include "llwlanimator_stub.cpp"
#include "llglslshader_stub.cpp"
#include "lldir_stub.cpp"
#include "llsky_stub.cpp"
#include "llpipeline_stub.cpp"
#include "llviewershadermgr_stub.cpp"
void assert_glerror(void) {}
LLViewerCamera::LLViewerCamera() {}
void LLViewerCamera::setView(F32 vertical_fov_rads) {}
std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args) { return std::string(""); }
char* curl_unescape(const char* c_str, int length)
{
char* copy = new char[length+4];
memcpy(copy, c_str, length);
copy[length+0] = 'E';
copy[length+1] = 'S';
copy[length+2] = 'C';
copy[length+3] = '\0';
return copy;
}
void curl_free(void* p) {delete[] ((char*)p);}
char* curl_escape(const char* c_str, int length) {
char* copy = new char[length+6];
memcpy(copy, c_str, length);
copy[length+0] = 'U';
copy[length+1] = 'N';
copy[length+2] = 'E';
copy[length+3] = 'S';
copy[length+4] = 'C';
copy[length+5] = '\0';
return copy;
}
namespace tut
{
// Main Setup
struct LLWLParamManagerFixture
{
class LLWLParamManagerTest
{
};
LLWLParamManager* mTestManager;
LLWLParamManagerFixture()
: mTestManager(LLWLParamManager::getInstance())
{
}
~LLWLParamManagerFixture()
{
}
};
typedef test_group<LLWLParamManagerFixture> factory;
typedef factory::object object;
factory tf("LLWLParamManager test");
// Tests
template<> template<>
void object::test<1>()
{
try
{
std::string preset =
"<llsd>\
<map>\
<key>ambient</key>\
<array>\
<real>1.0499999523162842</real>\
<real>1.0499999523162842</real>\
<real>1.0499999523162842</real>\
<real>0.34999999403953552</real>\
</array>\
<key>blue_density</key>\
<array>\
<real>0.2447581488182351</real>\
<real>0.44872328639030457</real>\
<real>0.75999999046325684</real>\
<real>0.38000004053115788</real>\
</array>\
<key>blue_horizon</key>\
<array>\
<real>0.49548382097675159</real>\
<real>0.49548381382419748</real>\
<real>0.63999999284744291</real>\
<real>0.31999999642372146</real>\
</array>\
<key>cloud_color</key>\
<array>\
<real>0.40999999165535073</real>\
<real>0.40999999165535073</real>\
<real>0.40999999165535073</real>\
<real>0.40999999165535073</real>\
</array>\
<key>cloud_pos_density1</key>\
<array>\
<real>1.6884100437164307</real>\
<real>0.52609699964523315</real>\
<real>0.99999999999999289</real>\
<real>1</real>\
</array>\
<key>cloud_pos_density2</key>\
<array>\
<real>1.6884100437164307</real>\
<real>0.52609699964523315</real>\
<real>0.125</real>\
<real>1</real>\
</array>\
<key>cloud_scale</key>\
<array>\
<real>0.4199999868869746</real>\
<real>0</real>\
<real>0</real>\
<real>1</real>\
</array>\
<key>cloud_scroll_rate</key>\
<array>\
<real>10.199999809265137</real>\
<real>10.01099967956543</real>\
</array>\
<key>cloud_shadow</key>\
<array>\
<real>0.26999998092651367</real>\
<real>0</real>\
<real>0</real>\
<real>1</real>\
</array>\
<key>density_multiplier</key>\
<array>\
<real>0.00017999998817685818</real>\
<real>0</real>\
<real>0</real>\
<real>1</real>\
</array>\
<key>distance_multiplier</key>\
<array>\
<real>0.80000001192093606</real>\
<real>0</real>\
<real>0</real>\
<real>1</real>\
</array>\
<key>east_angle</key>\
<real>0</real>\
<key>enable_cloud_scroll</key>\
<array>\
<boolean>1</boolean>\
<boolean>1</boolean>\
</array>\
<key>gamma</key>\
<array>\
<real>1</real>\
<real>0</real>\
<real>0</real>\
<real>1</real>\
</array>\
<key>glow</key>\
<array>\
<real>5</real>\
<real>0.0010000000474974513</real>\
<real>-0.47999998927116394</real>\
<real>1</real>\
</array>\
<key>haze_density</key>\
<array>\
<real>0.69999998807907104</real>\
<real>0</real>\
<real>0</real>\
<real>1</real>\
</array>\
<key>haze_horizon</key>\
<array>\
<real>0.18999999761581243</real>\
<real>0.19915600121021271</real>\
<real>0.19915600121021271</real>\
<real>1</real>\
</array>\
<key>lightnorm</key>\
<array>\
<real>0</real>\
<real>0.70710659027099609</real>\
<real>-0.70710694789886475</real>\
<real>0</real>\
</array>\
<key>max_y</key>\
<array>\
<real>1605</real>\
<real>0</real>\
<real>0</real>\
<real>1</real>\
</array>\
<key>preset_num</key>\
<integer>22</integer>\
<key>star_brightness</key>\
<real>0</real>\
<key>sun_angle</key>\
<real>2.3561947345733643</real>\
<key>sunlight_color</key>\
<array>\
<real>0.73421055078505759</real>\
<real>0.78157895803450828</real>\
<real>0.89999997615813498</real>\
<real>0.29999998211860301</real>\
</array>\
</map>\
</llsd>";
std::stringstream preset_stream(preset);
mTestManager->loadPresetFromXML(LLWLParamKey("test1", LLWLParamKey::SCOPE_LOCAL), preset_stream);
LLWLParamSet dummy;
ensure("Couldn't get ParamSet after loading it", mTestManager->getParamSet(LLWLParamKey("test1", LLWLParamKey::SCOPE_LOCAL), dummy));
}
catch (...)
{
fail("loadPresetFromXML test crashed!");
}
}
template<> template<>
void object::test<2>()
{
mTestManager->propagateParameters();
ensure_equals("Wrong value from getDomeOffset()", mTestManager->getDomeOffset(), 0.96f);
ensure_equals("Wrong value from getDomeRadius()", mTestManager->getDomeRadius(), 15000.f);
ensure_equals("Wrong value from getLightDir()", mTestManager->getLightDir(), LLVector4(-0,0,1,0));
ensure_equals("Wrong value from getClampedLightDir()", mTestManager->getClampedLightDir(), LLVector4(-0,0,1,0));
ensure_equals("Wrong value from getRotatedLightDir()", mTestManager->getRotatedLightDir(), LLVector4(0,0,0,1));
}
}
+41
View File
@@ -0,0 +1,41 @@
/**
* @file llwlparamset_stub.cpp
* @brief stub class to allow unit testing
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
LLWLParamSet::LLWLParamSet(void)
{
}
void LLWLParamSet::updateCloudScrolling()
{
}
void LLWLParamSet::set(const std::string& name, const LLVector4& val)
{
}
void LLWLParamSet::update(LLGLSLShader *shader) const
{
}
+515
View File
@@ -0,0 +1,515 @@
/**
* @file llworldmap_test.cpp
* @author Merov Linden
* @date 2009-03-09
*
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
// Dependencies
#include "linden_common.h"
#include "llapr.h"
#include "llsingleton.h"
#include "lltrans.h"
#include "lluistring.h"
#include "../llviewertexture.h"
#include "../llworldmapmessage.h"
// Class to test
#include "../llworldmap.h"
// Tut header
#include "../test/lltut.h"
// -------------------------------------------------------------------------------------------
// Stubbing: Declarations required to link and run the class being tested
// Notes:
// * Add here stubbed implementation of the few classes and methods used in the class to be tested
// * Add as little as possible (let the link errors guide you)
// * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code)
// * A simulator for a class can be implemented here. Please comment and document thoroughly.
// Stub image calls
void LLGLTexture::setBoostLevel(S32 ) { }
void LLGLTexture::setAddressMode(LLTexUnit::eTextureAddressMode ) { }
LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(const LLUUID&, FTType, bool, LLGLTexture::EBoostLevel, S8,
LLGLint, LLGLenum, LLHost ) { return NULL; }
// Stub related map calls
LLWorldMapMessage::LLWorldMapMessage() { }
LLWorldMapMessage::~LLWorldMapMessage() { }
void LLWorldMapMessage::sendItemRequest(U32 type, U64 handle) { }
void LLWorldMapMessage::sendMapBlockRequest(U16 min_x, U16 min_y, U16 max_x, U16 max_y, bool return_nonexistent) { }
LLWorldMipmap::LLWorldMipmap() { }
LLWorldMipmap::~LLWorldMipmap() { }
void LLWorldMipmap::reset() { }
void LLWorldMipmap::dropBoostLevels() { }
void LLWorldMipmap::equalizeBoostLevels() { }
LLPointer<LLViewerFetchedTexture> LLWorldMipmap::getObjectsTile(U32 grid_x, U32 grid_y, S32 level, bool load) { return NULL; }
// Stub other stuff
std::string LLTrans::getString(std::string_view, const LLStringUtil::format_map_t&, bool def_string) { return std::string("test_trans"); }
void LLUIString::updateResult() const { }
void LLUIString::setArg(const std::string& , const std::string& ) { }
void LLUIString::assign(const std::string& ) { }
// End Stubbing
// -------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------
// TUT
// -------------------------------------------------------------------------------------------
const F32 X_WORLD_TEST = 1000.0f * REGION_WIDTH_METERS;
const F32 Y_WORLD_TEST = 2000.0f * REGION_WIDTH_METERS;
const F32 Z_WORLD_TEST = 240.0f;
const std::string ITEM_NAME_TEST = "Item Foo";
const std::string TOOLTIP_TEST = "Tooltip Foo";
const std::string SIM_NAME_TEST = "Sim Foo";
namespace tut
{
// Test wrapper declarations
struct iteminfo_test
{
// Instance to be tested
LLItemInfo* mItem;
// Constructor and destructor of the test wrapper
iteminfo_test()
{
LLUUID id;
mItem = new LLItemInfo(X_WORLD_TEST, Y_WORLD_TEST, ITEM_NAME_TEST, id);
}
~iteminfo_test()
{
delete mItem;
}
};
struct siminfo_test
{
// Instance to be tested
LLSimInfo* mSim;
// Constructor and destructor of the test wrapper
siminfo_test()
{
U64 handle = to_region_handle_global(X_WORLD_TEST, Y_WORLD_TEST);
mSim = new LLSimInfo(handle);
}
~siminfo_test()
{
delete mSim;
}
};
struct worldmap_test
{
// Instance to be tested
LLWorldMap* mWorld;
// Constructor and destructor of the test wrapper
worldmap_test()
{
mWorld = LLWorldMap::getInstance();
}
~worldmap_test()
{
mWorld = NULL;
}
};
// Tut templating thingamagic: test group, object and test instance
typedef test_group<iteminfo_test> iteminfo_t;
typedef iteminfo_t::object iteminfo_object_t;
tut::iteminfo_t tut_iteminfo("LLItemInfo");
typedef test_group<siminfo_test> siminfo_t;
typedef siminfo_t::object siminfo_object_t;
tut::siminfo_t tut_siminfo("LLSimInfo");
typedef test_group<worldmap_test> worldmap_t;
typedef worldmap_t::object worldmap_object_t;
tut::worldmap_t tut_worldmap("LLWorldMap");
// ---------------------------------------------------------------------------------------
// Test functions
// Notes:
// * Test as many as you possibly can without requiring a full blown simulation of everything
// * The tests are executed in sequence so the test instance state may change between calls
// * Remember that you cannot test private methods with tut
// ---------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
// Test the LLItemInfo interface
// ---------------------------------------------------------------------------------------
template<> template<>
void iteminfo_object_t::test<1>()
{
// Test 1 : setCount() / getCount()
mItem->setCount(10);
ensure("LLItemInfo::setCount() test failed", mItem->getCount() == 10);
// Test 2 : setTooltip() / getToolTip()
std::string tooltip = TOOLTIP_TEST;
mItem->setTooltip(tooltip);
ensure("LLItemInfo::setTooltip() test failed", mItem->getToolTip() == TOOLTIP_TEST);
// Test 3 : setElevation() / getGlobalPosition()
mItem->setElevation(Z_WORLD_TEST);
LLVector3d pos = mItem->getGlobalPosition();
LLVector3d ref(X_WORLD_TEST, Y_WORLD_TEST, Z_WORLD_TEST);
ensure("LLItemInfo::getGlobalPosition() test failed", pos == ref);
// Test 4 : getName()
std::string name = mItem->getName();
ensure("LLItemInfo::getName() test failed", name == ITEM_NAME_TEST);
// Test 5 : isName()
ensure("LLItemInfo::isName() test failed", mItem->isName(name));
// Test 6 : getUUID()
LLUUID id;
ensure("LLItemInfo::getUUID() test failed", mItem->getUUID() == id);
// Test 7 : getRegionHandle()
U64 handle = to_region_handle_global(X_WORLD_TEST, Y_WORLD_TEST);
ensure("LLItemInfo::getRegionHandle() test failed", mItem->getRegionHandle() == handle);
}
// ---------------------------------------------------------------------------------------
// Test the LLSimInfo interface
// ---------------------------------------------------------------------------------------
// Test Setters and Accessors methods
template<> template<>
void siminfo_object_t::test<1>()
{
// Test 1 : setName() / getName()
std::string name = SIM_NAME_TEST;
mSim->setName(name);
ensure("LLSimInfo::setName() test failed", mSim->getName() == SIM_NAME_TEST);
// Test 2 : isName()
ensure("LLSimInfo::isName() test failed", mSim->isName(name));
// Test 3 : getGlobalPos()
LLVector3 local;
LLVector3d ref(X_WORLD_TEST, Y_WORLD_TEST, 0.0f);
LLVector3d pos = mSim->getGlobalPos(local);
ensure("LLSimInfo::getGlobalPos() test failed", pos == ref);
// Test 4 : getGlobalOrigin()
pos = mSim->getGlobalOrigin();
ensure("LLSimInfo::getGlobalOrigin() test failed", pos == ref);
// Test 5 : clearImage()
try {
mSim->clearImage();
} catch (...) {
fail("LLSimInfo::clearImage() test failed");
}
// Test 6 : dropImagePriority()
try {
mSim->dropImagePriority();
} catch (...) {
fail("LLSimInfo::dropImagePriority() test failed");
}
// Test 7 : updateAgentCount()
try {
mSim->updateAgentCount(0.0f);
} catch (...) {
fail("LLSimInfo::updateAgentCount() test failed");
}
// Test 8 : getAgentCount()
S32 agents = mSim->getAgentCount();
ensure("LLSimInfo::getAgentCount() test failed", agents == 0);
// Test 9 : setLandForSaleImage() / getLandForSaleImage()
LLUUID id;
mSim->setLandForSaleImage(id);
LLPointer<LLViewerFetchedTexture> image = mSim->getLandForSaleImage();
ensure("LLSimInfo::getLandForSaleImage() test failed", image.isNull());
// Test 10 : isPG()
mSim->setAccess(SIM_ACCESS_PG);
ensure("LLSimInfo::isPG() test failed", mSim->isPG());
// Test 11 : isDown()
mSim->setAccess(SIM_ACCESS_DOWN);
ensure("LLSimInfo::isDown() test failed", mSim->isDown());
// Test 12 : Access strings can't be accessed from unit test...
//ensure("LLSimInfo::getAccessString() test failed", mSim->getAccessString() == "Offline");
// Test 13 : Region strings can't be accessed from unit test...
//mSim->setRegionFlags(REGION_FLAGS_SANDBOX);
//ensure("LLSimInfo::setRegionFlags() test failed", mSim->getFlagsString() == "Sandbox");
}
// Test management of LLInfoItem lists
template<> template<>
void siminfo_object_t::test<2>()
{
// Test 14 : clearItems()
try {
mSim->clearItems();
} catch (...) {
fail("LLSimInfo::clearItems() at init test failed");
}
// Test 15 : Verify that all the lists are empty
LLSimInfo::item_info_list_t list;
list = mSim->getTeleHub();
ensure("LLSimInfo::getTeleHub() empty at init test failed", list.empty());
list = mSim->getInfoHub();
ensure("LLSimInfo::getInfoHub() empty at init test failed", list.empty());
list = mSim->getPGEvent();
ensure("LLSimInfo::getPGEvent() empty at init test failed", list.empty());
list = mSim->getMatureEvent();
ensure("LLSimInfo::getMatureEvent() empty at init test failed", list.empty());
list = mSim->getLandForSale();
ensure("LLSimInfo::getLandForSale() empty at init test failed", list.empty());
list = mSim->getAgentLocation();
ensure("LLSimInfo::getAgentLocation() empty at init test failed", list.empty());
// Create an item to be inserted
LLUUID id;
LLItemInfo item(X_WORLD_TEST, Y_WORLD_TEST, ITEM_NAME_TEST, id);
// Insert the item in each list
mSim->insertTeleHub(item);
mSim->insertInfoHub(item);
mSim->insertPGEvent(item);
mSim->insertMatureEvent(item);
mSim->insertLandForSale(item);
mSim->insertAgentLocation(item);
// Test 16 : Verify that the lists contain 1 item each
list = mSim->getTeleHub();
ensure("LLSimInfo::insertTeleHub() test failed", list.size() == 1);
list = mSim->getInfoHub();
ensure("LLSimInfo::insertInfoHub() test failed", list.size() == 1);
list = mSim->getPGEvent();
ensure("LLSimInfo::insertPGEvent() test failed", list.size() == 1);
list = mSim->getMatureEvent();
ensure("LLSimInfo::insertMatureEvent() test failed", list.size() == 1);
list = mSim->getLandForSale();
ensure("LLSimInfo::insertLandForSale() test failed", list.size() == 1);
list = mSim->getAgentLocation();
ensure("LLSimInfo::insertAgentLocation() test failed", list.size() == 1);
// Test 17 : clearItems()
try {
mSim->clearItems();
} catch (...) {
fail("LLSimInfo::clearItems() at end test failed");
}
// Test 18 : Verify that all the lists are empty again... *except* agent which is persisted!! (on purpose)
list = mSim->getTeleHub();
ensure("LLSimInfo::getTeleHub() empty after clear test failed", list.empty());
list = mSim->getInfoHub();
ensure("LLSimInfo::getInfoHub() empty after clear test failed", list.empty());
list = mSim->getPGEvent();
ensure("LLSimInfo::getPGEvent() empty after clear test failed", list.empty());
list = mSim->getMatureEvent();
ensure("LLSimInfo::getMatureEvent() empty after clear test failed", list.empty());
list = mSim->getLandForSale();
ensure("LLSimInfo::getLandForSale() empty after clear test failed", list.empty());
list = mSim->getAgentLocation();
ensure("LLSimInfo::getAgentLocation() empty after clear test failed", list.size() == 1);
}
// ---------------------------------------------------------------------------------------
// Test the LLWorldMap interface
// ---------------------------------------------------------------------------------------
// Test Setters and Accessors methods
template<> template<>
void worldmap_object_t::test<1>()
{
// Test 1 : reset()
try {
mWorld->reset();
} catch (...) {
fail("LLWorldMap::reset() at init test failed");
}
// Test 2 : clearImageRefs()
try {
mWorld->clearImageRefs();
} catch (...) {
fail("LLWorldMap::clearImageRefs() test failed");
}
// Test 3 : dropImagePriorities()
try {
mWorld->dropImagePriorities();
} catch (...) {
fail("LLWorldMap::dropImagePriorities() test failed");
}
// Test 4 : reloadItems()
try {
mWorld->reloadItems(true);
} catch (...) {
fail("LLWorldMap::reloadItems() test failed");
}
// Test 5 : updateRegions()
try {
mWorld->updateRegions(1000, 1000, 1004, 1004);
} catch (...) {
fail("LLWorldMap::updateRegions() test failed");
}
// Test 6 : equalizeBoostLevels()
try {
mWorld->equalizeBoostLevels();
} catch (...) {
fail("LLWorldMap::equalizeBoostLevels() test failed");
}
// Test 7 : getObjectsTile()
try {
LLPointer<LLViewerFetchedTexture> image = mWorld->getObjectsTile((U32)(X_WORLD_TEST/REGION_WIDTH_METERS), (U32)(Y_WORLD_TEST/REGION_WIDTH_METERS), 1);
ensure("LLWorldMap::getObjectsTile() failed", image.isNull());
} catch (...) {
fail("LLWorldMap::getObjectsTile() test failed with exception");
}
}
// Test management of LLSimInfo lists
template<> template<>
void worldmap_object_t::test<2>()
{
// Test 8 : reset()
try {
mWorld->reset();
} catch (...) {
fail("LLWorldMap::reset() at init test failed");
}
// Test 9 : Verify that all the region list is empty
LLWorldMap::sim_info_map_t list;
list = mWorld->getRegionMap();
ensure("LLWorldMap::getRegionMap() empty at init test failed", list.empty());
// Test 10 : Insert a region
bool success;
LLUUID id;
std::string name_sim = SIM_NAME_TEST;
success = mWorld->insertRegion( U32(X_WORLD_TEST),
U32(Y_WORLD_TEST),
name_sim,
id,
SIM_ACCESS_PG,
REGION_FLAGS_SANDBOX);
list = mWorld->getRegionMap();
ensure("LLWorldMap::insertRegion() failed", success && (list.size() == 1));
// Test 11 : Insert an item in the same region -> number of regions doesn't increase
std::string name_item = ITEM_NAME_TEST;
success = mWorld->insertItem( U32(X_WORLD_TEST + REGION_WIDTH_METERS/2),
U32(Y_WORLD_TEST + REGION_WIDTH_METERS/2),
name_item,
id,
MAP_ITEM_LAND_FOR_SALE,
0, 0);
list = mWorld->getRegionMap();
ensure("LLWorldMap::insertItem() in existing region failed", success && (list.size() == 1));
// Test 12 : Insert an item in another region -> number of regions increases
success = mWorld->insertItem( U32(X_WORLD_TEST + REGION_WIDTH_METERS*2),
U32(Y_WORLD_TEST + REGION_WIDTH_METERS*2),
name_item,
id,
MAP_ITEM_LAND_FOR_SALE,
0, 0);
list = mWorld->getRegionMap();
ensure("LLWorldMap::insertItem() in unexisting region failed", success && (list.size() == 2));
// Test 13 : simInfoFromPosGlobal() in region
LLVector3d pos1( X_WORLD_TEST + REGION_WIDTH_METERS*2 + REGION_WIDTH_METERS/2,
Y_WORLD_TEST + REGION_WIDTH_METERS*2 + REGION_WIDTH_METERS/2,
0.0f);
LLSimInfo* sim;
sim = mWorld->simInfoFromPosGlobal(pos1);
ensure("LLWorldMap::simInfoFromPosGlobal() test on existing region failed", sim != NULL);
// Test 14 : simInfoFromPosGlobal() outside region
LLVector3d pos2( X_WORLD_TEST + REGION_WIDTH_METERS*4 + REGION_WIDTH_METERS/2,
Y_WORLD_TEST + REGION_WIDTH_METERS*4 + REGION_WIDTH_METERS/2,
0.0f);
sim = mWorld->simInfoFromPosGlobal(pos2);
ensure("LLWorldMap::simInfoFromPosGlobal() test outside region failed", sim == NULL);
// Test 15 : simInfoFromName()
sim = mWorld->simInfoFromName(name_sim);
ensure("LLWorldMap::simInfoFromName() test on existing region failed", sim != NULL);
// Test 16 : simInfoFromHandle()
U64 handle = to_region_handle_global(X_WORLD_TEST, Y_WORLD_TEST);
sim = mWorld->simInfoFromHandle(handle);
ensure("LLWorldMap::simInfoFromHandle() test on existing region failed", sim != NULL);
// Test 17 : simNameFromPosGlobal()
LLVector3d pos3( X_WORLD_TEST + REGION_WIDTH_METERS/2,
Y_WORLD_TEST + REGION_WIDTH_METERS/2,
0.0f);
success = mWorld->simNameFromPosGlobal(pos3, name_sim);
ensure("LLWorldMap::simNameFromPosGlobal() test on existing region failed", success && (name_sim == SIM_NAME_TEST));
// Test 18 : reset()
try {
mWorld->reset();
} catch (...) {
fail("LLWorldMap::reset() at end test failed");
}
// Test 19 : Verify that all the region list is empty
list = mWorld->getRegionMap();
ensure("LLWorldMap::getRegionMap() empty at end test failed", list.empty());
}
// Test tracking
template<> template<>
void worldmap_object_t::test<3>()
{
// Point to track
LLVector3d pos( X_WORLD_TEST + REGION_WIDTH_METERS/2, Y_WORLD_TEST + REGION_WIDTH_METERS/2, Z_WORLD_TEST);
// Test 20 : no tracking
mWorld->cancelTracking();
ensure("LLWorldMap::cancelTracking() at begin test failed", mWorld->isTracking() == false);
// Test 21 : set tracking
mWorld->setTracking(pos);
ensure("LLWorldMap::setTracking() failed", mWorld->isTracking() && !mWorld->isTrackingValidLocation());
// Test 22 : set click and commit flags
mWorld->setTrackingDoubleClick();
ensure("LLWorldMap::setTrackingDoubleClick() failed", mWorld->isTrackingDoubleClick());
mWorld->setTrackingCommit();
ensure("LLWorldMap::setTrackingCommit() failed", mWorld->isTrackingCommit());
// Test 23 : in rectangle test
bool inRect = mWorld->isTrackingInRectangle( X_WORLD_TEST, Y_WORLD_TEST,
X_WORLD_TEST + REGION_WIDTH_METERS,
Y_WORLD_TEST + REGION_WIDTH_METERS);
ensure("LLWorldMap::isTrackingInRectangle() in rectangle failed", inRect);
inRect = mWorld->isTrackingInRectangle( X_WORLD_TEST + REGION_WIDTH_METERS,
Y_WORLD_TEST + REGION_WIDTH_METERS,
X_WORLD_TEST + 2 * REGION_WIDTH_METERS,
Y_WORLD_TEST + 2 * REGION_WIDTH_METERS);
ensure("LLWorldMap::isTrackingInRectangle() outside rectangle failed", !inRect);
// Test 24 : set tracking to valid and invalid
mWorld->setTrackingValid();
ensure("LLWorldMap::setTrackingValid() failed", mWorld->isTrackingValidLocation() && !mWorld->isTrackingInvalidLocation());
mWorld->setTrackingInvalid();
ensure("LLWorldMap::setTrackingInvalid() failed", !mWorld->isTrackingValidLocation() && mWorld->isTrackingInvalidLocation());
// Test 25 : getTrackedPositionGlobal()
LLVector3d res = mWorld->getTrackedPositionGlobal();
ensure("LLWorldMap::getTrackedPositionGlobal() failed", res == pos);
// Test 26 : reset tracking
mWorld->cancelTracking();
ensure("LLWorldMap::cancelTracking() at end test failed", mWorld->isTracking() == false);
}
}
+165
View File
@@ -0,0 +1,165 @@
/**
* @file llworldmipmap_test.cpp
* @author Merov Linden
* @date 2009-02-03
*
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
// Dependencies
#include "linden_common.h"
#include "../llviewertexture.h"
#include "../llviewercontrol.h"
// Class to test
#include "../llworldmipmap.h"
// Tut header
#include "../test/lltut.h"
// -------------------------------------------------------------------------------------------
// Stubbing: Declarations required to link and run the class being tested
// Notes:
// * Add here stubbed implementation of the few classes and methods used in the class to be tested
// * Add as little as possible (let the link errors guide you)
// * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code)
// * A simulator for a class can be implemented here. Please comment and document thoroughly.
void LLGLTexture::setBoostLevel(S32 ) { }
LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string&, FTType, bool, LLGLTexture::EBoostLevel, S8,
LLGLint, LLGLenum, const LLUUID& ) { return NULL; }
LLControlGroup::LLControlGroup(const std::string& name) : LLInstanceTracker<LLControlGroup, std::string>(name) { }
LLControlGroup::~LLControlGroup() { }
std::string LLControlGroup::getString(std::string_view) { return std::string("test_url"); }
LLControlGroup gSavedSettings("test_settings");
// End Stubbing
// -------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------
// TUT
// -------------------------------------------------------------------------------------------
namespace tut
{
// Test wrapper declaration
struct worldmipmap_test
{
// Derived test class
class LLTestWorldMipmap : public LLWorldMipmap
{
// Put here stubbs of virtual methods we shouldn't call all the way down
};
// Instance to be tested
LLTestWorldMipmap* mMap;
// Constructor and destructor of the test wrapper
worldmipmap_test()
{
mMap = new LLTestWorldMipmap;
}
~worldmipmap_test()
{
delete mMap;
}
};
// Tut templating thingamagic: test group, object and test instance
typedef test_group<worldmipmap_test> worldmipmap_t;
typedef worldmipmap_t::object worldmipmap_object_t;
tut::worldmipmap_t tut_worldmipmap("LLWorldMipmap");
// ---------------------------------------------------------------------------------------
// Test functions
// Notes:
// * Test as many as you possibly can without requiring a full blown simulation of everything
// * The tests are executed in sequence so the test instance state may change between calls
// * Remember that you cannot test private methods with tut
// ---------------------------------------------------------------------------------------
// Test static methods
// Test 1 : scaleToLevel()
template<> template<>
void worldmipmap_object_t::test<1>()
{
S32 level = mMap->scaleToLevel(0.0);
ensure("scaleToLevel() test 1 failed", level == LLWorldMipmap::MAP_LEVELS);
level = mMap->scaleToLevel((F32)LLWorldMipmap::MAP_TILE_SIZE);
ensure("scaleToLevel() test 2 failed", level == 1);
level = mMap->scaleToLevel(10.f * LLWorldMipmap::MAP_TILE_SIZE);
ensure("scaleToLevel() test 3 failed", level == 1);
}
// Test 2 : globalToMipmap()
template<> template<>
void worldmipmap_object_t::test<2>()
{
U32 grid_x, grid_y;
mMap->globalToMipmap(1000.f*REGION_WIDTH_METERS, 1000.f*REGION_WIDTH_METERS, 1, &grid_x, &grid_y);
ensure("globalToMipmap() test 1 failed", (grid_x == 1000) && (grid_y == 1000));
mMap->globalToMipmap(0.0, 0.0, LLWorldMipmap::MAP_LEVELS, &grid_x, &grid_y);
ensure("globalToMipmap() test 2 failed", (grid_x == 0) && (grid_y == 0));
}
// Test 3 : getObjectsTile()
template<> template<>
void worldmipmap_object_t::test<3>()
{
// Depends on some inline methods in LLViewerImage... Thinking about how to make this work
// LLPointer<LLViewerImage> img = mMap->getObjectsTile(0, 0, 1);
// ensure("getObjectsTile() test failed", img.isNull());
}
// Test 4 : equalizeBoostLevels()
template<> template<>
void worldmipmap_object_t::test<4>()
{
try
{
mMap->equalizeBoostLevels();
}
catch (...)
{
fail("equalizeBoostLevels() test failed");
}
}
// Test 5 : dropBoostLevels()
template<> template<>
void worldmipmap_object_t::test<5>()
{
try
{
mMap->dropBoostLevels();
}
catch (...)
{
fail("dropBoostLevels() test failed");
}
}
// Test 6 : reset()
template<> template<>
void worldmipmap_object_t::test<6>()
{
try
{
mMap->reset();
}
catch (...)
{
fail("reset() test failed");
}
}
}
@@ -0,0 +1,238 @@
/*
* @file llxmlrpclistener_test.cpp
* @author Nat Goodspeed
* @date 2009-03-20
* @brief Test for llxmlrpclistener.
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
// Precompiled header
#include "../llviewerprecompiledheaders.h"
// associated header
#include "../llxmlrpclistener.h"
// STL headers
#include <iomanip>
// std headers
// external library headers
// other Linden headers
#include "../test/lltut.h"
#include "../llxmlrpctransaction.h"
#include "llevents.h"
#include "lleventfilter.h"
#include "llsd.h"
#include "llhost.h"
#include "llcontrol.h"
#include "tests/wrapllerrs.h"
#include "tests/commtest.h"
LLControlGroup gSavedSettings("Global");
/*****************************************************************************
* TUT
*****************************************************************************/
namespace tut
{
struct data
{
data():
pumps(LLEventPumps::instance()),
uri(std::string("http://") +
LLHost("127.0.0.1", commtest_data::getport("PORT")).getString())
{
// These variables are required by machinery used by
// LLXMLRPCTransaction. The values reflect reality for this test
// executable; hopefully these values are correct.
gSavedSettings.declareBOOL("BrowserProxyEnabled", FALSE, "", LLControlVariable::PERSIST_NO); // don't persist
gSavedSettings.declareBOOL("NoVerifySSLCert", TRUE, "", LLControlVariable::PERSIST_NO); // don't persist
}
// LLEventPump listener signature
bool captureReply(const LLSD& r)
{
reply = r;
return false;
}
LLSD reply;
LLEventPumps& pumps;
std::string uri;
};
typedef test_group<data> llxmlrpclistener_group;
typedef llxmlrpclistener_group::object object;
llxmlrpclistener_group llxmlrpclistenergrp("llxmlrpclistener");
template<> template<>
void object::test<1>()
{
set_test_name("request validation");
WrapLLErrs capture;
LLSD request;
request["uri"] = uri;
std::string threw = capture.catch_llerrs([&pumps, &request](){
pumps.obtain("LLXMLRPCTransaction").post(request);
});
ensure_contains("threw exception", threw, "missing params");
ensure_contains("identified missing", threw, "method");
ensure_contains("identified missing", threw, "reply");
}
template<> template<>
void object::test<2>()
{
set_test_name("param types validation");
WrapLLErrs capture;
LLSD request;
request["uri"] = uri;
request["method"] = "hello";
request["reply"] = "reply";
LLSD& params(request["params"]);
params["who"]["specifically"] = "world"; // LLXMLRPCListener only handles scalar params
std::string threw = capture.catch_llerrs([&pumps, &request](){
pumps.obtain("LLXMLRPCTransaction").post(request);
});
ensure_contains("threw exception", threw, "unknown type");
}
template<> template<>
void object::test<3>()
{
set_test_name("success case");
LLSD request;
request["uri"] = uri;
request["method"] = "hello";
request["reply"] = "reply";
LLSD& params(request["params"]);
params["who"] = "world";
// Set up a timeout filter so we don't spin forever waiting.
LLEventTimeout watchdog;
// Connect the timeout filter to the reply pump.
LLTempBoundListener temp(
pumps.obtain("reply").
listen("watchdog", boost::bind(&LLEventTimeout::post, boost::ref(watchdog), _1)));
// Now connect our target listener to the timeout filter.
watchdog.listen("captureReply", boost::bind(&data::captureReply, this, _1));
// Kick off the request...
reply.clear();
pumps.obtain("LLXMLRPCTransaction").post(request);
// Set the timer
F32 timeout(10);
watchdog.eventAfter(timeout, LLSD().with("timeout", 0));
// and pump "mainloop" until we get something, whether from
// LLXMLRPCListener or from the watchdog filter.
LLTimer timer;
F32 start = timer.getElapsedTimeF32();
LLEventPump& mainloop(pumps.obtain("mainloop"));
while (reply.isUndefined())
{
mainloop.post(LLSD());
}
ensure("timeout works", (timer.getElapsedTimeF32() - start) < (timeout + 1));
ensure_equals(reply["responses"]["hi_there"].asString(), "Hello, world!");
}
template<> template<>
void object::test<4>()
{
set_test_name("bogus method");
LLSD request;
request["uri"] = uri;
request["method"] = "goodbye";
request["reply"] = "reply";
LLSD& params(request["params"]);
params["who"] = "world";
// Set up a timeout filter so we don't spin forever waiting.
LLEventTimeout watchdog;
// Connect the timeout filter to the reply pump.
LLTempBoundListener temp(
pumps.obtain("reply").
listen("watchdog", boost::bind(&LLEventTimeout::post, boost::ref(watchdog), _1)));
// Now connect our target listener to the timeout filter.
watchdog.listen("captureReply", boost::bind(&data::captureReply, this, _1));
// Kick off the request...
reply.clear();
pumps.obtain("LLXMLRPCTransaction").post(request);
// Set the timer
F32 timeout(10);
watchdog.eventAfter(timeout, LLSD().with("timeout", 0));
// and pump "mainloop" until we get something, whether from
// LLXMLRPCListener or from the watchdog filter.
LLTimer timer;
F32 start = timer.getElapsedTimeF32();
LLEventPump& mainloop(pumps.obtain("mainloop"));
while (reply.isUndefined())
{
mainloop.post(LLSD());
}
ensure("timeout works", (timer.getElapsedTimeF32() - start) < (timeout + 1));
ensure_equals("XMLRPC error", reply["status"].asString(), "XMLRPCError");
}
template<> template<>
void object::test<5>()
{
set_test_name("bad type");
LLSD request;
request["uri"] = uri;
request["method"] = "getdict";
request["reply"] = "reply";
(void)request["params"];
// Set up a timeout filter so we don't spin forever waiting.
LLEventTimeout watchdog;
// Connect the timeout filter to the reply pump.
LLTempBoundListener temp(
pumps.obtain("reply").
listen("watchdog", boost::bind(&LLEventTimeout::post, boost::ref(watchdog), _1)));
// Now connect our target listener to the timeout filter.
watchdog.listen("captureReply", boost::bind(&data::captureReply, this, _1));
// Kick off the request...
reply.clear();
pumps.obtain("LLXMLRPCTransaction").post(request);
// Set the timer
F32 timeout(10);
watchdog.eventAfter(timeout, LLSD().with("timeout", 0));
// and pump "mainloop" until we get something, whether from
// LLXMLRPCListener or from the watchdog filter.
LLTimer timer;
F32 start = timer.getElapsedTimeF32();
LLEventPump& mainloop(pumps.obtain("mainloop"));
while (reply.isUndefined())
{
mainloop.post(LLSD());
}
ensure("timeout works", (timer.getElapsedTimeF32() - start) < (timeout + 1));
ensure_equals(reply["status"].asString(), "BadType");
ensure_contains("bad type", reply["responses"]["nested_dict"].asString(), "bad XMLRPC type");
}
} // namespace tut
/*****************************************************************************
* Resolve link errors: use real machinery here, since we intend to exchange
* actual XML with a peer process.
*****************************************************************************/
// Including llxmlrpctransaction.cpp drags in the static LLXMLRPCListener
// instantiated there. That's why it works to post requests to the LLEventPump
// named "LLXMLRPCTransaction".
#include "../llxmlrpctransaction.cpp"
#include "llcontrol.cpp"
#include "llxmltree.cpp"
#include "llxmlparser.cpp"
+95
View File
@@ -0,0 +1,95 @@
#!/usr/bin/env python3
"""\
@file test_llxmlrpc_peer.py
@author Nat Goodspeed
@date 2008-10-09
@brief This script asynchronously runs the executable (with args) specified on
the command line, returning its result code. While that executable is
running, we provide dummy local services for use by C++ tests.
$LicenseInfo:firstyear=2008&license=viewerlgpl$
Second Life Viewer Source Code
Copyright (C) 2010, Linden Research, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation;
version 2.1 of the License only.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
$/LicenseInfo$
"""
import os
import sys
from xmlrpc.server import SimpleXMLRPCServer
mydir = os.path.dirname(__file__) # expected to be .../indra/newview/tests/
sys.path.insert(0, os.path.join(mydir, os.pardir, os.pardir, "llmessage", "tests"))
from testrunner import freeport, run, debug
class TestServer(SimpleXMLRPCServer):
# This server_bind() override is borrowed and simplified from
# BaseHTTPServer.HTTPServer.server_bind(): we want to capture the actual
# server port. BaseHTTPServer.HTTPServer.server_bind() stores the actual
# port in a server_port attribute, but SimpleXMLRPCServer isn't derived
# from HTTPServer. So do it ourselves.
def server_bind(self):
"""Override server_bind to store the server port."""
SimpleXMLRPCServer.server_bind(self)
self.server_port = self.socket.getsockname()[1]
def _dispatch(self, method, params):
try:
func = getattr(self, method)
except AttributeError:
raise Exception('method "%s" is not supported' % method)
else:
# LLXMLRPCListener constructs XMLRPC parameters that arrive as a
# 1-tuple containing a dict.
return func(**(params[0]))
def hello(self, who):
# LLXMLRPCListener expects a dict return.
return {"hi_there": "Hello, %s!" % who}
def getdict(self):
return dict(nested_dict=dict(a=17, b=5))
def log_request(self, code, size=None):
# For present purposes, we don't want the request splattered onto
# stderr, as it would upset devs watching the test run
pass
def log_error(self, format, *args):
# Suppress error output as well
pass
if __name__ == "__main__":
# function to make a server with specified port
make_server = lambda port: TestServer(('127.0.0.1', port))
if not sys.platform.startswith("win"):
# Instantiate a TestServer on a port chosen by the runtime.
xmlrpcd = make_server(0)
else:
# "Then there's Windows"
# Instantiate a TestServer on the first free port in the specified
# port range.
xmlrpcd, port = freeport(range(8000, 8020), make_server)
# Pass the selected port number to the subject test program via the
# environment. We don't want to impose requirements on the test program's
# command-line parsing -- and anyway, for C++ integration tests, that's
# performed in TUT code rather than our own.
os.environ["PORT"] = str(xmlrpcd.server_port)
sys.exit(run(server_inst=xmlrpcd, *sys.argv[1:]))