Imported existing code

This commit is contained in:
Hazim Gazov
2010-04-02 02:48:44 -03:00
parent 48fbc5ae91
commit 7a86d01598
13996 changed files with 2468699 additions and 0 deletions

169
indra/test/CMakeLists.txt Normal file
View File

@@ -0,0 +1,169 @@
# -*- cmake -*-
project (test)
include(00-Common)
include(LLCommon)
include(LLDatabase)
include(LLInventory)
include(LLMath)
include(LLMessage)
include(LLVFS)
include(LLXML)
include(LScript)
include(Linking)
include(Tut)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLDATABASE_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLMESSAGE_INCLUDE_DIRS}
${LLINVENTORY_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
${LSCRIPT_INCLUDE_DIRS}
)
set(test_SOURCE_FILES
common.cpp
inventory.cpp
io.cpp
# llapp_tut.cpp # Temporarily removed until thread issues can be solved
llbase64_tut.cpp
llblowfish_tut.cpp
llbuffer_tut.cpp
lldate_tut.cpp
llerror_tut.cpp
llhost_tut.cpp
llhttpdate_tut.cpp
llhttpclient_tut.cpp
llhttpnode_tut.cpp
llinventoryparcel_tut.cpp
lliohttpserver_tut.cpp
lljoint_tut.cpp
llmime_tut.cpp
llmessageconfig_tut.cpp
llmodularmath_tut.cpp
llnamevalue_tut.cpp
llpermissions_tut.cpp
llpipeutil.cpp
llquaternion_tut.cpp
llrandom_tut.cpp
llsaleinfo_tut.cpp
llscriptresource_tut.cpp
llsdmessagebuilder_tut.cpp
llsdmessagereader_tut.cpp
llsd_new_tut.cpp
llsdserialize_tut.cpp
llsdutil_tut.cpp
llservicebuilder_tut.cpp
llstreamtools_tut.cpp
llstring_tut.cpp
lltemplatemessagebuilder_tut.cpp
lltimestampcache_tut.cpp
lltiming_tut.cpp
lltranscode_tut.cpp
lltut.cpp
lluri_tut.cpp
lluuidhashmap_tut.cpp
llxfer_tut.cpp
math.cpp
message_tut.cpp
reflection_tut.cpp
test.cpp
v2math_tut.cpp
v3color_tut.cpp
v3dmath_tut.cpp
v3math_tut.cpp
v4color_tut.cpp
v4coloru_tut.cpp
v4math_tut.cpp
)
set(test_HEADER_FILES
CMakeLists.txt
llpipeutil.h
llsdtraits.h
lltut.h
)
if (NOT WINDOWS)
list(APPEND test_SOURCE_FILES
llmessagetemplateparser_tut.cpp
)
endif (NOT WINDOWS)
if (NOT DARWIN)
list(APPEND test_SOURCE_FILES
)
endif (NOT DARWIN)
set_source_files_properties(${test_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
list(APPEND test_SOURC_FILES ${test_HEADER_FILES})
add_executable(test ${test_SOURCE_FILES})
target_link_libraries(test
${LLDATABASE_LIBRARIES}
${LLINVENTORY_LIBRARIES}
${LLMESSAGE_LIBRARIES}
${LLMATH_LIBRARIES}
${LLVFS_LIBRARIES}
${LLXML_LIBRARIES}
${LSCRIPT_LIBRARIES}
${LLCOMMON_LIBRARIES}
${APRICONV_LIBRARIES}
${PTHREAD_LIBRARY}
${WINDOWS_LIBRARIES}
${DL_LIBRARY}
)
if (WINDOWS)
set_target_properties(test
PROPERTIES
LINK_FLAGS "/NODEFAULTLIB:LIBCMT"
LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\""
)
endif (WINDOWS)
get_target_property(TEST_EXE test LOCATION)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cpp_tests_ok.txt
COMMAND ${TEST_EXE}
ARGS
--output=${CMAKE_CURRENT_BINARY_DIR}/cpp_test_results.txt
--touch=${CMAKE_CURRENT_BINARY_DIR}/cpp_tests_ok.txt
DEPENDS test
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "C++ unit tests"
)
set(test_results ${CMAKE_CURRENT_BINARY_DIR}/cpp_tests_ok.txt)
if (EXISTS /etc/debian_version_FAIL)
# The Python tests have all kinds of wacky non-portable assumptions
# built in.
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/py_tests_ok.txt
COMMAND ${PYTHON_EXECUTABLE}
ARGS
${CMAKE_CURRENT_SOURCE_DIR}/test.py
--mode=static
--output=${CMAKE_CURRENT_BINARY_DIR}/py_test_results.txt
--touch=${CMAKE_CURRENT_BINARY_DIR}/py_tests_ok.txt
--mode=static
DEPENDS test.py
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Python unit tests"
)
list(APPEND test_results ${CMAKE_CURRENT_BINARY_DIR}/py_tests_ok.txt)
endif (EXISTS /etc/debian_version_FAIL)
add_custom_target(tests_ok ALL DEPENDS ${test_results})

View File

@@ -0,0 +1 @@
.A<><41>3<EFBFBD>L<EFBFBD>E ``<60><03><>K<EFBFBD>@<40><><EFBFBD>;M[<05>B<EFBFBD><42><04><>><3E><>C<EFBFBD>'

BIN
indra/test/blowfish.2.bin Normal file

Binary file not shown.

View File

@@ -0,0 +1 @@
01234567890123456789012345678901234

79
indra/test/blowfish.pl Executable file
View File

@@ -0,0 +1,79 @@
#!/usr/bin/perl
#
# Test Perl Crypt::CBC Blowfish algorithm and initial parameter settings
# for compatibility with OpenSSL's Blowfish algorithm/settings.
#
# Used by outbound LSL email (openssl C library) and mailglue (Perl library)
use strict;
use warnings;
# *TODO: specify test count here
use Test::More qw(no_plan);
use Crypt::CBC;
use MIME::Base64;
my $init_vector = "\x00" x 8;
# my $key = pack("H*", "ef5a8376eb0c99fe0dafa487d15bec19cae63d1e25fe31d8d92f7ab0398246d70ee733108e47360e16359654571cf5bab6c3375b42cee4fa");
# my $key = "d263eb8a78034e40";
#"8d082918aa369174";
my $key = "\x00" x 16;
my $cipher = Crypt::CBC->new( { cipher => 'Blowfish',
regenerate_key => 0,
key => $key,
iv => $init_vector,
header => 'none',
prepend_iv => 0,
keysize => 16 } );
#my $blocks = $cipher->blocksize();
#print "blocksize $blocks\n";
my $len;
my $input = "01234567890123456789012345678901234\n";
#my $input = "a whale of a tale I tell you lad, a whale of a tale for me, a whale of a tale and the fiddlers three";
$len = length($input);
is ($len, 36, "input length");
$len = length($key);
is ($len, 16, "key length");
my $encrypted = $cipher->encrypt($input);
is (length($encrypted), 40, "encrypted length");
open(FH, "blowfish.1.bin");
my $bin = scalar <FH>;
is ($encrypted, $bin, "matches openssl");
close(FH);
my $base64 = encode_base64($encrypted);
is ($base64, "LkGExDOMTNxFIGBg8gP43UvbQLz7xztNWwYF2kLrtwT4hD7LykOXJw==\n",
"base64 output");
my $unbase64 = decode_base64($base64);
is( $encrypted, $unbase64, "reverse base64" );
my $output = $cipher->decrypt($unbase64);
is ($input, $output, "reverse encrypt");
$key = pack("H[32]", "526a1e07a19dbaed84c4ff08a488d15e");
$cipher = Crypt::CBC->new( { cipher => 'Blowfish',
regenerate_key => 0,
key => $key,
iv => $init_vector,
header => 'none',
prepend_iv => 0,
keysize => 16 } );
$encrypted = $cipher->encrypt($input);
is (length($encrypted), 40, "uuid encrypted length");
$output = $cipher->decrypt($encrypted);
is ($input, $output, "uuid reverse encrypt");
open(FH, "blowfish.2.bin");
$bin = scalar <FH>;
close(FH);
is( $encrypted, $bin, "uuid matches openssl" );
print encode_base64($encrypted);

675
indra/test/common.cpp Normal file
View File

@@ -0,0 +1,675 @@
/**
* @file common.cpp
* @author Phoenix
* @date 2005-10-12
* @brief Common templates for test framework
*
* $LicenseInfo:firstyear=2005&license=viewergpl$
*
* Copyright (c) 2005-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
/**
*
* THOROUGH_DESCRIPTION of common.cpp
*
*/
#include "linden_common.h"
#include "lltut.h"
#include <algorithm>
#include <iomanip>
#include <iterator>
#include "llmemorystream.h"
#include "llsd.h"
#include "llsdserialize.h"
#include "u64.h"
#include "llhash.h"
#if LL_WINDOWS
// disable overflow warnings
#pragma warning(disable: 4307)
#endif
namespace tut
{
struct sd_data
{
};
typedef test_group<sd_data> sd_test;
typedef sd_test::object sd_object;
tut::sd_test sd("llsd");
template<> template<>
void sd_object::test<1>()
{
std::ostringstream resp;
resp << "{'connect':true, 'position':[r128,r128,r128], 'look_at':[r0,r1,r0], 'agent_access':'M', 'region_x':i8192, 'region_y':i8192}";
std::string str = resp.str();
LLMemoryStream mstr((U8*)str.c_str(), str.size());
LLSD response;
S32 count = LLSDSerialize::fromNotation(response, mstr, str.size());
ensure("stream parsed", response.isDefined());
ensure_equals("stream parse count", count, 13);
ensure_equals("sd type", response.type(), LLSD::TypeMap);
ensure_equals("map element count", response.size(), 6);
ensure_equals("value connect", response["connect"].asBoolean(), true);
ensure_equals("value region_x", response["region_x"].asInteger(),8192);
ensure_equals("value region_y", response["region_y"].asInteger(),8192);
}
template<> template<>
void sd_object::test<2>()
{
const std::string decoded("random");
//const std::string encoded("cmFuZG9t\n");
const std::string streamed("b(6)\"random\"");
typedef std::vector<U8> buf_t;
buf_t buf;
std::copy(
decoded.begin(),
decoded.end(),
std::back_insert_iterator<buf_t>(buf));
LLSD sd;
sd = buf;
std::stringstream str;
S32 count = LLSDSerialize::toNotation(sd, str);
ensure_equals("output count", count, 1);
std::string actual(str.str());
ensure_equals("formatted binary encoding", actual, streamed);
sd.clear();
LLSDSerialize::fromNotation(sd, str, str.str().size());
std::vector<U8> after;
after = sd.asBinary();
ensure_equals("binary decoded size", after.size(), decoded.size());
ensure("binary decoding", (0 == memcmp(
&after[0],
decoded.c_str(),
decoded.size())));
}
template<> template<>
void sd_object::test<3>()
{
for(S32 i = 0; i < 100; ++i)
{
// gen up a starting point
typedef std::vector<U8> buf_t;
buf_t source;
srand(i); /* Flawfinder: ignore */
S32 size = rand() % 1000 + 10;
std::generate_n(
std::back_insert_iterator<buf_t>(source),
size,
rand);
LLSD sd(source);
std::stringstream str;
S32 count = LLSDSerialize::toNotation(sd, str);
sd.clear();
ensure_equals("format count", count, 1);
LLSD sd2;
count = LLSDSerialize::fromNotation(sd2, str, str.str().size());
ensure_equals("parse count", count, 1);
buf_t dest = sd2.asBinary();
str.str("");
str << "binary encoding size " << i;
ensure_equals(str.str().c_str(), dest.size(), source.size());
str.str("");
str << "binary encoding " << i;
ensure(str.str().c_str(), (source == dest));
}
}
template<> template<>
void sd_object::test<4>()
{
std::ostringstream ostr;
ostr << "{'task_id':u1fd77b79-a8e7-25a5-9454-02a4d948ba1c}\n"
<< "{\n\tname\tObject|\n}\n";
std::string expected = ostr.str();
std::stringstream serialized;
serialized << "'" << LLSDNotationFormatter::escapeString(expected)
<< "'";
LLSD sd;
S32 count = LLSDSerialize::fromNotation(
sd,
serialized,
serialized.str().size());
ensure_equals("parse count", count, 1);
ensure_equals("String streaming", sd.asString(), expected);
}
template<> template<>
void sd_object::test<5>()
{
for(S32 i = 0; i < 100; ++i)
{
// gen up a starting point
typedef std::vector<U8> buf_t;
buf_t source;
srand(666 + i); /* Flawfinder: ignore */
S32 size = rand() % 1000 + 10;
std::generate_n(
std::back_insert_iterator<buf_t>(source),
size,
rand);
std::stringstream str;
str << "b(" << size << ")\"";
str.write((const char*)&source[0], size);
str << "\"";
LLSD sd;
S32 count = LLSDSerialize::fromNotation(sd, str, str.str().size());
ensure_equals("binary parse", count, 1);
buf_t actual = sd.asBinary();
ensure_equals("binary size", actual.size(), (size_t)size);
ensure("binary data", (0 == memcmp(&source[0], &actual[0], size)));
}
}
template<> template<>
void sd_object::test<6>()
{
std::string expected("'{\"task_id\":u1fd77b79-a8e7-25a5-9454-02a4d948ba1c}'\t\n\t\t");
std::stringstream str;
str << "s(" << expected.size() << ")'";
str.write(expected.c_str(), expected.size());
str << "'";
LLSD sd;
S32 count = LLSDSerialize::fromNotation(sd, str, str.str().size());
ensure_equals("parse count", count, 1);
std::string actual = sd.asString();
ensure_equals("string sizes", actual.size(), expected.size());
ensure_equals("string content", actual, expected);
}
template<> template<>
void sd_object::test<7>()
{
std::string msg("come on in");
std::stringstream stream;
stream << "{'connect':1, 'message':'" << msg << "',"
<< " 'position':[r45.65,r100.1,r25.5],"
<< " 'look_at':[r0,r1,r0],"
<< " 'agent_access':'PG'}";
LLSD sd;
S32 count = LLSDSerialize::fromNotation(
sd,
stream,
stream.str().size());
ensure_equals("parse count", count, 12);
ensure_equals("bool value", sd["connect"].asBoolean(), true);
ensure_equals("message value", sd["message"].asString(), msg);
ensure_equals("pos x", sd["position"][0].asReal(), 45.65);
ensure_equals("pos y", sd["position"][1].asReal(), 100.1);
ensure_equals("pos z", sd["position"][2].asReal(), 25.5);
ensure_equals("look x", sd["look_at"][0].asReal(), 0.0);
ensure_equals("look y", sd["look_at"][1].asReal(), 1.0);
ensure_equals("look z", sd["look_at"][2].asReal(), 0.0);
}
template<> template<>
void sd_object::test<8>()
{
std::stringstream resp;
resp << "{'label':'short string test', 'singlechar':'a', 'empty':'', 'endoftest':'end' }";
LLSD response;
S32 count = LLSDSerialize::fromNotation(
response,
resp,
resp.str().size());
ensure_equals("parse count", count, 5);
ensure_equals("sd type", response.type(), LLSD::TypeMap);
ensure_equals("map element count", response.size(), 4);
ensure_equals("singlechar", response["singlechar"].asString(), "a");
ensure_equals("empty", response["empty"].asString(), "");
}
template<> template<>
void sd_object::test<9>()
{
std::ostringstream resp;
resp << "{'label':'short binary test', 'singlebinary':b(1)\"A\", 'singlerawstring':s(1)\"A\", 'endoftest':'end' }";
std::string str = resp.str();
LLSD sd;
LLMemoryStream mstr((U8*)str.c_str(), str.size());
S32 count = LLSDSerialize::fromNotation(sd, mstr, str.size());
ensure_equals("parse count", count, 5);
ensure("sd created", sd.isDefined());
ensure_equals("sd type", sd.type(), LLSD::TypeMap);
ensure_equals("map element count", sd.size(), 4);
ensure_equals(
"label",
sd["label"].asString(),
"short binary test");
std::vector<U8> bin = sd["singlebinary"].asBinary();
std::vector<U8> expected;
expected.resize(1);
expected[0] = 'A';
ensure("single binary", (0 == memcmp(&bin[0], &expected[0], 1)));
ensure_equals(
"single string",
sd["singlerawstring"].asString(),
std::string("A"));
ensure_equals("end", sd["endoftest"].asString(), "end");
}
template<> template<>
void sd_object::test<10>()
{
std::string message("parcel '' is naughty.");
std::stringstream str;
str << "{'message':'" << LLSDNotationFormatter::escapeString(message)
<< "'}";
std::string expected_str("{'message':'parcel \\'\\' is naughty.'}");
std::string actual_str = str.str();
ensure_equals("stream contents", actual_str, expected_str);
LLSD sd;
S32 count = LLSDSerialize::fromNotation(sd, str, actual_str.size());
ensure_equals("parse count", count, 2);
ensure("valid parse", sd.isDefined());
std::string actual = sd["message"].asString();
ensure_equals("message contents", actual, message);
}
template<> template<>
void sd_object::test<11>()
{
std::string expected("\"\"\"\"''''''\"");
std::stringstream str;
str << "'" << LLSDNotationFormatter::escapeString(expected) << "'";
LLSD sd;
S32 count = LLSDSerialize::fromNotation(sd, str, str.str().size());
ensure_equals("parse count", count, 1);
ensure_equals("string value", sd.asString(), expected);
}
template<> template<>
void sd_object::test<12>()
{
std::string expected("mytest\\");
std::stringstream str;
str << "'" << LLSDNotationFormatter::escapeString(expected) << "'";
LLSD sd;
S32 count = LLSDSerialize::fromNotation(sd, str, str.str().size());
ensure_equals("parse count", count, 1);
ensure_equals("string value", sd.asString(), expected);
}
template<> template<>
void sd_object::test<13>()
{
for(S32 i = 0; i < 1000; ++i)
{
// gen up a starting point
std::string expected;
srand(1337 + i); /* Flawfinder: ignore */
S32 size = rand() % 30 + 5;
std::generate_n(
std::back_insert_iterator<std::string>(expected),
size,
rand);
std::stringstream str;
str << "'" << LLSDNotationFormatter::escapeString(expected) << "'";
LLSD sd;
S32 count = LLSDSerialize::fromNotation(sd, str, expected.size());
ensure_equals("parse count", count, 1);
std::string actual = sd.asString();
/*
if(actual != expected)
{
llwarns << "iteration " << i << llendl;
std::ostringstream e_str;
std::string::iterator iter = expected.begin();
std::string::iterator end = expected.end();
for(; iter != end; ++iter)
{
e_str << (S32)((U8)(*iter)) << " ";
}
e_str << std::endl;
llsd_serialize_string(e_str, expected);
llwarns << "expected size: " << expected.size() << llendl;
llwarns << "expected: " << e_str.str() << llendl;
std::ostringstream a_str;
iter = actual.begin();
end = actual.end();
for(; iter != end; ++iter)
{
a_str << (S32)((U8)(*iter)) << " ";
}
a_str << std::endl;
llsd_serialize_string(a_str, actual);
llwarns << "actual size: " << actual.size() << llendl;
llwarns << "actual: " << a_str.str() << llendl;
}
*/
ensure_equals("string value", actual, expected);
}
}
template<> template<>
void sd_object::test<14>()
{
//#if LL_WINDOWS && _MSC_VER >= 1400
// skip_fail("Fails on VS2005 due to broken LLSDSerialize::fromNotation() parser.");
//#endif
std::string param = "[{'version':i1},{'data':{'binary_bucket':b(0)\"\"},'from_id':u3c115e51-04f4-523c-9fa6-98aff1034730,'from_name':'Phoenix Linden','id':u004e45e5-5576-277a-fba7-859d6a4cb5c8,'message':'hey','offline':i0,'timestamp':i0,'to_id':u3c5f1bb4-5182-7546-6401-1d329b4ff2f8,'type':i0},{'agent_id':u3c115e51-04f4-523c-9fa6-98aff1034730,'god_level':i0,'limited_to_estate':i1}]";
std::istringstream istr;
istr.str(param);
LLSD param_sd;
LLSDSerialize::fromNotation(param_sd, istr, param.size());
ensure_equals("parsed type", param_sd.type(), LLSD::TypeArray);
LLSD version_sd = param_sd[0];
ensure_equals("version type", version_sd.type(), LLSD::TypeMap);
ensure("has version", version_sd.has("version"));
ensure_equals("version number", version_sd["version"].asInteger(), 1);
LLSD src_sd = param_sd[1];
ensure_equals("src type", src_sd.type(), LLSD::TypeMap);
LLSD dst_sd = param_sd[2];
ensure_equals("dst type", dst_sd.type(), LLSD::TypeMap);
}
template<> template<>
void sd_object::test<15>()
{
std::string val = "[{'failures':!,'successfuls':[u3c115e51-04f4-523c-9fa6-98aff1034730]}]";
std::istringstream istr;
istr.str(val);
LLSD sd;
LLSDSerialize::fromNotation(sd, istr, val.size());
ensure_equals("parsed type", sd.type(), LLSD::TypeArray);
ensure_equals("parsed size", sd.size(), 1);
LLSD failures = sd[0]["failures"];
ensure("no failures.", failures.isUndefined());
LLSD success = sd[0]["successfuls"];
ensure_equals("success type", success.type(), LLSD::TypeArray);
ensure_equals("success size", success.size(), 1);
ensure_equals("success instance type", success[0].type(), LLSD::TypeUUID);
}
template<> template<>
void sd_object::test<16>()
{
std::string val = "[f,t,0,1,{'foo':t,'bar':f}]";
std::istringstream istr;
istr.str(val);
LLSD sd;
LLSDSerialize::fromNotation(sd, istr, val.size());
ensure_equals("parsed type", sd.type(), LLSD::TypeArray);
ensure_equals("parsed size", sd.size(), 5);
ensure_equals("element 0 false", sd[0].asBoolean(), false);
ensure_equals("element 1 true", sd[1].asBoolean(), true);
ensure_equals("element 2 false", sd[2].asBoolean(), false);
ensure_equals("element 3 true", sd[3].asBoolean(), true);
LLSD map = sd[4];
ensure_equals("element 4 type", map.type(), LLSD::TypeMap);
ensure_equals("map foo type", map["foo"].type(), LLSD::TypeBoolean);
ensure_equals("map foo value", map["foo"].asBoolean(), true);
ensure_equals("map bar type", map["bar"].type(), LLSD::TypeBoolean);
ensure_equals("map bar value", map["bar"].asBoolean(), false);
}
/*
template<> template<>
void sd_object::test<16>()
{
}
*/
}
#if 0
'{\'task_id\':u1fd77b79-a8e7-25a5-9454-02a4d948ba1c}\n{\n\tname\tObject|\n\tpermissions 0\n\t{\n\t\tbase_mask\t7fffffff\n\t\towner_mask\t7fffffff\n\t\tgroup_mask\t00000000\n\t\teveryone_mask\t00000000\n\t\tnext_owner_mask\t00082000\n\t\tcreator_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\towner_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\tlast_owner_id\t00000000-0000-0000-0000-000000000000\n\t\tgroup_id\t00000000-0000-0000-0000-000000000000\n\t}\n\tlocal_id\t10284\n\ttotal_crc\t35\n\ttype\t1\n\ttask_valid\t2\n\ttravel_access\t21\n\tdisplayopts\t2\n\tdisplaytype\tv\n\tpos\t0\t0\t0\n\toldpos\t0\t0\t0\n\trotation\t4.371139183945160766597837e-08\t1\t4.371139183945160766597837e-08\t0\n\tvelocity\t0\t0\t0\n\tangvel\t0\t0\t0\n\tscale\t0.2816932\t0.2816932\t0.2816932\n\tsit_offset\t0\t0\t0\n\tcamera_eye_offset\t0\t0\t0\n\tcamera_at_offset\t0\t0\t0\n\tsit_quat\t0\t0\t0\t1\n\tsit_hint\t0\n\tstate\t80\n\tmaterial\t3\n\tsoundid\t00000000-0000-0000-0000-000000000000\n\tsoundgain\t0\n\tsoundradius\t0\n\tsoundflags\t0\n\ttextcolor\t0 0 0 1\n\tselected\t0\n\tselector\t00000000-0000-0000-0000-000000000000\n\tusephysics\t0\n\trotate_x\t1\n\trotate_y\t1\n\trotate_z\t1\n\tphantom\t0\n\tremote_script_access_pin\t0\n\tvolume_detect\t0\n\tblock_grabs\t0\n\tdie_at_edge\t0\n\treturn_at_edge\t0\n\ttemporary\t0\n\tsandbox\t0\n\tsandboxhome\t0\t0\t0\n\tshape 0\n\t{\n\t\tpath 0\n\t\t{\n\t\t\tcurve\t16\n\t\t\tbegin\t0\n\t\t\tend\t1\n\t\t\tscale_x\t1\n\t\t\tscale_y\t1\n\t\t\tshear_x\t0\n\t\t\tshear_y\t0\n\t\t\ttwist\t0\n\t\t\ttwist_begin\t0\n\t\t\tradius_offset\t0\n\t\t\ttaper_x\t0\n\t\t\ttaper_y\t0\n\t\t\trevolutions\t1\n\t\t\tskew\t0\n\t\t}\n\t\tprofile 0\n\t\t{\n\t\t\tcurve\t1\n\t\t\tbegin\t0\n\t\t\tend\t1\n\t\t\thollow\t0\n\t\t}\n\t}\n\tfaces\t6\n\t{\n\t\timageid\t89556747-24cb-43ed-920b-47caed15465f\n\t\tcolors\t1 1 1 1\n\t\tscales\t0.56\n\t\tscalet\t0.56\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\t89556747-24cb-43ed-920b-47caed15465f\n\t\tcolors\t1 1 1 1\n\t\tscales\t0.56\n\t\tscalet\t0.56\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\t89556747-24cb-43ed-920b-47caed15465f\n\t\tcolors\t1 1 1 1\n\t\tscales\t0.56\n\t\tscalet\t0.56\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\t89556747-24cb-43ed-920b-47caed15465f\n\t\tcolors\t1 1 1 1\n\t\tscales\t0.56\n\t\tscalet\t0.56\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\t89556747-24cb-43ed-920b-47caed15465f\n\t\tcolors\t1 1 1 1\n\t\tscales\t0.56\n\t\tscalet\t0.56\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\t89556747-24cb-43ed-920b-47caed15465f\n\t\tcolors\t1 1 1 1\n\t\tscales\t0.56\n\t\tscalet\t0.56\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\tps_next_crc\t1\n\tgpw_bias\t1\n\tip\t0\n\tcomplete\tTRUE\n\tdelay\t50000\n\tnextstart\t1132625972249870\n\tbirthtime\t1132625953120694\n\treztime\t1132625953120694\n\tparceltime\t1132625953120694\n\ttax_rate\t1.01615\n\tnamevalue\tAttachmentOrientation VEC3 RW DS -3.141593, 0.000000, -3.141593\n\tnamevalue\tAttachmentOffset VEC3 RW DS 0.000000, 0.000000, 0.000000\n\tnamevalue\tAttachPt U32 RW S 5\n\tnamevalue\tAttachItemID STRING RW SV 1f9975c0-2951-1b93-dd83-46e2b932fcc8\n\tscratchpad\t0\n\t{\n\t\n\t}\n\tsale_info\t0\n\t{\n\t\tsale_type\tnot\n\t\tsale_price\t10\n\t}\n\torig_asset_id\t52019cdd-b464-ba19-e66d-3da751fef9da\n\torig_item_id\t1f9975c0-2951-1b93-dd83-46e2b932fcc8\n\tcorrect_family_id\t00000000-0000-0000-0000-000000000000\n\thas_rezzed\t0\n\tpre_link_base_mask\t7fffffff\n\tdefault_pay_price\t-2\t1\t5\t10\t20\n}\n'
#endif
namespace tut
{
struct mem_data
{
};
typedef test_group<mem_data> mem_test;
typedef mem_test::object mem_object;
tut::mem_test mem_stream("memory_stream");
template<> template<>
void mem_object::test<1>()
{
const char HELLO_WORLD[] = "hello world";
LLMemoryStream mem((U8*)&HELLO_WORLD[0], strlen(HELLO_WORLD)); /* Flawfinder: ignore */
std::string hello;
std::string world;
mem >> hello >> world;
ensure_equals("first word", hello, std::string("hello"));
ensure_equals("second word", world, std::string("world"));
}
}
namespace tut
{
struct U64_data
{
};
typedef test_group<U64_data> U64_test;
typedef U64_test::object U64_object;
tut::U64_test U64_testcase("U64_conversion");
// U64_to_str
template<> template<>
void U64_object::test<1>()
{
U64 val;
std::string val_str;
char result[256];
std::string result_str;
val = U64L(18446744073709551610); // slightly less than MAX_U64
val_str = "18446744073709551610";
U64_to_str(val, result, sizeof(result));
result_str = (const char*) result;
ensure_equals("U64_to_str converted 1.1", val_str, result_str);
val = 0;
val_str = "0";
U64_to_str(val, result, sizeof(result));
result_str = (const char*) result;
ensure_equals("U64_to_str converted 1.2", val_str, result_str);
val = U64L(18446744073709551615); // 0xFFFFFFFFFFFFFFFF
val_str = "18446744073709551615";
U64_to_str(val, result, sizeof(result));
result_str = (const char*) result;
ensure_equals("U64_to_str converted 1.3", val_str, result_str);
// overflow - will result in warning at compile time
val = U64L(18446744073709551615) + 1; // overflow 0xFFFFFFFFFFFFFFFF + 1 == 0
val_str = "0";
U64_to_str(val, result, sizeof(result));
result_str = (const char*) result;
ensure_equals("U64_to_str converted 1.4", val_str, result_str);
val = U64L(-1); // 0xFFFFFFFFFFFFFFFF == 18446744073709551615
val_str = "18446744073709551615";
U64_to_str(val, result, sizeof(result));
result_str = (const char*) result;
ensure_equals("U64_to_str converted 1.5", val_str, result_str);
val = U64L(10000000000000000000); // testing preserving of 0s
val_str = "10000000000000000000";
U64_to_str(val, result, sizeof(result));
result_str = (const char*) result;
ensure_equals("U64_to_str converted 1.6", val_str, result_str);
val = 1; // testing no leading 0s
val_str = "1";
U64_to_str(val, result, sizeof(result));
result_str = (const char*) result;
ensure_equals("U64_to_str converted 1.7", val_str, result_str);
val = U64L(18446744073709551615); // testing exact sized buffer for result
val_str = "18446744073709551615";
memset(result, 'A', sizeof(result)); // initialize buffer with all 'A'
U64_to_str(val, result, sizeof("18446744073709551615")); //pass in the exact size
result_str = (const char*) result;
ensure_equals("U64_to_str converted 1.8", val_str, result_str);
val = U64L(18446744073709551615); // testing smaller sized buffer for result
val_str = "1844";
memset(result, 'A', sizeof(result)); // initialize buffer with all 'A'
U64_to_str(val, result, 5); //pass in a size of 5. should only copy first 4 integers and add a null terminator
result_str = (const char*) result;
ensure_equals("U64_to_str converted 1.9", val_str, result_str);
}
// str_to_U64
template<> template<>
void U64_object::test<2>()
{
U64 val;
U64 result;
val = U64L(18446744073709551610); // slightly less than MAX_U64
result = str_to_U64("18446744073709551610");
ensure_equals("str_to_U64 converted 2.1", val, result);
val = U64L(0); // empty string
result = str_to_U64(LLStringUtil::null);
ensure_equals("str_to_U64 converted 2.2", val, result);
val = U64L(0); // 0
result = str_to_U64("0");
ensure_equals("str_to_U64 converted 2.3", val, result);
val = U64L(18446744073709551615); // 0xFFFFFFFFFFFFFFFF
result = str_to_U64("18446744073709551615");
ensure_equals("str_to_U64 converted 2.4", val, result);
// overflow - will result in warning at compile time
val = U64L(18446744073709551615) + 1; // overflow 0xFFFFFFFFFFFFFFFF + 1 == 0
result = str_to_U64("18446744073709551616");
ensure_equals("str_to_U64 converted 2.5", val, result);
val = U64L(1234); // process till first non-integral character
result = str_to_U64("1234A5678");
ensure_equals("str_to_U64 converted 2.6", val, result);
val = U64L(5678); // skip all non-integral characters
result = str_to_U64("ABCD5678");
ensure_equals("str_to_U64 converted 2.7", val, result);
// should it skip negative sign and process
// rest of string or return 0
val = U64L(1234); // skip initial negative sign
result = str_to_U64("-1234");
ensure_equals("str_to_U64 converted 2.8", val, result);
val = U64L(5678); // stop at negative sign in the middle
result = str_to_U64("5678-1234");
ensure_equals("str_to_U64 converted 2.9", val, result);
val = U64L(0); // no integers
result = str_to_U64("AaCD");
ensure_equals("str_to_U64 converted 2.10", val, result);
}
// U64_to_F64
template<> template<>
void U64_object::test<3>()
{
F64 val;
F64 result;
result = 18446744073709551610.0;
val = U64_to_F64(U64L(18446744073709551610));
ensure_equals("U64_to_F64 converted 3.1", val, result);
result = 18446744073709551615.0; // 0xFFFFFFFFFFFFFFFF
val = U64_to_F64(U64L(18446744073709551615));
ensure_equals("U64_to_F64 converted 3.2", val, result);
result = 0.0; // overflow 0xFFFFFFFFFFFFFFFF + 1 == 0
// overflow - will result in warning at compile time
val = U64_to_F64(U64L(18446744073709551615)+1);
ensure_equals("U64_to_F64 converted 3.3", val, result);
result = 0.0; // 0
val = U64_to_F64(U64L(0));
ensure_equals("U64_to_F64 converted 3.4", val, result);
result = 1.0; // odd
val = U64_to_F64(U64L(1));
ensure_equals("U64_to_F64 converted 3.5", val, result);
result = 2.0; // even
val = U64_to_F64(U64L(2));
ensure_equals("U64_to_F64 converted 3.6", val, result);
result = U64L(0x7FFFFFFFFFFFFFFF) * 1.0L; // 0x7FFFFFFFFFFFFFFF
val = U64_to_F64(U64L(0x7FFFFFFFFFFFFFFF));
ensure_equals("U64_to_F64 converted 3.7", val, result);
}
// llstrtou64
// seems to be deprecated - could not find it being used
// anywhere in the tarball - skipping unit tests for now
}
namespace tut
{
struct hash_data
{
};
typedef test_group<hash_data> hash_test;
typedef hash_test::object hash_object;
tut::hash_test hash_tester("hash_test");
template<> template<>
void hash_object::test<1>()
{
const char * str1 = "test string one";
const char * same_as_str1 = "test string one";
size_t hash1 = llhash(str1);
size_t same_as_hash1 = llhash(same_as_str1);
ensure("Hashes from identical strings should be equal", hash1 == same_as_hash1);
char str[100];
strcpy( str, "Another test" );
size_t hash2 = llhash(str);
strcpy( str, "Different string, same pointer" );
size_t hash3 = llhash(str);
ensure("Hashes from same pointer but different string should not be equal", hash2 != hash3);
}
}

539
indra/test/inventory.cpp Normal file
View File

@@ -0,0 +1,539 @@
/**
* @file inventory.cpp
* @author Phoenix
* @date 2005-11-15
* @brief Functions for inventory test framework
*
* $LicenseInfo:firstyear=2005&license=viewergpl$
*
* Copyright (c) 2005-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "lltut.h"
#include "llinventory.h"
#include "llsd.h"
#if LL_WINDOWS
// disable unreachable code warnings
#pragma warning(disable: 4702)
#endif
LLPointer<LLInventoryItem> create_random_inventory_item()
{
LLUUID item_id;
item_id.generate();
LLUUID parent_id;
parent_id.generate();
LLPermissions perm;
LLUUID creator_id;
creator_id.generate();
LLUUID owner_id;
owner_id.generate();
LLUUID last_owner_id;
last_owner_id.generate();
LLUUID group_id;
group_id.generate();
perm.init(creator_id, owner_id, last_owner_id, group_id);
perm.initMasks(PERM_ALL, PERM_ALL, PERM_COPY, PERM_COPY, PERM_MODIFY | PERM_COPY);
LLUUID asset_id;
asset_id.generate();
S32 price = rand();
LLSaleInfo sale_info(LLSaleInfo::FS_COPY, price);
U32 flags = rand();
S32 creation = time(NULL);
LLPointer<LLInventoryItem> item = new LLInventoryItem(
item_id,
parent_id,
perm,
asset_id,
LLAssetType::AT_OBJECT,
LLInventoryType::IT_ATTACHMENT,
std::string("Sample Object"),
std::string("Used for Testing"),
sale_info,
flags,
creation);
return item;
}
LLPointer<LLInventoryCategory> create_random_inventory_cat()
{
LLUUID item_id;
item_id.generate();
LLUUID parent_id;
parent_id.generate();
LLPointer<LLInventoryCategory> cat = new LLInventoryCategory(
item_id,
parent_id,
LLAssetType::AT_NONE,
std::string("Sample category"));
return cat;
}
namespace tut
{
struct inventory_data
{
};
typedef test_group<inventory_data> inventory_test;
typedef inventory_test::object inventory_object;
tut::inventory_test inv("llinventory");
//***class LLInventoryType***//
template<> template<>
void inventory_object::test<1>()
{
LLInventoryType::EType retType = LLInventoryType::lookup(std::string("sound"));
ensure("1.LLInventoryType::lookup(char*) failed", retType == LLInventoryType::IT_SOUND);
retType = LLInventoryType::lookup(std::string("snapshot"));
ensure("2.LLInventoryType::lookup(char*) failed", retType == LLInventoryType::IT_SNAPSHOT);
}
template<> template<>
void inventory_object::test<2>()
{
const char* retType = LLInventoryType::lookup(LLInventoryType::IT_CALLINGCARD);
ensure("1.LLInventoryType::lookup(EType) failed", 0 == strcmp(retType, "callcard"));
retType = LLInventoryType::lookup(LLInventoryType::IT_LANDMARK);
ensure("2.LLInventoryType::lookup(EType) failed", 0 == strcmp(retType, "landmark"));
}
template<> template<>
void inventory_object::test<3>()
{
static const char* retType = LLInventoryType::lookupHumanReadable(LLInventoryType::IT_CALLINGCARD);
ensure("1.LLInventoryType::lookupHumanReadable(EType) failed", 0 == strcmp(retType, "calling card"));
retType = LLInventoryType::lookupHumanReadable(LLInventoryType::IT_LANDMARK);
ensure("2.LLInventoryType::lookupHumanReadable(EType) failed", 0 == strcmp(retType, "landmark"));
}
template<> template<>
void inventory_object::test<4>()
{
static LLInventoryType::EType retType = LLInventoryType::defaultForAssetType(LLAssetType::AT_TEXTURE);
ensure("1.LLInventoryType::defaultForAssetType(LLAssetType EType) failed", retType == LLInventoryType::IT_TEXTURE);
retType = LLInventoryType::defaultForAssetType(LLAssetType::AT_LANDMARK);
ensure("2.LLInventoryType::defaultForAssetType(LLAssetType EType) failed", retType == LLInventoryType::IT_LANDMARK);
}
//*****class LLInventoryItem*****//
template<> template<>
void inventory_object::test<5>()
{
LLPointer<LLInventoryItem> src = create_random_inventory_item();
LLSD sd = ll_create_sd_from_inventory_item(src);
//llinfos << "sd: " << *sd << llendl;
LLPointer<LLInventoryItem> dst = ll_create_item_from_sd(sd);
ensure_equals("1.item id::getUUID() failed", dst->getUUID(), src->getUUID());
ensure_equals("2.parent::getParentUUID() failed", dst->getParentUUID(), src->getParentUUID());
ensure_equals("3.name::getName() failed", dst->getName(), src->getName());
ensure_equals("4.type::getType() failed", dst->getType(), src->getType());
ensure_equals("5.permissions::getPermissions() failed", dst->getPermissions(), src->getPermissions());
ensure_equals("6.description::getDescription() failed", dst->getDescription(), src->getDescription());
ensure_equals("7.sale type::getSaleType() failed", dst->getSaleInfo().getSaleType(), src->getSaleInfo().getSaleType());
ensure_equals("8.sale price::getSalePrice() failed", dst->getSaleInfo().getSalePrice(), src->getSaleInfo().getSalePrice());
ensure_equals("9.asset id::getAssetUUID() failed", dst->getAssetUUID(), src->getAssetUUID());
ensure_equals("10.inventory type::getInventoryType() failed", dst->getInventoryType(), src->getInventoryType());
ensure_equals("11.flags::getFlags() failed", dst->getFlags(), src->getFlags());
ensure_equals("12.creation::getCreationDate() failed", dst->getCreationDate(), src->getCreationDate());
LLUUID new_item_id, new_parent_id;
new_item_id.generate();
src->setUUID(new_item_id);
new_parent_id.generate();
src->setParent(new_parent_id);
std::string new_name = "LindenLab";
src->rename(new_name);
src->setType(LLAssetType::AT_SOUND);
LLUUID new_asset_id;
new_asset_id.generate();
src->setAssetUUID(new_asset_id);
std::string new_desc = "SecondLife Testing";
src->setDescription(new_desc);
S32 new_price = rand();
LLSaleInfo new_sale_info(LLSaleInfo::FS_COPY, new_price);
src->setSaleInfo(new_sale_info);
U32 new_flags = rand();
S32 new_creation = time(NULL);
LLPermissions new_perm;
LLUUID new_creator_id;
new_creator_id.generate();
LLUUID new_owner_id;
new_owner_id.generate();
LLUUID last_owner_id;
last_owner_id.generate();
LLUUID new_group_id;
new_group_id.generate();
new_perm.init(new_creator_id, new_owner_id, last_owner_id, new_group_id);
new_perm.initMasks(PERM_ALL, PERM_ALL, PERM_COPY, PERM_COPY, PERM_MODIFY | PERM_COPY);
src->setPermissions(new_perm);
src->setInventoryType(LLInventoryType::IT_SOUND);
src->setFlags(new_flags);
src->setCreationDate(new_creation);
sd = ll_create_sd_from_inventory_item(src);
//llinfos << "sd: " << *sd << llendl;
dst = ll_create_item_from_sd(sd);
ensure_equals("13.item id::getUUID() failed", dst->getUUID(), src->getUUID());
ensure_equals("14.parent::getParentUUID() failed", dst->getParentUUID(), src->getParentUUID());
ensure_equals("15.name::getName() failed", dst->getName(), src->getName());
ensure_equals("16.type::getType() failed", dst->getType(), src->getType());
ensure_equals("17.permissions::getPermissions() failed", dst->getPermissions(), src->getPermissions());
ensure_equals("18.description::getDescription() failed", dst->getDescription(), src->getDescription());
ensure_equals("19.sale type::getSaleType() failed type", dst->getSaleInfo().getSaleType(), src->getSaleInfo().getSaleType());
ensure_equals("20.sale price::getSalePrice() failed price", dst->getSaleInfo().getSalePrice(), src->getSaleInfo().getSalePrice());
ensure_equals("21.asset id::getAssetUUID() failed id", dst->getAssetUUID(), src->getAssetUUID());
ensure_equals("22.inventory type::getInventoryType() failed type", dst->getInventoryType(), src->getInventoryType());
ensure_equals("23.flags::getFlags() failed", dst->getFlags(), src->getFlags());
ensure_equals("24.creation::getCreationDate() failed", dst->getCreationDate(), src->getCreationDate());
}
template<> template<>
void inventory_object::test<6>()
{
LLPointer<LLInventoryItem> src = create_random_inventory_item();
LLUUID new_item_id, new_parent_id;
new_item_id.generate();
src->setUUID(new_item_id);
new_parent_id.generate();
src->setParent(new_parent_id);
std::string new_name = "LindenLab";
src->rename(new_name);
src->setType(LLAssetType::AT_SOUND);
LLUUID new_asset_id;
new_asset_id.generate();
src->setAssetUUID(new_asset_id);
std::string new_desc = "SecondLife Testing";
src->setDescription(new_desc);
S32 new_price = rand();
LLSaleInfo new_sale_info(LLSaleInfo::FS_COPY, new_price);
src->setSaleInfo(new_sale_info);
U32 new_flags = rand();
S32 new_creation = time(NULL);
LLPermissions new_perm;
LLUUID new_creator_id;
new_creator_id.generate();
LLUUID new_owner_id;
new_owner_id.generate();
LLUUID last_owner_id;
last_owner_id.generate();
LLUUID new_group_id;
new_group_id.generate();
new_perm.init(new_creator_id, new_owner_id, last_owner_id, new_group_id);
new_perm.initMasks(PERM_ALL, PERM_ALL, PERM_COPY, PERM_COPY, PERM_MODIFY | PERM_COPY);
src->setPermissions(new_perm);
src->setInventoryType(LLInventoryType::IT_SOUND);
src->setFlags(new_flags);
src->setCreationDate(new_creation);
LLSD sd = ll_create_sd_from_inventory_item(src);
LLPointer<LLInventoryItem> dst = ll_create_item_from_sd(sd);
LLPointer<LLInventoryItem> src1 = create_random_inventory_item();
src1->copyItem(src);
src1->cloneItem(src);
ensure_equals("1.item id::getUUID() failed", dst->getUUID(), src1->getUUID());
ensure_equals("2.parent::getParentUUID() failed", dst->getParentUUID(), src1->getParentUUID());
ensure_equals("3.name::getName() failed", dst->getName(), src1->getName());
ensure_equals("4.type::getType() failed", dst->getType(), src1->getType());
ensure_equals("5.permissions::getPermissions() failed", dst->getPermissions(), src1->getPermissions());
ensure_equals("6.description::getDescription() failed", dst->getDescription(), src1->getDescription());
ensure_equals("7.sale type::getSaleType() failed type", dst->getSaleInfo().getSaleType(), src1->getSaleInfo().getSaleType());
ensure_equals("8.sale price::getSalePrice() failed price", dst->getSaleInfo().getSalePrice(), src1->getSaleInfo().getSalePrice());
ensure_equals("9.asset id::getAssetUUID() failed id", dst->getAssetUUID(), src1->getAssetUUID());
ensure_equals("10.inventory type::getInventoryType() failed type", dst->getInventoryType(), src1->getInventoryType());
ensure_equals("11.flags::getFlags() failed", dst->getFlags(), src1->getFlags());
ensure_equals("12.creation::getCreationDate() failed", dst->getCreationDate(), src1->getCreationDate());
LLPointer<LLInventoryItem> src2;
src1->cloneItem(src2);
ensure_not_equals("13.item id::getUUID() failed", src1->getUUID(), src2->getUUID());
ensure_equals("14.parent::getParentUUID() failed", src2->getParentUUID(), src1->getParentUUID());
ensure_equals("15.name::getName() failed", src2->getName(), src1->getName());
ensure_equals("16.type::getType() failed", src2->getType(), src1->getType());
ensure_equals("17.permissions::getPermissions() failed", src2->getPermissions(), src1->getPermissions());
ensure_equals("18.description::getDescription() failed", src2->getDescription(), src1->getDescription());
ensure_equals("19.sale type::getSaleType() failed type", src2->getSaleInfo().getSaleType(), src1->getSaleInfo().getSaleType());
ensure_equals("20.sale price::getSalePrice() failed price", src2->getSaleInfo().getSalePrice(), src1->getSaleInfo().getSalePrice());
ensure_equals("21.asset id::getAssetUUID() failed id", src2->getAssetUUID(), src1->getAssetUUID());
ensure_equals("22.inventory type::getInventoryType() failed type", src2->getInventoryType(), src1->getInventoryType());
ensure_equals("23.flags::getFlags() failed", src2->getFlags(), src1->getFlags());
ensure_equals("24.creation::getCreationDate() failed", src2->getCreationDate(), src1->getCreationDate());
}
template<> template<>
void inventory_object::test<7>()
{
LLFILE* fp = LLFile::fopen("linden_file.dat","w+");
if(!fp)
{
llerrs << "file could not be opened\n" << llendl;
return;
}
LLPointer<LLInventoryItem> src1 = create_random_inventory_item();
src1->exportFile(fp, TRUE);
fclose(fp);
LLPointer<LLInventoryItem> src2 = new LLInventoryItem();
fp = LLFile::fopen("linden_file.dat","r+");
if(!fp)
{
llerrs << "file could not be opened\n" << llendl;
return;
}
src2->importFile(fp);
fclose(fp);
ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID());
ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID());
ensure_equals("3.permissions::getPermissions() failed", src1->getPermissions(), src2->getPermissions());
ensure_equals("4.sale price::getSalePrice() failed price", src1->getSaleInfo().getSalePrice(), src2->getSaleInfo().getSalePrice());
ensure_equals("5.asset id::getAssetUUID() failed id", src1->getAssetUUID(), src2->getAssetUUID());
ensure_equals("6.type::getType() failed", src1->getType(), src2->getType());
ensure_equals("7.inventory type::getInventoryType() failed type", src1->getInventoryType(), src2->getInventoryType());
ensure_equals("8.name::getName() failed", src1->getName(), src2->getName());
ensure_equals("9.description::getDescription() failed", src1->getDescription(), src2->getDescription());
ensure_equals("10.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate());
}
template<> template<>
void inventory_object::test<8>()
{
LLPointer<LLInventoryItem> src1 = create_random_inventory_item();
std::ostringstream ostream;
src1->exportLegacyStream(ostream, TRUE);
std::istringstream istream(ostream.str());
LLPointer<LLInventoryItem> src2 = new LLInventoryItem();
src2->importLegacyStream(istream);
ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID());
ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID());
ensure_equals("3.permissions::getPermissions() failed", src1->getPermissions(), src2->getPermissions());
ensure_equals("4.sale price::getSalePrice() failed price", src1->getSaleInfo().getSalePrice(), src2->getSaleInfo().getSalePrice());
ensure_equals("5.asset id::getAssetUUID() failed id", src1->getAssetUUID(), src2->getAssetUUID());
ensure_equals("6.type::getType() failed", src1->getType(), src2->getType());
ensure_equals("7.inventory type::getInventoryType() failed type", src1->getInventoryType(), src2->getInventoryType());
ensure_equals("8.name::getName() failed", src1->getName(), src2->getName());
ensure_equals("9.description::getDescription() failed", src1->getDescription(), src2->getDescription());
ensure_equals("10.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate());
}
template<> template<>
void inventory_object::test<9>()
{
// exportFileXML seg-faults for some reason. LLXMLNode is teh suck.
#if 0
LLPointer<LLInventoryItem> src1 = create_random_inventory_item();
LLXMLNode* x_node = src1->exportFileXML(TRUE);
LLPointer<LLInventoryItem> src2 = new LLInventoryItem();
src2->importXML(x_node);
ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID());
ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID());
ensure_equals("3.permissions::getPermissions() failed", src1->getPermissions(), src2->getPermissions());
ensure_equals("4.sale price::getSalePrice() failed price", src1->getSaleInfo().getSalePrice(), src2->getSaleInfo().getSalePrice());
ensure_equals("5.asset id::getAssetUUID() failed id", src1->getAssetUUID(), src2->getAssetUUID());
ensure_equals("6.type::getType() failed", src1->getType(), src2->getType());
ensure_equals("7.inventory type::getInventoryType() failed type", src1->getInventoryType(), src2->getInventoryType());
ensure_equals("8.name::getName() failed", src1->getName(), src2->getName());
ensure_equals("9.description::getDescription() failed", src1->getDescription(), src2->getDescription());
ensure_equals("10.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate());
#endif
}
template<> template<>
void inventory_object::test<10>()
{
LLPointer<LLInventoryItem> src1 = create_random_inventory_item();
U8* bin_bucket = new U8[300];
S32 bin_bucket_size = src1->packBinaryBucket(bin_bucket, NULL);
LLPointer<LLInventoryItem> src2 = new LLInventoryItem();
src2->unpackBinaryBucket(bin_bucket, bin_bucket_size);
ensure_equals("1.sale price::getSalePrice() failed price", src1->getSaleInfo().getSalePrice(), src2->getSaleInfo().getSalePrice());
ensure_equals("2.sale type::getSaleType() failed type", src1->getSaleInfo().getSaleType(), src2->getSaleInfo().getSaleType());
ensure_equals("3.type::getType() failed", src1->getType(), src2->getType());
ensure_equals("4.inventory type::getInventoryType() failed type", src1->getInventoryType(), src2->getInventoryType());
ensure_equals("5.name::getName() failed", src1->getName(), src2->getName());
ensure_equals("6.description::getDescription() failed", src1->getDescription(), src2->getDescription());
ensure_equals("7.flags::getFlags() failed", src1->getFlags(), src2->getFlags());
}
template<> template<>
void inventory_object::test<11>()
{
LLPointer<LLInventoryItem> src1 = create_random_inventory_item();
LLSD retSd = src1->asLLSD();
LLPointer<LLInventoryItem> src2 = new LLInventoryItem();
src2->fromLLSD(retSd);
ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID());
ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID());
ensure_equals("3.permissions::getPermissions() failed", src1->getPermissions(), src2->getPermissions());
ensure_equals("4.asset id::getAssetUUID() failed id", src1->getAssetUUID(), src2->getAssetUUID());
ensure_equals("5.type::getType() failed", src1->getType(), src2->getType());
ensure_equals("6.inventory type::getInventoryType() failed type", src1->getInventoryType(), src2->getInventoryType());
ensure_equals("7.flags::getFlags() failed", src1->getFlags(), src2->getFlags());
ensure_equals("8.sale type::getSaleType() failed type", src1->getSaleInfo().getSaleType(), src2->getSaleInfo().getSaleType());
ensure_equals("9.sale price::getSalePrice() failed price", src1->getSaleInfo().getSalePrice(), src2->getSaleInfo().getSalePrice());
ensure_equals("10.name::getName() failed", src1->getName(), src2->getName());
ensure_equals("11.description::getDescription() failed", src1->getDescription(), src2->getDescription());
ensure_equals("12.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate());
}
//******class LLInventoryCategory*******//
template<> template<>
void inventory_object::test<12>()
{
LLPointer<LLInventoryCategory> src = create_random_inventory_cat();
LLSD sd = ll_create_sd_from_inventory_category(src);
LLPointer<LLInventoryCategory> dst = ll_create_category_from_sd(sd);
ensure_equals("1.item id::getUUID() failed", dst->getUUID(), src->getUUID());
ensure_equals("2.parent::getParentUUID() failed", dst->getParentUUID(), src->getParentUUID());
ensure_equals("3.name::getName() failed", dst->getName(), src->getName());
ensure_equals("4.type::getType() failed", dst->getType(), src->getType());
ensure_equals("5.preferred type::getPreferredType() failed", dst->getPreferredType(), src->getPreferredType());
src->setPreferredType( LLAssetType::AT_TEXTURE);
sd = ll_create_sd_from_inventory_category(src);
dst = ll_create_category_from_sd(sd);
ensure_equals("6.preferred type::getPreferredType() failed", dst->getPreferredType(), src->getPreferredType());
}
template<> template<>
void inventory_object::test<13>()
{
LLFILE* fp = LLFile::fopen("linden_file.dat","w");
if(!fp)
{
llerrs << "file coudnt be opened\n" << llendl;
return;
}
LLPointer<LLInventoryCategory> src1 = create_random_inventory_cat();
src1->exportFile(fp, TRUE);
fclose(fp);
LLPointer<LLInventoryCategory> src2 = new LLInventoryCategory();
fp = LLFile::fopen("linden_file.dat","r");
if(!fp)
{
llerrs << "file coudnt be opened\n" << llendl;
return;
}
src2->importFile(fp);
fclose(fp);
ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID());
ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID());
ensure_equals("3.type::getType() failed", src1->getType(), src2->getType());
ensure_equals("4.preferred type::getPreferredType() failed", src1->getPreferredType(), src2->getPreferredType());
ensure_equals("5.name::getName() failed", src1->getName(), src2->getName());
}
template<> template<>
void inventory_object::test<14>()
{
LLPointer<LLInventoryCategory> src1 = create_random_inventory_cat();
std::ostringstream ostream;
src1->exportLegacyStream(ostream, TRUE);
std::istringstream istream(ostream.str());
LLPointer<LLInventoryCategory> src2 = new LLInventoryCategory();
src2->importLegacyStream(istream);
ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID());
ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID());
ensure_equals("3.type::getType() failed", src1->getType(), src2->getType());
ensure_equals("4.preferred type::getPreferredType() failed", src1->getPreferredType(), src2->getPreferredType());
ensure_equals("5.name::getName() failed", src1->getName(), src2->getName());
}
}

1604
indra/test/io.cpp Normal file

File diff suppressed because one or more lines are too long

171
indra/test/llapp_tut.cpp Normal file
View File

@@ -0,0 +1,171 @@
/**
* @file llapp_tut.cpp
* @author Phoenix
* @date 2006-09-12
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "llapp.h"
#include "lltut.h"
namespace tut
{
struct application
{
class LLTestApp : public LLApp
{
public:
virtual bool init() { return true; }
virtual bool cleanup() { return true; }
virtual bool mainLoop() { return true; }
};
LLTestApp* mApp;
application()
{
mApp = new LLTestApp;
}
~application()
{
delete mApp;
}
};
typedef test_group<application> application_t;
typedef application_t::object application_object_t;
tut::application_t tut_application("application");
template<> template<>
void application_object_t::test<1>()
{
LLSD defaults;
defaults["template"] = "../../../scripts/messages/message_template.msg";
defaults["configdir"] = ".";
defaults["db_host"] = "mysql.shakti.lindenlab.com";
defaults["db_user"] = "linden";
defaults["db_password"] = "gomez";
defaults["datadir"] = "data";
mApp->setOptionData(LLApp::PRIORITY_DEFAULT, defaults);
LLSD db_user_sd = mApp->getOption("db_user");
ensure_equals("data type", db_user_sd.type(), LLSD::TypeString);
ensure_equals(
"data value", db_user_sd.asString(), std::string("linden"));
}
template<> template<>
void application_object_t::test<2>()
{
const int ARGC = 13;
char* ARGV[ARGC] =
{
"", // argv[0] is usually the application name
"-crashcount",
"2",
"-space",
"spaceserver.grid.lindenlab.com",
"-db_host",
"localhost",
"--allowlslhttprequests",
"-asset-uri",
"http://asset.grid.lindenlab.com/assets",
"-data",
"127.0.0.1",
"--smtp"
};
bool ok = mApp->parseCommandOptions(ARGC, ARGV);
ensure("command line parsed", ok);
ensure_equals(
"crashcount", mApp->getOption("crashcount").asInteger(), 2);
ensure_equals(
"space",
mApp->getOption("space").asString(),
std::string("spaceserver.grid.lindenlab.com"));
ensure_equals(
"db_host",
mApp->getOption("db_host").asString(),
std::string("localhost"));
ensure("allowlshlttprequests", mApp->getOption("smtp"));
ensure_equals(
"asset-uri",
mApp->getOption("asset-uri").asString(),
std::string("http://asset.grid.lindenlab.com/assets"));
ensure_equals(
"data",
mApp->getOption("data").asString(),
std::string("127.0.0.1"));
ensure("smtp", mApp->getOption("smtp"));
}
template<> template<>
void application_object_t::test<3>()
{
const int ARGC = 4;
char* ARGV[ARGC] =
{
"", // argv[0] is usually the application name
"crashcount",
"2",
"--space"
};
bool ok = mApp->parseCommandOptions(ARGC, ARGV);
ensure("command line parse failure", !ok);
}
template<> template<>
void application_object_t::test<4>()
{
const int ARGC = 4;
char* ARGV[ARGC] =
{
"", // argv[0] is usually the application name
"--crashcount",
"2",
"space"
};
bool ok = mApp->parseCommandOptions(ARGC, ARGV);
ensure("command line parse failure", !ok);
}
template<> template<>
void application_object_t::test<5>()
{
LLSD options;
options["boolean-test"] = true;
mApp->setOptionData(LLApp::PRIORITY_GENERAL_CONFIGURATION, options);
ensure("bool set", mApp->getOption("boolean-test").asBoolean());
options["boolean-test"] = false;
mApp->setOptionData(LLApp::PRIORITY_RUNTIME_OVERRIDE, options);
ensure("bool unset", !mApp->getOption("boolean-test").asBoolean());
}
}

View File

@@ -0,0 +1,201 @@
/**
* @file asset_upload_queue_tut.cpp
* @brief Tests for newview/llassetuploadqueue.cpp
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "lltut.h"
#include "mock_http_client.h"
#include "../newview/llassetuploadqueue.cpp"
// Mock implementation.
LLAssetUploadResponder::LLAssetUploadResponder(const LLSD& post_data,
const LLUUID& vfile_id,
LLAssetType::EType asset_type)
{
}
LLAssetUploadResponder::LLAssetUploadResponder(const LLSD& post_data, const std::string& file_name)
{
}
LLAssetUploadResponder::~LLAssetUploadResponder()
{
}
void LLAssetUploadResponder::error(U32 statusNum, const std::string& reason)
{
}
void LLAssetUploadResponder::result(const LLSD& content)
{
}
void LLAssetUploadResponder::uploadUpload(const LLSD& content)
{
}
void LLAssetUploadResponder::uploadComplete(const LLSD& content)
{
}
void LLAssetUploadResponder::uploadFailure(const LLSD& content)
{
}
LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_data,
const LLUUID& vfile_id,
LLAssetType::EType asset_type) :
LLAssetUploadResponder(post_data, vfile_id, asset_type)
{
}
LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_data,
const std::string& file_name) :
LLAssetUploadResponder(post_data, file_name)
{
}
LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_data,
const std::string& file_name,
const LLUUID& queue_id) :
LLAssetUploadResponder(post_data, file_name)
{
}
void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content)
{
}
namespace tut
{
class asset_upload_queue_test_data : public MockHttpClient {};
typedef test_group<asset_upload_queue_test_data> asset_upload_queue_test;
typedef asset_upload_queue_test::object asset_upload_queue_object;
tut::asset_upload_queue_test asset_upload_queue("asset_upload_queue");
void queue(LLAssetUploadQueue& q, const std::string& filename)
{
LLUUID task_id;
LLUUID item_id;
BOOL is_running = FALSE;
BOOL is_target_mono = TRUE;
LLUUID queue_id;
q.queue(filename, task_id, item_id, is_running, is_target_mono, queue_id);
}
class LLTestSupplier : public LLAssetUploadQueueSupplier
{
public:
void set(LLAssetUploadQueue* queue) {mQueue = queue;}
virtual LLAssetUploadQueue* get() const
{
return mQueue;
}
private:
LLAssetUploadQueue* mQueue;
};
template<> template<>
void asset_upload_queue_object::test<1>()
{
setupTheServer();
reset();
LLTestSupplier* supplier = new LLTestSupplier();
LLAssetUploadQueue q("http://localhost:8888/test/success", supplier);
supplier->set(&q);
queue(q, "foo.bar");
ensure("upload queue not empty before request", q.isEmpty());
runThePump(10);
ensure("upload queue not empty after request", q.isEmpty());
}
template<> template<>
void asset_upload_queue_object::test<2>()
{
reset();
LLTestSupplier* supplier = new LLTestSupplier();
LLAssetUploadQueue q("http://localhost:8888/test/error", supplier);
supplier->set(&q);
queue(q, "foo.bar");
ensure("upload queue not empty before request", q.isEmpty());
runThePump(10);
ensure("upload queue not empty after request", q.isEmpty());
}
template<> template<>
void asset_upload_queue_object::test<3>()
{
reset();
LLTestSupplier* supplier = new LLTestSupplier();
LLAssetUploadQueue q("http://localhost:8888/test/timeout", supplier);
supplier->set(&q);
queue(q, "foo.bar");
ensure("upload queue not empty before request", q.isEmpty());
runThePump(10);
ensure("upload queue not empty after request", q.isEmpty());
}
template<> template<>
void asset_upload_queue_object::test<4>()
{
reset();
LLTestSupplier* supplier = new LLTestSupplier();
LLAssetUploadQueue q("http://localhost:8888/test/success", supplier);
supplier->set(&q);
queue(q, "foo.bar");
queue(q, "baz.bar");
ensure("upload queue empty before request", !q.isEmpty());
runThePump(10);
ensure("upload queue not empty before request", q.isEmpty());
runThePump(10);
ensure("upload queue not empty after request", q.isEmpty());
}
template<> template<>
void asset_upload_queue_object::test<5>()
{
reset();
LLTestSupplier* supplier = new LLTestSupplier();
LLAssetUploadQueue q("http://localhost:8888/test/success", supplier);
supplier->set(&q);
queue(q, "foo.bar");
runThePump(10);
ensure("upload queue not empty before request", q.isEmpty());
queue(q, "baz.bar");
ensure("upload queue not empty after request", q.isEmpty());
runThePump(10);
killServer();
}
}

View File

@@ -0,0 +1,82 @@
/**
* @file llbase64_tut.cpp
* @author James Cook
* @date 2007-02-04
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "lltut.h"
#include "llbase64.h"
#include <string>
#include "lluuid.h"
namespace tut
{
struct base64_data
{
};
typedef test_group<base64_data> base64_test;
typedef base64_test::object base64_object;
tut::base64_test base64("base64");
template<> template<>
void base64_object::test<1>()
{
std::string result;
result = LLBase64::encode(NULL, 0);
ensure("encode nothing", (result == "") );
LLUUID nothing;
result = LLBase64::encode(&nothing.mData[0], UUID_BYTES);
ensure("encode blank uuid",
(result == "AAAAAAAAAAAAAAAAAAAAAA==") );
LLUUID id("526a1e07-a19d-baed-84c4-ff08a488d15e");
result = LLBase64::encode(&id.mData[0], UUID_BYTES);
ensure("encode random uuid",
(result == "UmoeB6Gduu2ExP8IpIjRXg==") );
}
template<> template<>
void base64_object::test<2>()
{
std::string result;
U8 blob[40] = { 115, 223, 172, 255, 140, 70, 49, 125, 236, 155, 45, 199, 101, 17, 164, 131, 230, 19, 80, 64, 112, 53, 135, 98, 237, 12, 26, 72, 126, 14, 145, 143, 118, 196, 11, 177, 132, 169, 195, 134 };
result = LLBase64::encode(&blob[0], 40);
ensure("encode 40 bytes",
(result == "c9+s/4xGMX3smy3HZRGkg+YTUEBwNYdi7QwaSH4OkY92xAuxhKnDhg==") );
}
}

View File

@@ -0,0 +1,124 @@
/**
* @file llbitpack_tut.cpp
* @author Adroit
* @date 2007-02
* @brief llstreamtools test cases.
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "bitpack.h"
#include "lltut.h"
namespace tut
{
struct bit_pack
{
};
typedef test_group<bit_pack> bit_pack_t;
typedef bit_pack_t::object bit_pack_object_t;
tut::bit_pack_t tut_bit_pack("bitpack");
// pack -> unpack
template<> template<>
void bit_pack_object_t::test<1>()
{
U8 packbuffer[255];
U8 unpackbuffer[255];
int pack_bufsize = 0;
int unpack_bufsize = 0;
LLBitPack bitpack(packbuffer, 255);
char str[] = "SecondLife is a 3D virtual world";
int len = sizeof(str);
pack_bufsize = bitpack.bitPack((U8*) str, len*8);
pack_bufsize = bitpack.flushBitPack();
LLBitPack bitunpack(packbuffer, pack_bufsize*8);
unpack_bufsize = bitunpack.bitUnpack(unpackbuffer, len*8);
ensure("bitPack: unpack size should be same as string size prior to pack", len == unpack_bufsize);
ensure_memory_matches("str->bitPack->bitUnpack should be equal to string", str, len, unpackbuffer, unpack_bufsize);
}
// pack large, unpack in individual bytes
template<> template<>
void bit_pack_object_t::test<2>()
{
U8 packbuffer[255];
U8 unpackbuffer[255];
int pack_bufsize = 0;
int unpack_bufsize = 0;
LLBitPack bitpack(packbuffer, 255);
char str[] = "SecondLife";
int len = sizeof(str);
pack_bufsize = bitpack.bitPack((U8*) str, len*8);
pack_bufsize = bitpack.flushBitPack();
LLBitPack bitunpack(packbuffer, pack_bufsize*8);
unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8);
ensure("bitPack: individual unpack: 0", unpackbuffer[0] == (U8) str[0]);
unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8);
ensure("bitPack: individual unpack: 1", unpackbuffer[0] == (U8) str[1]);
unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8);
ensure("bitPack: individual unpack: 2", unpackbuffer[0] == (U8) str[2]);
unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8);
ensure("bitPack: individual unpack: 3", unpackbuffer[0] == (U8) str[3]);
unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8);
ensure("bitPack: individual unpack: 4", unpackbuffer[0] == (U8) str[4]);
unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8);
ensure("bitPack: individual unpack: 5", unpackbuffer[0] == (U8) str[5]);
unpack_bufsize = bitunpack.bitUnpack(unpackbuffer, 8*4); // Life
ensure_memory_matches("bitPack: 4 bytes unpack:", unpackbuffer, 4, str+6, 4);
}
// U32 packing
template<> template<>
void bit_pack_object_t::test<3>()
{
U8 packbuffer[255];
int pack_bufsize = 0;
LLBitPack bitpack(packbuffer, 255);
U32 num = 0x41fab67a;
pack_bufsize = bitpack.bitPack((U8*)&num, 8*sizeof(U32));
pack_bufsize = bitpack.flushBitPack();
LLBitPack bitunpack(packbuffer, pack_bufsize*8);
U32 res = 0;
// since packing and unpacking is done on same machine in the unit test run,
// endianness should not matter
bitunpack.bitUnpack((U8*) &res, sizeof(res)*8);
ensure("U32->bitPack->bitUnpack->U32 should be equal", num == res);
}
}

View File

@@ -0,0 +1,147 @@
/**
* @file llblowfish_tut.cpp
* @author James Cook, james@lindenlab.com
* @date 2007-02-04
*
* Data files generated with:
* openssl enc -bf-cbc -in blowfish.digits.txt -out blowfish.1.bin -K 00000000000000000000000000000000 -iv 0000000000000000 -p
* openssl enc -bf-cbc -in blowfish.digits.txt -out blowfish.2.bin -K 526a1e07a19dbaed84c4ff08a488d15e -iv 0000000000000000 -p
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "lltut.h"
#include "llblowfishcipher.h"
#include "lluuid.h"
namespace tut
{
class LLData
{
public:
unsigned char* mInput;
int mInputSize;
LLData()
{
// \n to make it easier to create text files
// for testing with command line openssl
mInput = (unsigned char*)"01234567890123456789012345678901234\n";
mInputSize = 36;
}
bool matchFile(const std::string& filename,
const std::string& data)
{
LLFILE* fp = LLFile::fopen(filename, "rb");
if (!fp)
{
// sometimes test is run inside the indra directory
std::string path = "test/";
path += filename;
fp = LLFile::fopen(path, "rb");
}
if (!fp)
{
llwarns << "unabled to open " << filename << llendl;
return false;
}
std::string good;
good.resize(256);
size_t got = fread(&good[0], 1, 256, fp);
lldebugs << "matchFile read " << got << llendl;
fclose(fp);
good.resize(got);
return (good == data);
}
};
typedef test_group<LLData> blowfish_test;
typedef blowfish_test::object blowfish_object;
// Create test with name that can be selected on
// command line of test app.
tut::blowfish_test blowfish("blowfish");
template<> template<>
void blowfish_object::test<1>()
{
LLUUID blank;
LLBlowfishCipher cipher(&blank.mData[0], UUID_BYTES);
U32 dst_len = cipher.requiredEncryptionSpace(36);
ensure("encryption space 36",
(dst_len == 40) );
// Blowfish adds an additional 8-byte block if your
// input is an exact multiple of 8
dst_len = cipher.requiredEncryptionSpace(8);
ensure("encryption space 8",
(dst_len == 16) );
}
template<> template<>
void blowfish_object::test<2>()
{
LLUUID blank;
LLBlowfishCipher cipher(&blank.mData[0], UUID_BYTES);
std::string result;
result.resize(256);
U32 count = cipher.encrypt(mInput, mInputSize,
(U8*) &result[0], 256);
ensure("encrypt output count",
(count == 40) );
result.resize(count);
ensure("encrypt null key", matchFile("blowfish.1.bin", result));
}
template<> template<>
void blowfish_object::test<3>()
{
// same as base64 test id
LLUUID id("526a1e07-a19d-baed-84c4-ff08a488d15e");
LLBlowfishCipher cipher(&id.mData[0], UUID_BYTES);
std::string result;
result.resize(256);
U32 count = cipher.encrypt(mInput, mInputSize,
(U8*) &result[0], 256);
ensure("encrypt output count",
(count == 40) );
result.resize(count);
ensure("encrypt real key", matchFile("blowfish.2.bin", result));
}
}

277
indra/test/llbuffer_tut.cpp Normal file
View File

@@ -0,0 +1,277 @@
/**
* @file llbuffer_tut.cpp
* @author Adroit
* @date 2007-03
* @brief llbuffer test cases.
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "lltut.h"
#include "llbuffer.h"
#include "llerror.h"
#include "llmemtype.h"
namespace tut
{
struct buffer
{
};
typedef test_group<buffer> buffer_t;
typedef buffer_t::object buffer_object_t;
tut::buffer_t tut_buffer("buffer");
template<> template<>
void buffer_object_t::test<1>()
{
LLChannelDescriptors channelDescriptors;
ensure("in() and out() functions Failed", (0 == channelDescriptors.in() && 1 == channelDescriptors.out()));
S32 val = 50;
LLChannelDescriptors channelDescriptors1(val);
ensure("LLChannelDescriptors in() and out() functions Failed", (50 == channelDescriptors1.in() && 51 == channelDescriptors1.out()));
}
template<> template<>
void buffer_object_t::test<2>()
{
LLSegment segment;
ensure("LLSegment get functions failed", (0 == segment.getChannel() && NULL == segment.data() && 0 == segment.size()));
segment.setChannel(50);
ensure_equals("LLSegment setChannel() function failed", segment.getChannel(), 50);
ensure("LLSegment isOnChannel() function failed", (TRUE == segment.isOnChannel(50)));
}
template<> template<>
void buffer_object_t::test<3>()
{
S32 channel = 30;
const char str[] = "SecondLife";
S32 len = sizeof(str);
LLSegment segment(channel, (U8*)str, len);
ensure("LLSegment get functions failed", (30 == segment.getChannel() && len == segment.size() && (U8*)str == segment.data()));
ensure_memory_matches("LLSegment::data() failed", segment.data(), segment.size(), (U8*)str, len);
ensure("LLSegment isOnChannel() function failed", (TRUE == segment.isOnChannel(channel)));
}
template<> template<>
void buffer_object_t::test<4>()
{
S32 channel = 50;
S32 bigSize = 16384*2;
char str[] = "SecondLife";
S32 smallSize = sizeof(str);
LLSegment segment;
LLHeapBuffer buf; // use default size of DEFAULT_HEAP_BUFFER_SIZE = 16384
S32 requestSize;
requestSize = 16384-1;
ensure("1. LLHeapBuffer createSegment failed", (TRUE == buf.createSegment(channel, requestSize, segment)) && segment.size() == requestSize);
// second request for remainign 1 byte
requestSize = 1;
ensure("2. LLHeapBuffer createSegment failed", (TRUE == buf.createSegment(channel, requestSize, segment)) && segment.size() == requestSize);
// it should fail now.
requestSize = 1;
ensure("3. LLHeapBuffer createSegment failed", (FALSE == buf.createSegment(channel, requestSize, segment)));
LLHeapBuffer buf1(bigSize);
// requst for more than default size but less than total sizeit should fail now.
requestSize = 16384 + 1;
ensure("4. LLHeapBuffer createSegment failed", (TRUE == buf1.createSegment(channel, requestSize, segment)) && segment.size() == requestSize);
LLHeapBuffer buf2((U8*) str, smallSize);
requestSize = smallSize;
ensure("5. LLHeapBuffer createSegment failed", (TRUE == buf2.createSegment(channel, requestSize, segment)) && segment.size() == requestSize && memcmp(segment.data(), (U8*) str, requestSize) == 0);
requestSize = smallSize+1;
ensure("6. LLHeapBuffer createSegment failed", (FALSE == buf2.createSegment(channel, requestSize, segment)));
}
//makeChannelConsumer()
template<> template<>
void buffer_object_t::test<5>()
{
LLChannelDescriptors inchannelDescriptors(20);
LLChannelDescriptors outchannelDescriptors = LLBufferArray::makeChannelConsumer(inchannelDescriptors);
ensure("LLBufferArray::makeChannelConsumer() function Failed", (21 == outchannelDescriptors.in()));
}
template<> template<>
void buffer_object_t::test<6>()
{
LLBufferArray bufferArray;
const char array[] = "SecondLife";
S32 len = strlen(array);
LLChannelDescriptors channelDescriptors = bufferArray.nextChannel();
bufferArray.append(channelDescriptors.in(), (U8*)array, len);
S32 count = bufferArray.countAfter(channelDescriptors.in(), NULL);
ensure_equals("Appended size is:", count, len);
}
//append() and prepend()
template<> template<>
void buffer_object_t::test<7>()
{
LLBufferArray bufferArray;
const char array[] = "SecondLife";
S32 len = strlen(array);
const char array1[] = "LindenLabs";
S32 len1 = strlen(array1);
std::string str(array1);
str.append(array);
LLChannelDescriptors channelDescriptors = bufferArray.nextChannel();
bufferArray.append(channelDescriptors.in(), (U8*)array, len);
bufferArray.prepend(channelDescriptors.in(), (U8*)array1, len1);
char buf[100];
S32 len2 = 20;
bufferArray.readAfter(channelDescriptors.in(), NULL, (U8*)buf, len2);
ensure_equals("readAfter length failed", len2, 20);
buf[len2] = '\0';
ensure_equals("readAfter/prepend/append failed", buf, str);
}
//append()
template<> template<>
void buffer_object_t::test<8>()
{
LLBufferArray bufferArray;
const char array[] = "SecondLife";
S32 len = strlen(array);
const char array1[] = "LindenLabs";
S32 len1 = strlen(array1);
std::string str(array);
str.append(array1);
LLChannelDescriptors channelDescriptors = bufferArray.nextChannel();
bufferArray.append(channelDescriptors.in(), (U8*)array, len);
bufferArray.append(channelDescriptors.in(), (U8*)array1, len1);
char buf[100];
S32 len2 = 20;
bufferArray.readAfter(channelDescriptors.in(), NULL, (U8*)buf, len2);
ensure_equals("readAfter length failed", len2, 20);
buf[len2] = '\0';
ensure_equals("readAfter/append/append failed", buf, str);
}
template<> template<>
void buffer_object_t::test<9>()
{
LLBufferArray bufferArray;
const char array[] = "SecondLife";
S32 len = strlen(array) + 1;
std::string str(array);
LLChannelDescriptors channelDescriptors = bufferArray.nextChannel();
bufferArray.append(channelDescriptors.in(), (U8*)array, len);
LLBufferArray bufferArray1;
ensure("Contents are not copied and the source buffer is not empty", (1 == bufferArray1.takeContents(bufferArray)));
char buf[100];
S32 len2 = len;
bufferArray1.readAfter(channelDescriptors.in(), NULL, (U8*)buf, len2);
ensure_equals("takeContents failed to copy", buf, str);
}
//seek()
template<> template<>
void buffer_object_t::test<10>()
{
const char array[] = "SecondLife is a Virtual World";
S32 len = strlen(array);
LLBufferArray bufferArray;
bufferArray.append(0, (U8*)array, len);
char buf[255];
S32 len1 = 16;
U8* last = bufferArray.readAfter(0, 0, (U8*)buf, len1);
buf[len1] = '\0';
last = bufferArray.seek(0, last, -2);
len1 = 15;
last = bufferArray.readAfter(0, last, (U8*)buf, len1);
buf[len1] = '\0';
std::string str(buf);
ensure_equals("Seek does'nt worked", str, std::string("a Virtual World"));
}
template<> template<>
void buffer_object_t::test<11>()
{
const char array[] = "SecondLife is a Virtual World";
S32 len = strlen(array);
LLBufferArray bufferArray;
bufferArray.append(0, (U8*)array, len);
char buf[255];
S32 len1 = 10;
U8* last = bufferArray.readAfter(0, 0, (U8*)buf, len1);
bufferArray.splitAfter(last);
LLBufferArray::segment_iterator_t iterator = bufferArray.beginSegment();
++iterator;
std::string str(((char*)(*iterator).data()), (*iterator).size());
ensure_equals("Strings are not equal;splitAfter() operation failed", str, std::string(" is a Virtual World"));
}
//makeSegment()->eraseSegment()
template<> template<>
void buffer_object_t::test<12>()
{
LLBufferArray bufferArray;
LLChannelDescriptors channelDescriptors;
LLBufferArray::segment_iterator_t it;
S32 length = 1000;
it = bufferArray.makeSegment(channelDescriptors.out(), length);
ensure("makeSegment() function failed", (it != bufferArray.endSegment()));
ensure("eraseSegment() function failed", bufferArray.eraseSegment(it));
ensure("eraseSegment() begin/end should now be same", bufferArray.beginSegment() == bufferArray.endSegment());
}
// constructSegmentAfter()
template<> template<>
void buffer_object_t::test<13>()
{
LLBufferArray bufferArray;
LLBufferArray::segment_iterator_t it;
LLSegment segment;
LLBufferArray::segment_iterator_t end = bufferArray.endSegment();
it = bufferArray.constructSegmentAfter(NULL, segment);
ensure("constructSegmentAfter() function failed", (it == end));
}
}

View File

@@ -0,0 +1,148 @@
/**
* @file llcontrol_tut.cpp
* @date February 2008
* @brief control group unit tests
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
* Copyright (c) 2008-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include <tut/tut.hpp>
#include "lltut.h"
#include "llcontrol.h"
#include "llsdserialize.h"
namespace tut
{
struct control_group
{
LLControlGroup* mCG;
std::string mTestConfigDir;
std::string mTestConfigFile;
static bool mListenerFired;
control_group()
{
mCG = new LLControlGroup;
LLUUID random;
random.generate();
// generate temp dir
std::ostringstream oStr;
oStr << "/tmp/llcontrol-test-" << random << "/";
mTestConfigDir = oStr.str();
mTestConfigFile = mTestConfigDir + "settings.xml";
LLFile::mkdir(mTestConfigDir);
LLSD config;
config["TestSetting"]["Comment"] = "Dummy setting used for testing";
config["TestSetting"]["Persist"] = 1;
config["TestSetting"]["Type"] = "U32";
config["TestSetting"]["Value"] = 12;
writeSettingsFile(config);
}
~control_group()
{
//Remove test files
delete mCG;
}
void writeSettingsFile(const LLSD& config)
{
llofstream file(mTestConfigFile);
if (file.is_open())
{
LLSDSerialize::toPrettyXML(config, file);
}
file.close();
}
static bool handleListenerTest(const LLSD& newvalue)
{
control_group::mListenerFired = true;
return true;
}
};
bool control_group::mListenerFired = false;
typedef test_group<control_group> control_group_test;
typedef control_group_test::object control_group_t;
control_group_test tut_control_group("control_group");
//load settings from files - LLSD
template<> template<>
void control_group_t::test<1>()
{
int results = mCG->loadFromFile(mTestConfigFile.c_str());
ensure("number of settings", (results == 1));
ensure("value of setting", (mCG->getU32("TestSetting") == 12));
}
//save settings to files
template<> template<>
void control_group_t::test<2>()
{
int results = mCG->loadFromFile(mTestConfigFile.c_str());
mCG->setU32("TestSetting", 13);
ensure_equals("value of changed setting", mCG->getU32("TestSetting"), 13);
LLControlGroup test_cg;
std::string temp_test_file = (mTestConfigDir + "setting_llsd_temp.xml");
mCG->saveToFile(temp_test_file.c_str(), TRUE);
results = test_cg.loadFromFile(temp_test_file.c_str());
ensure("number of changed settings loaded", (results == 1));
ensure("value of changed settings loaded", (test_cg.getU32("TestSetting") == 13));
}
//priorities
template<> template<>
void control_group_t::test<3>()
{
int results = mCG->loadFromFile(mTestConfigFile.c_str());
LLControlVariable* control = mCG->getControl("TestSetting");
LLSD new_value = 13;
control->setValue(new_value, FALSE);
ensure_equals("value of changed setting", mCG->getU32("TestSetting"), 13);
LLControlGroup test_cg;
std::string temp_test_file = (mTestConfigDir + "setting_llsd_persist_temp.xml");
mCG->saveToFile(temp_test_file.c_str(), TRUE);
results = test_cg.loadFromFile(temp_test_file.c_str());
//If we haven't changed any settings, then we shouldn't have any settings to load
ensure("number of non-persisted changed settings loaded", (results == 0));
}
//listeners
template<> template<>
void control_group_t::test<4>()
{
int results = mCG->loadFromFile(mTestConfigFile.c_str());
ensure("number of settings", (results == 1));
mCG->getControl("TestSetting")->getSignal()->connect(boost::bind(&this->handleListenerTest, _1));
mCG->setU32("TestSetting", 13);
ensure("listener fired on changed setting", mListenerFired);
}
}

View File

@@ -0,0 +1,576 @@
/**
* @file lldatapacker_tut.cpp
* @author Adroit
* @date 2007-02
* @brief LLDataPacker test cases.
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "lltut.h"
#include "linden_common.h"
#include "lldatapacker.h"
#include "v4color.h"
#include "v4coloru.h"
#include "v2math.h"
#include "v3math.h"
#include "v4math.h"
#include "llsdserialize.h"
#define TEST_FILE_NAME "datapacker_test.txt"
namespace tut
{
struct datapacker_test
{
};
typedef test_group<datapacker_test> datapacker_test_t;
typedef datapacker_test_t::object datapacker_test_object_t;
tut::datapacker_test_t tut_datapacker_test("datapacker_test");
//*********LLDataPackerBinaryBuffer
template<> template<>
void datapacker_test_object_t::test<1>()
{
U8 packbuf[128];
F32 f_val1 = 44.44f, f_unpkval1;
F32 f_val2 = 12344.443232f, f_unpkval2;
F32 f_val3 = 44.4456789f, f_unpkval3;
LLDataPackerBinaryBuffer lldp(packbuf,128);
lldp.packFixed( f_val1, "linden_lab", FALSE, 8, 8);
lldp.packFixed( f_val2, "linden_lab", FALSE, 14, 16);
lldp.packFixed( f_val3, "linden_lab", FALSE, 8, 23);
LLDataPackerBinaryBuffer lldp1(packbuf, lldp.getCurrentSize());
lldp1.unpackFixed(f_unpkval1, "linden_lab", FALSE, 8, 8);
lldp1.unpackFixed(f_unpkval2, "linden_lab", FALSE, 14, 16);
lldp1.unpackFixed(f_unpkval3, "linden_lab", FALSE, 8, 23);
ensure_approximately_equals("LLDataPackerBinaryBuffer::packFixed 8 failed", f_val1, f_unpkval1, 8);
ensure_approximately_equals("LLDataPackerBinaryBuffer::packFixed 16 failed", f_val2, f_unpkval2, 16);
ensure_approximately_equals("LLDataPackerBinaryBuffer::packFixed 23 failed", f_val3, f_unpkval3, 31);
}
template<> template<>
void datapacker_test_object_t::test<2>()
{
U8 packbuf[1024];
char str[] = "SecondLife is virtual World\0";
char strBinary[] = "SecondLife is virtual World";
char strBinaryFixed[] = "Fixed Data";
S32 sizeBinaryFixed = sizeof(strBinaryFixed);
U8 valU8 = 'C';
U16 valU16 = 0xFFFF;
U32 valU32 = 0xFFFFFFFF;
S32 valS32 = -94967295;
F32 valF32 = 4354355.44f ;
LLColor4 llcol4(3.3f, 0, 4.4f, 5.5f);
LLColor4U llcol4u(3, 128, 24, 33);
LLVector2 llvec2(333.33f, 444.44f);
LLVector3 llvec3(333.33f, 444.44f, 555.55f);
LLVector4 llvec4(333.33f, 444.44f, 555.55f, 666.66f);
LLUUID uuid;
std::string unpkstr;
char unpkstrBinary[256];
char unpkstrBinaryFixed[256];
S32 unpksizeBinary;
U8 unpkvalU8;
U16 unpkvalU16;
U32 unpkvalU32;
S32 unpkvalS32;
F32 unpkvalF32;
LLColor4 unpkllcol4;
LLColor4U unpkllcol4u;
LLVector2 unpkllvec2;
LLVector3 unpkllvec3;
LLVector4 unpkllvec4;
LLUUID unpkuuid;
LLDataPackerBinaryBuffer lldp(packbuf,1024);
lldp.packString(str , "linden_lab_str");
lldp.packBinaryData((U8*)strBinary, sizeof(strBinary), "linden_lab_bd");
lldp.packBinaryDataFixed((U8*)strBinaryFixed, sizeBinaryFixed, "linden_lab_bdf");
lldp.packU8(valU8,"linden_lab_u8");
lldp.packU16(valU16,"linden_lab_u16");
lldp.packU32(valU32, "linden_lab_u32");
lldp.packS32(valS32, "linden_lab_s32");
lldp.packF32(valF32, "linden_lab_f32");
lldp.packColor4(llcol4, "linden_lab_col4");
lldp.packColor4U(llcol4u, "linden_lab_col4u");
lldp.packVector2(llvec2, "linden_lab_vec2");
lldp.packVector3(llvec3, "linden_lab_vec3");
lldp.packVector4(llvec4, "linden_lab_vec4");
uuid.generate();
lldp.packUUID(uuid, "linden_lab_uuid");
S32 cur_size = lldp.getCurrentSize();
LLDataPackerBinaryBuffer lldp1(packbuf, cur_size);
lldp1.unpackString(unpkstr , "linden_lab_str");
lldp1.unpackBinaryData((U8*)unpkstrBinary, unpksizeBinary, "linden_lab_bd");
lldp1.unpackBinaryDataFixed((U8*)unpkstrBinaryFixed, sizeBinaryFixed, "linden_lab_bdf");
lldp1.unpackU8(unpkvalU8,"linden_lab_u8");
lldp1.unpackU16(unpkvalU16,"linden_lab_u16");
lldp1.unpackU32(unpkvalU32, "linden_lab_u32");
lldp1.unpackS32(unpkvalS32, "linden_lab_s32");
lldp1.unpackF32(unpkvalF32, "linden_lab_f32");
lldp1.unpackColor4(unpkllcol4, "linden_lab_col4");
lldp1.unpackColor4U(unpkllcol4u, "linden_lab_col4u");
lldp1.unpackVector2(unpkllvec2, "linden_lab_vec2");
lldp1.unpackVector3(unpkllvec3, "linden_lab_vec3");
lldp1.unpackVector4(unpkllvec4, "linden_lab_vec4");
lldp1.unpackUUID(unpkuuid, "linden_lab_uuid");
ensure("LLDataPackerBinaryBuffer::packString failed", strcmp(str, unpkstr.c_str()) == 0);
ensure("LLDataPackerBinaryBuffer::packBinaryData failed", strcmp(strBinary, unpkstrBinary) == 0);
ensure("LLDataPackerBinaryBuffer::packBinaryDataFixed failed", strcmp(strBinaryFixed, unpkstrBinaryFixed) == 0);
ensure_equals("LLDataPackerBinaryBuffer::packU8 failed", valU8, unpkvalU8);
ensure_equals("LLDataPackerBinaryBuffer::packU16 failed", valU16, unpkvalU16);
ensure_equals("LLDataPackerBinaryBuffer::packU32 failed", valU32, unpkvalU32);
ensure_equals("LLDataPackerBinaryBuffer::packS32 failed", valS32, unpkvalS32);
ensure("LLDataPackerBinaryBuffer::packF32 failed", is_approx_equal(valF32, unpkvalF32));
ensure_equals("LLDataPackerBinaryBuffer::packColor4 failed", llcol4, unpkllcol4);
ensure_equals("LLDataPackerBinaryBuffer::packColor4U failed", llcol4u, unpkllcol4u);
ensure_equals("LLDataPackerBinaryBuffer::packVector2 failed", llvec2, unpkllvec2);
ensure_equals("LLDataPackerBinaryBuffer::packVector3 failed", llvec3, unpkllvec3);
ensure_equals("LLDataPackerBinaryBuffer::packVector4 failed", llvec4, unpkllvec4);
ensure_equals("LLDataPackerBinaryBuffer::packUUID failed", uuid, unpkuuid);
}
template<> template<>
void datapacker_test_object_t::test<3>()
{
U8 packbuf[128];
char str[] = "SecondLife is virtual World";
S32 strSize = sizeof(str); // include '\0'
LLDataPackerBinaryBuffer lldp(packbuf, 128);
lldp.packString(str , "linden_lab");
ensure("LLDataPackerBinaryBuffer: current size is wrong", strSize == lldp.getCurrentSize());
ensure("LLDataPackerBinaryBuffer: buffer size is wrong", 128 == lldp.getBufferSize());
lldp.reset();
ensure("LLDataPackerBinaryBuffer::reset failed",0 == lldp.getCurrentSize());
}
template<> template<>
void datapacker_test_object_t::test<4>()
{
U8* packbuf = new U8[128];
char str[] = "SecondLife is virtual World";
LLDataPackerBinaryBuffer lldp(packbuf, 128);
lldp.packString(str , "linden_lab");
lldp.freeBuffer();
ensure("LLDataPackerBinaryBuffer.freeBuffer failed" , 0 == lldp.getBufferSize());
}
template<> template<>
void datapacker_test_object_t::test<5>()
{
U8 buf[] = "SecondLife is virtual World";
S32 size = sizeof(buf);
LLDataPackerBinaryBuffer lldp(buf, size);
U8 new_buf[] = "Its Amazing";
size = sizeof(new_buf);
lldp.assignBuffer(new_buf, size);
ensure("LLDataPackerBinaryBuffer::assignBuffer failed" , ((lldp.getBufferSize() == size) && (0 == lldp.getCurrentSize()))) ;
}
template<> template<>
void datapacker_test_object_t::test<6>()
{
U8 packbuf[128];
char str[] = "SecondLife is virtual World";
LLDataPackerBinaryBuffer lldp(packbuf, 128);
lldp.packString(str , "linden_lab");
U8 new_buffer[128];
std::string unpkbuf;
LLDataPackerBinaryBuffer lldp1(new_buffer,128);
lldp1 = lldp;
lldp1.unpackString(unpkbuf, "linden_lab");
ensure("1. LLDataPackerBinaryBuffer::operator= failed" , lldp1.getBufferSize() == lldp.getBufferSize());
ensure_equals("2.LLDataPackerBinaryBuffer::operator= failed", str,unpkbuf);
}
//*********LLDataPackerAsciiBuffer
template<> template<>
void datapacker_test_object_t::test<7>()
{
char packbuf[128];
F32 f_val = 44.44f, f_unpkval;
LLDataPackerAsciiBuffer lldp(packbuf,128);
lldp.packFixed( f_val, "linden_lab", FALSE, 8, 8);
LLDataPackerAsciiBuffer lldp1(packbuf, lldp.getCurrentSize());
lldp1.unpackFixed(f_unpkval, "linden_lab", FALSE, 8, 8);
ensure_approximately_equals("LLDataPackerAsciiBuffer::packFixed failed", f_val, f_unpkval, 8);
}
template<> template<>
void datapacker_test_object_t::test<8>()
{
char packbuf[1024];
char str[] = "SecondLife is virtual World\0";
char strBinary[] = "SecondLife is virtual World";
char strBinaryFixed[] = "Fixed Data";
S32 sizeBinaryFixed = sizeof(strBinaryFixed);
U8 valU8 = 'C';
U16 valU16 = 0xFFFF;
U32 valU32 = 0xFFFFFFFF;
S32 valS32 = -94967295;
F32 valF32 = 4354355.44f ;
LLColor4 llcol4(3.3f, 0, 4.4f, 5.5f);
LLColor4U llcol4u(3, 128, 24, 33);
LLVector2 llvec2(333.33f, 444.44f);
LLVector3 llvec3(333.33f, 444.44f, 555.55f);
LLVector4 llvec4(4354355.44f, 444.44f, 555.55f, 666.66f);
LLUUID uuid;
std::string unpkstr;
char unpkstrBinary[256];
char unpkstrBinaryFixed[256];
S32 unpksizeBinary;
U8 unpkvalU8;
U16 unpkvalU16;
U32 unpkvalU32;
S32 unpkvalS32;
F32 unpkvalF32;
LLColor4 unpkllcol4;
LLColor4U unpkllcol4u;
LLVector2 unpkllvec2;
LLVector3 unpkllvec3;
LLVector4 unpkllvec4;
LLUUID unpkuuid;
LLDataPackerAsciiBuffer lldp(packbuf,1024);
lldp.packString(str , "linden_lab_str");
lldp.packBinaryData((U8*)strBinary, sizeof(strBinary), "linden_lab_bd");
lldp.packBinaryDataFixed((U8*)strBinaryFixed, sizeBinaryFixed, "linden_lab_bdf");
lldp.packU8(valU8,"linden_lab_u8");
lldp.packU16(valU16,"linden_lab_u16");
lldp.packU32(valU32, "linden_lab_u32");
lldp.packS32(valS32, "linden_lab_s32");
lldp.packF32(valF32, "linden_lab_f32");
lldp.packColor4(llcol4, "linden_lab_col4");
lldp.packColor4U(llcol4u, "linden_lab_col4u");
lldp.packVector2(llvec2, "linden_lab_vec2");
lldp.packVector3(llvec3, "linden_lab_vec3");
lldp.packVector4(llvec4, "linden_lab_vec4");
uuid.generate();
lldp.packUUID(uuid, "linden_lab_uuid");
S32 cur_size = lldp.getCurrentSize();
LLDataPackerAsciiBuffer lldp1(packbuf, cur_size);
lldp1.unpackString(unpkstr , "linden_lab_str");
lldp1.unpackBinaryData((U8*)unpkstrBinary, unpksizeBinary, "linden_lab_bd");
lldp1.unpackBinaryDataFixed((U8*)unpkstrBinaryFixed, sizeBinaryFixed, "linden_lab_bdf");
lldp1.unpackU8(unpkvalU8,"linden_lab_u8");
lldp1.unpackU16(unpkvalU16,"linden_lab_u16");
lldp1.unpackU32(unpkvalU32, "linden_lab_u32");
lldp1.unpackS32(unpkvalS32, "linden_lab_s32");
lldp1.unpackF32(unpkvalF32, "linden_lab_f32");
lldp1.unpackColor4(unpkllcol4, "linden_lab_col4");
lldp1.unpackColor4U(unpkllcol4u, "linden_lab_col4u");
lldp1.unpackVector2(unpkllvec2, "linden_lab_vec2");
lldp1.unpackVector3(unpkllvec3, "linden_lab_vec3");
lldp1.unpackVector4(unpkllvec4, "linden_lab_vec4");
lldp1.unpackUUID(unpkuuid, "linden_lab_uuid");
ensure("LLDataPackerAsciiBuffer::packString failed", strcmp(str, unpkstr.c_str()) == 0);
ensure("LLDataPackerAsciiBuffer::packBinaryData failed", strcmp(strBinary, unpkstrBinary) == 0);
ensure("LLDataPackerAsciiBuffer::packBinaryDataFixed failed", strcmp(strBinaryFixed, unpkstrBinaryFixed) == 0);
ensure_equals("LLDataPackerAsciiBuffer::packU8 failed", valU8, unpkvalU8);
ensure_equals("LLDataPackerAsciiBuffer::packU16 failed", valU16, unpkvalU16);
ensure_equals("LLDataPackerAsciiBuffer::packU32 failed", valU32, unpkvalU32);
ensure_equals("LLDataPackerAsciiBuffer::packS32 failed", valS32, unpkvalS32);
ensure("LLDataPackerAsciiBuffer::packF32 failed", is_approx_equal(valF32, unpkvalF32));
ensure_equals("LLDataPackerAsciiBuffer::packColor4 failed", llcol4, unpkllcol4);
ensure_equals("LLDataPackerAsciiBuffer::packColor4U failed", llcol4u, unpkllcol4u);
ensure_equals("LLDataPackerAsciiBuffer::packVector2 failed", llvec2, unpkllvec2);
ensure_equals("LLDataPackerAsciiBuffer::packVector3 failed", llvec3, unpkllvec3);
ensure_equals("LLDataPackerAsciiBuffer::packVector4 failed", llvec4, unpkllvec4);
ensure_equals("LLDataPackerAsciiBuffer::packUUID failed", uuid, unpkuuid);
}
template<> template<>
void datapacker_test_object_t::test<9>()
{
char* packbuf = new char[128];
char str[] = "SecondLife is virtual World";
LLDataPackerAsciiBuffer lldp(packbuf, 128);
lldp.packString(str , "linden_lab");
lldp.freeBuffer();
ensure("LLDataPackerAsciiBuffer::freeBuffer failed" , 0 == lldp.getBufferSize());
}
template<> template<>
void datapacker_test_object_t::test<10>()
{
char buf[] = "SecondLife is virtual World";
S32 size = sizeof(buf);
LLDataPackerAsciiBuffer lldp(buf, size);
char new_buf[] = "Its Amazing";
size = sizeof(new_buf);
lldp.assignBuffer(new_buf, size);
ensure("LLDataPackerAsciiBuffer::assignBuffer failed" , ((lldp.getBufferSize() == size) && (1 == lldp.getCurrentSize()))) ;
}
//*********LLDataPackerAsciiFile
template<> template<>
void datapacker_test_object_t::test<11>()
{
F32 f_val = 44.44f, f_unpkval;
LLFILE* fp = LLFile::fopen(TEST_FILE_NAME, "w+");
if(!fp)
{
llerrs << "File couldnt be open" <<llendl;
return;
}
LLDataPackerAsciiFile lldp(fp,2);
lldp.packFixed( f_val, "linden_lab", FALSE, 8, 8);
fflush(fp);
fseek(fp,0,SEEK_SET);
LLDataPackerAsciiFile lldp1(fp,2);
lldp1.unpackFixed(f_unpkval, "linden_lab", FALSE, 8, 8);
fclose(fp);
ensure_approximately_equals("LLDataPackerAsciiFile::packFixed failed", f_val, f_unpkval, 8);
}
template<> template<>
void datapacker_test_object_t::test<12>()
{
char str[] = "SecondLife is virtual World\0";
char strBinary[] = "SecondLife is virtual World";
char strBinaryFixed[] = "Fixed Data";
S32 sizeBinaryFixed = sizeof(strBinaryFixed);
U8 valU8 = 'C';
U16 valU16 = 0xFFFF;
U32 valU32 = 0xFFFFFFFF;
S32 valS32 = -94967295;
F32 valF32 = 4354355.44f ;
LLColor4 llcol4(3.3f, 0, 4.4f, 5.5f);
LLColor4U llcol4u(3, 128, 24, 33);
LLVector2 llvec2(333.33f, 444.44f);
LLVector3 llvec3(333.33f, 444.44f, 555.55f);
LLVector4 llvec4(333.33f, 444.44f, 555.55f, 666.66f);
LLUUID uuid;
std::string unpkstr;
char unpkstrBinary[256];
char unpkstrBinaryFixed[256];
S32 unpksizeBinary;
U8 unpkvalU8;
U16 unpkvalU16;
U32 unpkvalU32;
S32 unpkvalS32;
F32 unpkvalF32;
LLColor4 unpkllcol4;
LLColor4U unpkllcol4u;
LLVector2 unpkllvec2;
LLVector3 unpkllvec3;
LLVector4 unpkllvec4;
LLUUID unpkuuid;
LLFILE* fp = LLFile::fopen(TEST_FILE_NAME,"w+");
if(!fp)
{
llerrs << "File couldnt be open" <<llendl;
return;
}
LLDataPackerAsciiFile lldp(fp,2);
lldp.packString(str , "linden_lab_str");
lldp.packBinaryData((U8*)strBinary, sizeof(strBinary), "linden_lab_bd");
lldp.packBinaryDataFixed((U8*)strBinaryFixed, sizeBinaryFixed, "linden_lab_bdf");
lldp.packU8(valU8,"linden_lab_u8");
lldp.packU16(valU16,"linden_lab_u16");
lldp.packU32(valU32, "linden_lab_u32");
lldp.packS32(valS32, "linden_lab_s32");
lldp.packF32(valF32, "linden_lab_f32");
lldp.packColor4(llcol4, "linden_lab_col4");
lldp.packColor4U(llcol4u, "linden_lab_col4u");
lldp.packVector2(llvec2, "linden_lab_vec2");
lldp.packVector3(llvec3, "linden_lab_vec3");
lldp.packVector4(llvec4, "linden_lab_vec4");
uuid.generate();
lldp.packUUID(uuid, "linden_lab_uuid");
fflush(fp);
fseek(fp,0,SEEK_SET);
LLDataPackerAsciiFile lldp1(fp,2);
lldp1.unpackString(unpkstr , "linden_lab_str");
lldp1.unpackBinaryData((U8*)unpkstrBinary, unpksizeBinary, "linden_lab_bd");
lldp1.unpackBinaryDataFixed((U8*)unpkstrBinaryFixed, sizeBinaryFixed, "linden_lab_bdf");
lldp1.unpackU8(unpkvalU8,"linden_lab_u8");
lldp1.unpackU16(unpkvalU16,"linden_lab_u16");
lldp1.unpackU32(unpkvalU32, "linden_lab_u32");
lldp1.unpackS32(unpkvalS32, "linden_lab_s32");
lldp1.unpackF32(unpkvalF32, "linden_lab_f32");
lldp1.unpackColor4(unpkllcol4, "linden_lab_col4");
lldp1.unpackColor4U(unpkllcol4u, "linden_lab_col4u");
lldp1.unpackVector2(unpkllvec2, "linden_lab_vec2");
lldp1.unpackVector3(unpkllvec3, "linden_lab_vec3");
lldp1.unpackVector4(unpkllvec4, "linden_lab_vec4");
lldp1.unpackUUID(unpkuuid, "linden_lab_uuid");
fclose(fp);
ensure("LLDataPackerAsciiFile::packString failed", strcmp(str, unpkstr.c_str()) == 0);
ensure("LLDataPackerAsciiFile::packBinaryData failed", strcmp(strBinary, unpkstrBinary) == 0);
ensure("LLDataPackerAsciiFile::packBinaryDataFixed failed", strcmp(strBinaryFixed, unpkstrBinaryFixed) == 0);
ensure_equals("LLDataPackerAsciiFile::packU8 failed", valU8, unpkvalU8);
ensure_equals("LLDataPackerAsciiFile::packU16 failed", valU16, unpkvalU16);
ensure_equals("LLDataPackerAsciiFile::packU32 failed", valU32, unpkvalU32);
ensure_equals("LLDataPackerAsciiFile::packS32 failed", valS32, unpkvalS32);
ensure("LLDataPackerAsciiFile::packF32 failed", is_approx_equal(valF32, unpkvalF32));
ensure_equals("LLDataPackerAsciiFile::packColor4 failed", llcol4, unpkllcol4);
ensure_equals("LLDataPackerAsciiFile::packColor4U failed", llcol4u, unpkllcol4u);
ensure_equals("LLDataPackerAsciiFile::packVector2 failed", llvec2, unpkllvec2);
ensure_equals("LLDataPackerAsciiFile::packVector3 failed", llvec3, unpkllvec3);
ensure_equals("LLDataPackerAsciiFile::packVector4 failed", llvec4, unpkllvec4);
ensure_equals("LLDataPackerAsciiFile::packUUID failed", uuid, unpkuuid);
}
template<> template<>
void datapacker_test_object_t::test<13>()
{
F32 f_val = 44.44f, f_unpkval;
std::ostringstream ostr;
LLDataPackerAsciiFile lldp(ostr,2);
lldp.packFixed( f_val, "linden_lab", FALSE, 8, 8);
std::istringstream istr(ostr.str());
LLDataPackerAsciiFile lldp1(istr,2);
lldp1.unpackFixed(f_unpkval, "linden_lab", FALSE, 8, 8);
ensure_approximately_equals("LLDataPackerAsciiFile::packFixed (iostring) failed", f_val, f_unpkval, 8);
}
template<> template<>
void datapacker_test_object_t::test<14>()
{
char str[] = "SecondLife is virtual World\0";
char strBinary[] = "SecondLife is virtual World";
char strBinaryFixed[] = "Fixed Data";
S32 sizeBinaryFixed = sizeof(strBinaryFixed);
U8 valU8 = 'C';
U16 valU16 = 0xFFFF;
U32 valU32 = 0xFFFFFFFF;
S32 valS32 = -94967295;
F32 valF32 = 4354355.44f ;
LLColor4 llcol4(3.3f, 0, 4.4f, 5.5f);
LLColor4U llcol4u(3, 128, 24, 33);
LLVector2 llvec2(3333333.33f, 444.333344f);
LLVector3 llvec3(3323233.33f, 444.4324f, 555.553232f);
LLVector4 llvec4(333.33233f, 444.4323234f, 55323225.55f, 6323236.66f);
LLUUID uuid;
std::string unpkstr;
char unpkstrBinary[256];
char unpkstrBinaryFixed[256];
S32 unpksizeBinary;
U8 unpkvalU8;
U16 unpkvalU16;
U32 unpkvalU32;
S32 unpkvalS32;
F32 unpkvalF32;
LLColor4 unpkllcol4;
LLColor4U unpkllcol4u;
LLVector2 unpkllvec2;
LLVector3 unpkllvec3;
LLVector4 unpkllvec4;
LLUUID unpkuuid;
std::ostringstream ostr;
LLDataPackerAsciiFile lldp(ostr,2);
lldp.packString(str , "linden_lab_str");
lldp.packBinaryData((U8*)strBinary, sizeof(strBinary), "linden_lab_bd");
lldp.packBinaryDataFixed((U8*)strBinaryFixed, sizeBinaryFixed, "linden_lab_bdf");
lldp.packU8(valU8,"linden_lab_u8");
lldp.packU16(valU16,"linden_lab_u16");
lldp.packU32(valU32, "linden_lab_u32");
lldp.packS32(valS32, "linden_lab_s32");
lldp.packF32(valF32, "linden_lab_f32");
lldp.packColor4(llcol4, "linden_lab_col4");
lldp.packColor4U(llcol4u, "linden_lab_col4u");
lldp.packVector2(llvec2, "linden_lab_vec2");
lldp.packVector3(llvec3, "linden_lab_vec3");
lldp.packVector4(llvec4, "linden_lab_vec4");
uuid.generate();
lldp.packUUID(uuid, "linden_lab_uuid");
std::istringstream istr(ostr.str());
LLDataPackerAsciiFile lldp1(istr,2);
lldp1.unpackString(unpkstr , "linden_lab_str");
lldp1.unpackBinaryData((U8*)unpkstrBinary, unpksizeBinary, "linden_lab_bd");
lldp1.unpackBinaryDataFixed((U8*)unpkstrBinaryFixed, sizeBinaryFixed, "linden_lab_bdf");
lldp1.unpackU8(unpkvalU8,"linden_lab_u8");
lldp1.unpackU16(unpkvalU16,"linden_lab_u16");
lldp1.unpackU32(unpkvalU32, "linden_lab_u32");
lldp1.unpackS32(unpkvalS32, "linden_lab_s32");
lldp1.unpackF32(unpkvalF32, "linden_lab_f32");
lldp1.unpackColor4(unpkllcol4, "linden_lab_col4");
lldp1.unpackColor4U(unpkllcol4u, "linden_lab_col4u");
lldp1.unpackVector2(unpkllvec2, "linden_lab_vec2");
lldp1.unpackVector3(unpkllvec3, "linden_lab_vec3");
lldp1.unpackVector4(unpkllvec4, "linden_lab_vec4");
lldp1.unpackUUID(unpkuuid, "linden_lab_uuid");
ensure("LLDataPackerAsciiFile::packString (iostring) failed", strcmp(str, unpkstr.c_str()) == 0);
ensure("LLDataPackerAsciiFile::packBinaryData (iostring) failed", strcmp(strBinary, unpkstrBinary) == 0);
ensure("LLDataPackerAsciiFile::packBinaryDataFixed (iostring) failed", strcmp(strBinaryFixed, unpkstrBinaryFixed) == 0);
ensure_equals("LLDataPackerAsciiFile::packU8 (iostring) failed", valU8, unpkvalU8);
ensure_equals("LLDataPackerAsciiFile::packU16 (iostring) failed", valU16, unpkvalU16);
ensure_equals("LLDataPackerAsciiFile::packU32 (iostring) failed", valU32, unpkvalU32);
ensure_equals("LLDataPackerAsciiFile::packS32 (iostring) failed", valS32, unpkvalS32);
ensure("LLDataPackerAsciiFile::packF32 (iostring) failed", is_approx_equal(valF32, unpkvalF32));
ensure_equals("LLDataPackerAsciiFile::packColor4 (iostring) failed", llcol4, unpkllcol4);
ensure_equals("LLDataPackerAsciiFile::packColor4U (iostring) failed", llcol4u, unpkllcol4u);
ensure_equals("LLDataPackerAsciiFile::packVector2 (iostring) failed", llvec2, unpkllvec2);
ensure_equals("LLDataPackerAsciiFile::packVector3 (iostring) failed", llvec3, unpkllvec3);
ensure_equals("LLDataPackerAsciiFile::packVector4 (iostring) failed", llvec4, unpkllvec4);
ensure_equals("LLDataPackerAsciiFile::packUUID (iostring) failed", uuid, unpkuuid);
}
}

215
indra/test/lldate_tut.cpp Normal file
View File

@@ -0,0 +1,215 @@
/**
* @file lldate_tut.cpp
* @author Adroit
* @date 2007-02
* @brief LLDate test cases.
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "lldate.h"
#define VALID_DATE "2003-04-30T04:00:00Z"
#define VALID_DATE_LEAP "2004-02-29T04:00:00Z"
#define VALID_DATE_HOUR_BOUNDARY "2003-04-30T23:59:59Z"
#define VALID_DATE_FRACTIONAL_SECS "2007-09-26T20:31:33.70Z"
// invalid format
#define INVALID_DATE_MISSING_YEAR "-04-30T22:59:59Z"
#define INVALID_DATE_MISSING_MONTH "1900-0430T22:59:59Z"
#define INVALID_DATE_MISSING_DATE "1900-0430-T22:59:59Z"
#define INVALID_DATE_MISSING_T "1900-04-30-22:59:59Z"
#define INVALID_DATE_MISSING_HOUR "1900-04-30T:59:59Z"
#define INVALID_DATE_MISSING_MIN "1900-04-30T01::59Z"
#define INVALID_DATE_MISSING_SEC "1900-04-30T01:59Z"
#define INVALID_DATE_MISSING_Z "1900-04-30T01:59:23"
#define INVALID_DATE_EMPTY ""
// invalid values
// apr 1.1.1 seems to not care about constraining the date to valid
// dates. Put these back when the parser checks.
#define LL_DATE_PARSER_CHECKS_BOUNDARY 0
//#define INVALID_DATE_24HOUR_BOUNDARY "2003-04-30T24:00:00Z"
//#define INVALID_DATE_LEAP "2003-04-29T04:00:00Z"
//#define INVALID_DATE_HOUR "2003-04-30T24:59:59Z"
//#define INVALID_DATE_MIN "2003-04-30T22:69:59Z"
//#define INVALID_DATE_SEC "2003-04-30T22:59:69Z"
//#define INVALID_DATE_YEAR "0-04-30T22:59:59Z"
//#define INVALID_DATE_MONTH "2003-13-30T22:59:59Z"
//#define INVALID_DATE_DAY "2003-04-35T22:59:59Z"
namespace tut
{
struct date_test
{
};
typedef test_group<date_test> date_test_t;
typedef date_test_t::object date_test_object_t;
tut::date_test_t tut_date_test("date_test");
/* format validation */
template<> template<>
void date_test_object_t::test<1>()
{
LLDate date(VALID_DATE);
std::string expected_string;
bool result;
expected_string = VALID_DATE;
ensure_equals("Valid Date failed" , expected_string, date.asString());
result = date.fromString(VALID_DATE_LEAP);
expected_string = VALID_DATE_LEAP;
ensure_equals("VALID_DATE_LEAP failed" , expected_string, date.asString());
result = date.fromString(VALID_DATE_HOUR_BOUNDARY);
expected_string = VALID_DATE_HOUR_BOUNDARY;
ensure_equals("VALID_DATE_HOUR_BOUNDARY failed" , expected_string, date.asString());
result = date.fromString(VALID_DATE_FRACTIONAL_SECS);
expected_string = VALID_DATE_FRACTIONAL_SECS;
ensure_equals("VALID_DATE_FRACTIONAL_SECS failed" , expected_string, date.asString());
result = date.fromString(INVALID_DATE_MISSING_YEAR);
ensure_equals("INVALID_DATE_MISSING_YEAR should have failed" , result, false);
result = date.fromString(INVALID_DATE_MISSING_MONTH);
ensure_equals("INVALID_DATE_MISSING_MONTH should have failed" , result, false);
result = date.fromString(INVALID_DATE_MISSING_DATE);
ensure_equals("INVALID_DATE_MISSING_DATE should have failed" , result, false);
result = date.fromString(INVALID_DATE_MISSING_T);
ensure_equals("INVALID_DATE_MISSING_T should have failed" , result, false);
result = date.fromString(INVALID_DATE_MISSING_HOUR);
ensure_equals("INVALID_DATE_MISSING_HOUR should have failed" , result, false);
result = date.fromString(INVALID_DATE_MISSING_MIN);
ensure_equals("INVALID_DATE_MISSING_MIN should have failed" , result, false);
result = date.fromString(INVALID_DATE_MISSING_SEC);
ensure_equals("INVALID_DATE_MISSING_SEC should have failed" , result, false);
result = date.fromString(INVALID_DATE_MISSING_Z);
ensure_equals("INVALID_DATE_MISSING_Z should have failed" , result, false);
result = date.fromString(INVALID_DATE_EMPTY);
ensure_equals("INVALID_DATE_EMPTY should have failed" , result, false);
}
/* Invalid Value Handling */
template<> template<>
void date_test_object_t::test<2>()
{
#if LL_DATE_PARSER_CHECKS_BOUNDARY
LLDate date;
std::string expected_string;
bool result;
result = date.fromString(INVALID_DATE_24HOUR_BOUNDARY);
ensure_equals("INVALID_DATE_24HOUR_BOUNDARY should have failed" , result, false);
ensure_equals("INVALID_DATE_24HOUR_BOUNDARY date still set to old value on failure!" , date.secondsSinceEpoch(), 0);
result = date.fromString(INVALID_DATE_LEAP);
ensure_equals("INVALID_DATE_LEAP should have failed" , result, false);
result = date.fromString(INVALID_DATE_HOUR);
ensure_equals("INVALID_DATE_HOUR should have failed" , result, false);
result = date.fromString(INVALID_DATE_MIN);
ensure_equals("INVALID_DATE_MIN should have failed" , result, false);
result = date.fromString(INVALID_DATE_SEC);
ensure_equals("INVALID_DATE_SEC should have failed" , result, false);
result = date.fromString(INVALID_DATE_YEAR);
ensure_equals("INVALID_DATE_YEAR should have failed" , result, false);
result = date.fromString(INVALID_DATE_MONTH);
ensure_equals("INVALID_DATE_MONTH should have failed" , result, false);
result = date.fromString(INVALID_DATE_DAY);
ensure_equals("INVALID_DATE_DAY should have failed" , result, false);
#endif
}
/* API checks */
template<> template<>
void date_test_object_t::test<3>()
{
LLDate date;
std::istringstream stream(VALID_DATE);
std::string expected_string = VALID_DATE;
date.fromStream(stream);
ensure_equals("fromStream failed", date.asString(), expected_string);
}
template<> template<>
void date_test_object_t::test<4>()
{
LLDate date1(VALID_DATE);
LLDate date2(date1);
ensure_equals("LLDate(const LLDate& date) constructor failed", date1.asString(), date2.asString());
}
template<> template<>
void date_test_object_t::test<5>()
{
LLDate date1(VALID_DATE);
LLDate date2(date1.secondsSinceEpoch());
ensure_equals("secondsSinceEpoch not equal",date1.secondsSinceEpoch(), date2.secondsSinceEpoch());
ensure_equals("LLDate created using secondsSinceEpoch not equal", date1.asString(), date2.asString());
}
template<> template<>
void date_test_object_t::test<6>()
{
LLDate date(VALID_DATE);
std::ostringstream stream;
stream << date;
std::string expected_str = VALID_DATE;
ensure_equals("ostringstream failed", expected_str, stream.str());
}
template<> template<>
void date_test_object_t::test<7>()
{
LLDate date;
std::istringstream stream(VALID_DATE);
stream >> date;
std::string expected_str = VALID_DATE;
std::ostringstream out_stream;
out_stream << date;
ensure_equals("<< failed", date.asString(),expected_str);
ensure_equals("<< to >> failed", stream.str(),out_stream.str());
}
}

265
indra/test/lldir_tut.cpp Normal file
View File

@@ -0,0 +1,265 @@
/**
* @file lldir_tut.cpp
* @date 2008-05
* @brief LLDir test cases.
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
* Copyright (c) 2008-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "lltut.h"
#include "lldir.h"
namespace tut
{
struct LLDirTest
{
};
typedef test_group<LLDirTest> LLDirTest_t;
typedef LLDirTest_t::object LLDirTest_object_t;
tut::LLDirTest_t tut_LLDirTest("LLDir");
template<> template<>
void LLDirTest_object_t::test<1>()
// getDirDelimiter
{
ensure("getDirDelimiter", !gDirUtilp->getDirDelimiter().empty());
}
template<> template<>
void LLDirTest_object_t::test<2>()
// getBaseFileName
{
std::string delim = gDirUtilp->getDirDelimiter();
std::string rawFile = "foo";
std::string rawFileExt = "foo.bAr";
std::string rawFileNullExt = "foo.";
std::string rawExt = ".bAr";
std::string rawDot = ".";
std::string pathNoExt = "aa" + delim + "bb" + delim + "cc" + delim + "dd" + delim + "ee";
std::string pathExt = pathNoExt + ".eXt";
std::string dottedPathNoExt = "aa" + delim + "bb" + delim + "cc.dd" + delim + "ee";
std::string dottedPathExt = dottedPathNoExt + ".eXt";
// foo[.bAr]
ensure_equals("getBaseFileName/r-no-ext/no-strip-exten",
gDirUtilp->getBaseFileName(rawFile, false),
"foo");
ensure_equals("getBaseFileName/r-no-ext/strip-exten",
gDirUtilp->getBaseFileName(rawFile, true),
"foo");
ensure_equals("getBaseFileName/r-ext/no-strip-exten",
gDirUtilp->getBaseFileName(rawFileExt, false),
"foo.bAr");
ensure_equals("getBaseFileName/r-ext/strip-exten",
gDirUtilp->getBaseFileName(rawFileExt, true),
"foo");
// foo.
ensure_equals("getBaseFileName/rn-no-ext/no-strip-exten",
gDirUtilp->getBaseFileName(rawFileNullExt, false),
"foo.");
ensure_equals("getBaseFileName/rn-no-ext/strip-exten",
gDirUtilp->getBaseFileName(rawFileNullExt, true),
"foo");
// .bAr
// interesting case - with no basename, this IS the basename, not the extension.
ensure_equals("getBaseFileName/e-ext/no-strip-exten",
gDirUtilp->getBaseFileName(rawExt, false),
".bAr");
ensure_equals("getBaseFileName/e-ext/strip-exten",
gDirUtilp->getBaseFileName(rawExt, true),
".bAr");
// .
ensure_equals("getBaseFileName/d/no-strip-exten",
gDirUtilp->getBaseFileName(rawDot, false),
".");
ensure_equals("getBaseFileName/d/strip-exten",
gDirUtilp->getBaseFileName(rawDot, true),
".");
// aa/bb/cc/dd/ee[.eXt]
ensure_equals("getBaseFileName/no-ext/no-strip-exten",
gDirUtilp->getBaseFileName(pathNoExt, false),
"ee");
ensure_equals("getBaseFileName/no-ext/strip-exten",
gDirUtilp->getBaseFileName(pathNoExt, true),
"ee");
ensure_equals("getBaseFileName/ext/no-strip-exten",
gDirUtilp->getBaseFileName(pathExt, false),
"ee.eXt");
ensure_equals("getBaseFileName/ext/strip-exten",
gDirUtilp->getBaseFileName(pathExt, true),
"ee");
// aa/bb/cc.dd/ee[.eXt]
ensure_equals("getBaseFileName/d-no-ext/no-strip-exten",
gDirUtilp->getBaseFileName(dottedPathNoExt, false),
"ee");
ensure_equals("getBaseFileName/d-no-ext/strip-exten",
gDirUtilp->getBaseFileName(dottedPathNoExt, true),
"ee");
ensure_equals("getBaseFileName/d-ext/no-strip-exten",
gDirUtilp->getBaseFileName(dottedPathExt, false),
"ee.eXt");
ensure_equals("getBaseFileName/d-ext/strip-exten",
gDirUtilp->getBaseFileName(dottedPathExt, true),
"ee");
}
template<> template<>
void LLDirTest_object_t::test<3>()
// getDirName
{
std::string delim = gDirUtilp->getDirDelimiter();
std::string rawFile = "foo";
std::string rawFileExt = "foo.bAr";
std::string pathNoExt = "aa" + delim + "bb" + delim + "cc" + delim + "dd" + delim + "ee";
std::string pathExt = pathNoExt + ".eXt";
std::string dottedPathNoExt = "aa" + delim + "bb" + delim + "cc.dd" + delim + "ee";
std::string dottedPathExt = dottedPathNoExt + ".eXt";
// foo[.bAr]
ensure_equals("getDirName/r-no-ext",
gDirUtilp->getDirName(rawFile),
"");
ensure_equals("getDirName/r-ext",
gDirUtilp->getDirName(rawFileExt),
"");
// aa/bb/cc/dd/ee[.eXt]
ensure_equals("getDirName/no-ext",
gDirUtilp->getDirName(pathNoExt),
"aa" + delim + "bb" + delim + "cc" + delim + "dd");
ensure_equals("getDirName/ext",
gDirUtilp->getDirName(pathExt),
"aa" + delim + "bb" + delim + "cc" + delim + "dd");
// aa/bb/cc.dd/ee[.eXt]
ensure_equals("getDirName/d-no-ext",
gDirUtilp->getDirName(dottedPathNoExt),
"aa" + delim + "bb" + delim + "cc.dd");
ensure_equals("getDirName/d-ext",
gDirUtilp->getDirName(dottedPathExt),
"aa" + delim + "bb" + delim + "cc.dd");
}
template<> template<>
void LLDirTest_object_t::test<4>()
// getExtension
{
std::string delim = gDirUtilp->getDirDelimiter();
std::string rawFile = "foo";
std::string rawFileExt = "foo.bAr";
std::string rawFileNullExt = "foo.";
std::string rawExt = ".bAr";
std::string rawDot = ".";
std::string pathNoExt = "aa" + delim + "bb" + delim + "cc" + delim + "dd" + delim + "ee";
std::string pathExt = pathNoExt + ".eXt";
std::string dottedPathNoExt = "aa" + delim + "bb" + delim + "cc.dd" + delim + "ee";
std::string dottedPathExt = dottedPathNoExt + ".eXt";
// foo[.bAr]
ensure_equals("getExtension/r-no-ext",
gDirUtilp->getExtension(rawFile),
"");
ensure_equals("getExtension/r-ext",
gDirUtilp->getExtension(rawFileExt),
"bar");
// foo.
ensure_equals("getExtension/rn-no-ext",
gDirUtilp->getExtension(rawFileNullExt),
"");
// .bAr
// interesting case - with no basename, this IS the basename, not the extension.
ensure_equals("getExtension/e-ext",
gDirUtilp->getExtension(rawExt),
"");
// .
ensure_equals("getExtension/d",
gDirUtilp->getExtension(rawDot),
"");
// aa/bb/cc/dd/ee[.eXt]
ensure_equals("getExtension/no-ext",
gDirUtilp->getExtension(pathNoExt),
"");
ensure_equals("getExtension/ext",
gDirUtilp->getExtension(pathExt),
"ext");
// aa/bb/cc.dd/ee[.eXt]
ensure_equals("getExtension/d-no-ext",
gDirUtilp->getExtension(dottedPathNoExt),
"");
ensure_equals("getExtension/d-ext",
gDirUtilp->getExtension(dottedPathExt),
"ext");
}
}

768
indra/test/llerror_tut.cpp Normal file
View File

@@ -0,0 +1,768 @@
/**
* @file llerror_tut.cpp
* @date December 2006
* @brief error unit tests
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llerror.h"
namespace
{
void test_that_error_h_includes_enough_things_to_compile_a_message()
{
llinfos << "!" << llendl;
}
}
#include <tut/tut.hpp>
#include "lltut.h"
#include <vector>
#include "llerrorcontrol.h"
#include "llsd.h"
namespace
{
static bool fatalWasCalled;
void fatalCall(const std::string&) { fatalWasCalled = true; }
class TestRecorder : public LLError::Recorder
{
public:
TestRecorder() : mWantsTime(false) { }
~TestRecorder() { LLError::removeRecorder(this); }
void recordMessage(LLError::ELevel level,
const std::string& message)
{
mMessages.push_back(message);
}
int countMessages() { return (int) mMessages.size(); }
void clearMessages() { mMessages.clear(); }
void setWantsTime(bool t) { mWantsTime = t; }
bool wantsTime() { return mWantsTime; }
std::string message(int n)
{
std::ostringstream test_name;
test_name << "testing message " << n << ", not enough messages";
tut::ensure(test_name.str(), n < countMessages());
return mMessages[n];
}
private:
typedef std::vector<std::string> MessageVector;
MessageVector mMessages;
bool mWantsTime;
};
}
namespace tut
{
struct ErrorTestData
{
TestRecorder mRecorder;
LLError::Settings* mPriorErrorSettings;
ErrorTestData()
{
fatalWasCalled = false;
mPriorErrorSettings = LLError::saveAndResetSettings();
LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
LLError::setFatalFunction(fatalCall);
LLError::addRecorder(&mRecorder);
}
~ErrorTestData()
{
LLError::removeRecorder(&mRecorder);
LLError::restoreSettings(mPriorErrorSettings);
}
void ensure_message_count(int expectedCount)
{
ensure_equals("message count", mRecorder.countMessages(), expectedCount);
}
void ensure_message_contains(int n, const std::string& expectedText)
{
std::ostringstream test_name;
test_name << "testing message " << n;
ensure_contains(test_name.str(), mRecorder.message(n), expectedText);
}
void ensure_message_does_not_contain(int n, const std::string& expectedText)
{
std::ostringstream test_name;
test_name << "testing message " << n;
ensure_does_not_contain(test_name.str(), mRecorder.message(n), expectedText);
}
};
typedef test_group<ErrorTestData> ErrorTestGroup;
typedef ErrorTestGroup::object ErrorTestObject;
ErrorTestGroup errorTestGroup("error");
template<> template<>
void ErrorTestObject::test<1>()
// basic test of output
{
llinfos << "test" << llendl;
llinfos << "bob" << llendl;
ensure_message_contains(0, "test");
ensure_message_contains(1, "bob");
}
}
namespace
{
void writeSome()
{
lldebugs << "one" << llendl;
llinfos << "two" << llendl;
llwarns << "three" << llendl;
llerrs << "four" << llendl;
// fatal messages write out and addtional "error" message
}
};
namespace tut
{
template<> template<>
void ErrorTestObject::test<2>()
// messages are filtered based on default level
{
LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
writeSome();
ensure_message_contains(0, "one");
ensure_message_contains(1, "two");
ensure_message_contains(2, "three");
ensure_message_contains(3, "error");
ensure_message_contains(4, "four");
ensure_message_count(5);
LLError::setDefaultLevel(LLError::LEVEL_INFO);
writeSome();
ensure_message_contains(5, "two");
ensure_message_contains(6, "three");
ensure_message_contains(7, "error");
ensure_message_contains(8, "four");
ensure_message_count(9);
LLError::setDefaultLevel(LLError::LEVEL_WARN);
writeSome();
ensure_message_contains(9, "three");
ensure_message_contains(10, "error");
ensure_message_contains(11, "four");
ensure_message_count(12);
LLError::setDefaultLevel(LLError::LEVEL_ERROR);
writeSome();
ensure_message_contains(12, "error");
ensure_message_contains(13, "four");
ensure_message_count(14);
LLError::setDefaultLevel(LLError::LEVEL_NONE);
writeSome();
ensure_message_count(14);
}
template<> template<>
void ErrorTestObject::test<3>()
// error type string in output
{
writeSome();
ensure_message_contains(0, "DEBUG: ");
ensure_message_contains(1, "INFO: ");
ensure_message_contains(2, "WARNING: ");
ensure_message_does_not_contain(3, "ERROR");
ensure_message_contains(4, "ERROR: ");
ensure_message_count(5);
}
template<> template<>
void ErrorTestObject::test<4>()
// file abbreviation
{
std::string thisFile = __FILE__;
std::string abbreviateFile = LLError::abbreviateFile(thisFile);
ensure_ends_with("file name abbreviation",
abbreviateFile,
"test/llerror_tut.cpp"
);
ensure_does_not_contain("file name abbreviation",
abbreviateFile, "indra");
std::string someFile =
#if LL_WINDOWS
"C:/amy/bob/cam.cpp"
#else
"/amy/bob/cam.cpp"
#endif
;
std::string someAbbreviation = LLError::abbreviateFile(someFile);
ensure_equals("non-indra file abbreviation",
someAbbreviation, someFile);
}
}
namespace
{
std::string locationString(int line)
{
std::ostringstream location;
location << LLError::abbreviateFile(__FILE__)
<< "(" << line << ") : ";
return location.str();
}
std::string writeReturningLocation()
{
llinfos << "apple" << llendl; int this_line = __LINE__;
return locationString(this_line);
}
std::string writeReturningLocationAndFunction()
{
llinfos << "apple" << llendl; int this_line = __LINE__;
return locationString(this_line) + __FUNCTION__;
}
std::string errorReturningLocation()
{
llerrs << "die" << llendl; int this_line = __LINE__;
return locationString(this_line);
}
}
namespace tut
{
template<> template<>
void ErrorTestObject::test<5>()
// file and line information in log messages
{
std::string location = writeReturningLocation();
// expecting default to not print location information
LLError::setPrintLocation(true);
writeReturningLocation();
LLError::setPrintLocation(false);
writeReturningLocation();
ensure_message_does_not_contain(0, location);
ensure_message_contains(1, location);
ensure_message_does_not_contain(2, location);
}
}
/* The following helper functions and class members all log a simple message
from some particular function scope. Each function takes a bool argument
that indicates if it should log its own name or not (in the manner that
existing log messages often do.) The functions all return their C++
name so that test can be substantial mechanized.
*/
std::string logFromGlobal(bool id)
{
llinfos << (id ? "logFromGlobal: " : "") << "hi" << llendl;
return "logFromGlobal";
}
static std::string logFromStatic(bool id)
{
llinfos << (id ? "logFromStatic: " : "") << "hi" << llendl;
return "logFromStatic";
}
namespace
{
std::string logFromAnon(bool id)
{
llinfos << (id ? "logFromAnon: " : "") << "hi" << llendl;
return "logFromAnon";
}
}
namespace Foo {
std::string logFromNamespace(bool id)
{
llinfos << (id ? "Foo::logFromNamespace: " : "") << "hi" << llendl;
//return "Foo::logFromNamespace";
// there is no standard way to get the namespace name, hence
// we won't be testing for it
return "logFromNamespace";
}
}
namespace
{
class ClassWithNoLogType {
public:
std::string logFromMember(bool id)
{
llinfos << (id ? "ClassWithNoLogType::logFromMember: " : "") << "hi" << llendl;
return "ClassWithNoLogType::logFromMember";
}
static std::string logFromStatic(bool id)
{
llinfos << (id ? "ClassWithNoLogType::logFromStatic: " : "") << "hi" << llendl;
return "ClassWithNoLogType::logFromStatic";
}
};
class ClassWithLogType {
LOG_CLASS(ClassWithLogType);
public:
std::string logFromMember(bool id)
{
llinfos << (id ? "ClassWithLogType::logFromMember: " : "") << "hi" << llendl;
return "ClassWithLogType::logFromMember";
}
static std::string logFromStatic(bool id)
{
llinfos << (id ? "ClassWithLogType::logFromStatic: " : "") << "hi" << llendl;
return "ClassWithLogType::logFromStatic";
}
};
std::string logFromNamespace(bool id) { return Foo::logFromNamespace(id); }
std::string logFromClassWithNoLogTypeMember(bool id) { ClassWithNoLogType c; return c.logFromMember(id); }
std::string logFromClassWithNoLogTypeStatic(bool id) { return ClassWithNoLogType::logFromStatic(id); }
std::string logFromClassWithLogTypeMember(bool id) { ClassWithLogType c; return c.logFromMember(id); }
std::string logFromClassWithLogTypeStatic(bool id) { return ClassWithLogType::logFromStatic(id); }
void ensure_has(const std::string& message,
const std::string& actual, const std::string& expected)
{
std::string::size_type n1 = actual.find(expected);
if (n1 == std::string::npos)
{
std::stringstream ss;
ss << message << ": " << "expected to find a copy of " << expected
<< " in actual " << actual;
throw tut::failure(ss.str().c_str());
}
}
typedef std::string (*LogFromFunction)(bool);
void testLogName(TestRecorder& recorder, LogFromFunction f,
const std::string& class_name = "")
{
recorder.clearMessages();
std::string name = f(false);
f(true);
std::string messageWithoutName = recorder.message(0);
std::string messageWithName = recorder.message(1);
ensure_has(name + " logged without name",
messageWithoutName, name);
ensure_has(name + " logged with name",
messageWithName, name);
if (!class_name.empty())
{
ensure_has(name + "logged without name",
messageWithoutName, class_name);
ensure_has(name + "logged with name",
messageWithName, class_name);
}
}
}
namespace tut
{
template<> template<>
// class/function information in output
void ErrorTestObject::test<6>()
{
testLogName(mRecorder, logFromGlobal);
testLogName(mRecorder, logFromStatic);
testLogName(mRecorder, logFromAnon);
testLogName(mRecorder, logFromNamespace);
//testLogName(mRecorder, logFromClassWithNoLogTypeMember, "ClassWithNoLogType");
//testLogName(mRecorder, logFromClassWithNoLogTypeStatic, "ClassWithNoLogType");
// XXX: figure out what the exepcted response is for these
testLogName(mRecorder, logFromClassWithLogTypeMember, "ClassWithLogType");
testLogName(mRecorder, logFromClassWithLogTypeStatic, "ClassWithLogType");
}
}
namespace
{
std::string innerLogger()
{
llinfos << "inside" << llendl;
return "moo";
}
std::string outerLogger()
{
llinfos << "outside(" << innerLogger() << ")" << llendl;
return "bar";
}
void uberLogger()
{
llinfos << "uber(" << outerLogger() << "," << innerLogger() << ")" << llendl;
}
class LogWhileLogging
{
public:
void print(std::ostream& out) const
{
llinfos << "logging" << llendl;
out << "baz";
}
};
std::ostream& operator<<(std::ostream& out, const LogWhileLogging& l)
{ l.print(out); return out; }
void metaLogger()
{
LogWhileLogging l;
llinfos << "meta(" << l << ")" << llendl;
}
}
namespace tut
{
template<> template<>
// handle nested logging
void ErrorTestObject::test<7>()
{
outerLogger();
ensure_message_contains(0, "inside");
ensure_message_contains(1, "outside(moo)");
ensure_message_count(2);
uberLogger();
ensure_message_contains(2, "inside");
ensure_message_contains(3, "inside");
ensure_message_contains(4, "outside(moo)");
ensure_message_contains(5, "uber(bar,moo)");
ensure_message_count(6);
metaLogger();
ensure_message_contains(6, "logging");
ensure_message_contains(7, "meta(baz)");
ensure_message_count(8);
}
template<> template<>
// special handling of llerrs calls
void ErrorTestObject::test<8>()
{
LLError::setPrintLocation(false);
std::string location = errorReturningLocation();
ensure_message_contains(0, location + "error");
ensure_message_contains(1, "die");
ensure_message_count(2);
ensure("fatal callback called", fatalWasCalled);
}
}
namespace
{
std::string roswell()
{
return "1947-07-08T03:04:05Z";
}
void ufoSighting()
{
llinfos << "ufo" << llendl;
}
}
namespace tut
{
template<> template<>
// time in output (for recorders that need it)
void ErrorTestObject::test<9>()
{
LLError::setTimeFunction(roswell);
mRecorder.setWantsTime(false);
ufoSighting();
ensure_message_contains(0, "ufo");
ensure_message_does_not_contain(0, roswell());
mRecorder.setWantsTime(true);
ufoSighting();
ensure_message_contains(1, "ufo");
ensure_message_contains(1, roswell());
}
template<> template<>
// output order
void ErrorTestObject::test<10>()
{
LLError::setPrintLocation(true);
LLError::setTimeFunction(roswell);
mRecorder.setWantsTime(true);
std::string locationAndFunction = writeReturningLocationAndFunction();
ensure_equals("order is time type location function message",
mRecorder.message(0),
roswell() + " INFO: " + locationAndFunction + ": apple");
}
template<> template<>
// multiple recorders
void ErrorTestObject::test<11>()
{
TestRecorder altRecorder;
LLError::addRecorder(&altRecorder);
llinfos << "boo" << llendl;
ensure_message_contains(0, "boo");
ensure_equals("alt recorder count", altRecorder.countMessages(), 1);
ensure_contains("alt recorder message 0", altRecorder.message(0), "boo");
LLError::setTimeFunction(roswell);
TestRecorder anotherRecorder;
anotherRecorder.setWantsTime(true);
LLError::addRecorder(&anotherRecorder);
llinfos << "baz" << llendl;
std::string when = roswell();
ensure_message_does_not_contain(1, when);
ensure_equals("alt recorder count", altRecorder.countMessages(), 2);
ensure_does_not_contain("alt recorder message 1", altRecorder.message(1), when);
ensure_equals("another recorder count", anotherRecorder.countMessages(), 1);
ensure_contains("another recorder message 0", anotherRecorder.message(0), when);
}
}
class TestAlpha
{
LOG_CLASS(TestAlpha);
public:
static void doDebug() { lldebugs << "add dice" << llendl; }
static void doInfo() { llinfos << "any idea" << llendl; }
static void doWarn() { llwarns << "aim west" << llendl; }
static void doError() { llerrs << "ate eels" << llendl; }
static void doAll() { doDebug(); doInfo(); doWarn(); doError(); }
};
class TestBeta
{
LOG_CLASS(TestBeta);
public:
static void doDebug() { lldebugs << "bed down" << llendl; }
static void doInfo() { llinfos << "buy iron" << llendl; }
static void doWarn() { llwarns << "bad word" << llendl; }
static void doError() { llerrs << "big easy" << llendl; }
static void doAll() { doDebug(); doInfo(); doWarn(); doError(); }
};
namespace tut
{
template<> template<>
// filtering by class
void ErrorTestObject::test<12>()
{
LLError::setDefaultLevel(LLError::LEVEL_WARN);
LLError::setClassLevel("TestBeta", LLError::LEVEL_INFO);
TestAlpha::doAll();
TestBeta::doAll();
ensure_message_contains(0, "aim west");
ensure_message_contains(1, "error");
ensure_message_contains(2, "ate eels");
ensure_message_contains(3, "buy iron");
ensure_message_contains(4, "bad word");
ensure_message_contains(5, "error");
ensure_message_contains(6, "big easy");
ensure_message_count(7);
}
template<> template<>
// filtering by function, and that it will override class filtering
void ErrorTestObject::test<13>()
{
LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
LLError::setClassLevel("TestBeta", LLError::LEVEL_WARN);
LLError::setFunctionLevel("TestBeta::doInfo", LLError::LEVEL_DEBUG);
LLError::setFunctionLevel("TestBeta::doError", LLError::LEVEL_NONE);
TestBeta::doAll();
ensure_message_contains(0, "buy iron");
ensure_message_contains(1, "bad word");
ensure_message_count(2);
}
template<> template<>
// filtering by file
// and that it is overridden by both class and function filtering
void ErrorTestObject::test<14>()
{
LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
LLError::setFileLevel(LLError::abbreviateFile(__FILE__),
LLError::LEVEL_WARN);
LLError::setClassLevel("TestAlpha", LLError::LEVEL_INFO);
LLError::setFunctionLevel("TestAlpha::doError",
LLError::LEVEL_NONE);
LLError::setFunctionLevel("TestBeta::doError",
LLError::LEVEL_NONE);
TestAlpha::doAll();
TestBeta::doAll();
ensure_message_contains(0, "any idea");
ensure_message_contains(1, "aim west");
ensure_message_contains(2, "bad word");
ensure_message_count(3);
}
template<> template<>
// proper cached, efficient lookup of filtering
void ErrorTestObject::test<15>()
{
LLError::setDefaultLevel(LLError::LEVEL_NONE);
TestAlpha::doInfo();
ensure_message_count(0);
ensure_equals("first check", LLError::shouldLogCallCount(), 1);
TestAlpha::doInfo();
ensure_message_count(0);
ensure_equals("second check", LLError::shouldLogCallCount(), 1);
LLError::setClassLevel("TestAlpha", LLError::LEVEL_DEBUG);
TestAlpha::doInfo();
ensure_message_count(1);
ensure_equals("third check", LLError::shouldLogCallCount(), 2);
TestAlpha::doInfo();
ensure_message_count(2);
ensure_equals("fourth check", LLError::shouldLogCallCount(), 2);
LLError::setClassLevel("TestAlpha", LLError::LEVEL_WARN);
TestAlpha::doInfo();
ensure_message_count(2);
ensure_equals("fifth check", LLError::shouldLogCallCount(), 3);
TestAlpha::doInfo();
ensure_message_count(2);
ensure_equals("sixth check", LLError::shouldLogCallCount(), 3);
}
template<> template<>
// configuration from LLSD
void ErrorTestObject::test<16>()
{
std::string this_file = LLError::abbreviateFile(__FILE__);
LLSD config;
config["print-location"] = true;
config["default-level"] = "DEBUG";
LLSD set1;
set1["level"] = "WARN";
set1["files"][0] = this_file;
LLSD set2;
set2["level"] = "INFO";
set2["classes"][0] = "TestAlpha";
LLSD set3;
set3["level"] = "NONE";
set3["functions"][0] = "TestAlpha::doError";
set3["functions"][1] = "TestBeta::doError";
config["settings"][0] = set1;
config["settings"][1] = set2;
config["settings"][2] = set3;
LLError::configure(config);
TestAlpha::doAll();
TestBeta::doAll();
ensure_message_contains(0, "any idea");
ensure_message_contains(0, this_file);
ensure_message_contains(1, "aim west");
ensure_message_contains(2, "bad word");
ensure_message_count(3);
// make sure reconfiguring works
LLSD config2;
config2["default-level"] = "WARN";
LLError::configure(config2);
TestAlpha::doAll();
TestBeta::doAll();
ensure_message_contains(3, "aim west");
ensure_message_does_not_contain(3, this_file);
ensure_message_contains(4, "error");
ensure_message_contains(5, "ate eels");
ensure_message_contains(6, "bad word");
ensure_message_contains(7, "error");
ensure_message_contains(8, "big easy");
ensure_message_count(9);
}
}
/* Tests left:
handling of classes without LOG_CLASS
live update of filtering from file
syslog recorder
file recorder
cerr/stderr recorder
fixed buffer recorder
windows recorder
mutex use when logging (?)
strange careful about to crash handling (?)
*/

232
indra/test/llhost_tut.cpp Normal file
View File

@@ -0,0 +1,232 @@
/**
* @file llhost_tut.cpp
* @author Adroit
* @date 2007-02
* @brief llhost test cases.
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "lltut.h"
#include "llhost.h"
namespace tut
{
struct host_data
{
};
typedef test_group<host_data> host_test;
typedef host_test::object host_object;
tut::host_test host_testcase("llhost");
template<> template<>
void host_object::test<1>()
{
LLHost host;
ensure("IP address is not NULL", (0 == host.getAddress()) && (0 == host.getPort()) && !host.isOk());
}
template<> template<>
void host_object::test<2>()
{
U32 ip_addr = 0xc098017d;
U32 port = 8080;
LLHost host(ip_addr, port);
ensure("IP address is invalid", ip_addr == host.getAddress());
ensure("Port Number is invalid", port == host.getPort());
ensure("IP address and port number both should be ok", host.isOk());
}
template<> template<>
void host_object::test<3>()
{
const char* str = "192.168.1.1";
U32 port = 8080;
LLHost host(str, port);
ensure("IP address could not be processed", (host.getAddress() == ip_string_to_u32(str)));
ensure("Port Number is invalid", (port == host.getPort()));
}
template<> template<>
void host_object::test<4>()
{
U32 ip = ip_string_to_u32("192.168.1.1");
U32 port = 22;
U64 ip_port = (((U64) ip) << 32) | port;
LLHost host(ip_port);
ensure("IP address is invalid", ip == host.getAddress());
ensure("Port Number is invalid", port == host.getPort());
}
template<> template<>
void host_object::test<5>()
{
std::string ip_port_string = "192.168.1.1:8080";
U32 ip = ip_string_to_u32("192.168.1.1");
U32 port = 8080;
LLHost host(ip_port_string);
ensure("IP address from IP:port is invalid", ip == host.getAddress());
ensure("Port Number from from IP:port is invalid", port == host.getPort());
}
template<> template<>
void host_object::test<6>()
{
U32 ip = 0xc098017d, port = 8080;
LLHost host;
host.set(ip,port);
ensure("IP address is invalid", (ip == host.getAddress()));
ensure("Port Number is invalid", (port == host.getPort()));
}
template<> template<>
void host_object::test<7>()
{
const char* str = "192.168.1.1";
U32 port = 8080, ip;
LLHost host;
host.set(str,port);
ip = ip_string_to_u32(str);
ensure("IP address is invalid", (ip == host.getAddress()));
ensure("Port Number is invalid", (port == host.getPort()));
str = "64.233.187.99";
ip = ip_string_to_u32(str);
host.setAddress(str);
ensure("IP address is invalid", (ip == host.getAddress()));
ip = 0xc098017b;
host.setAddress(ip);
ensure("IP address is invalid", (ip == host.getAddress()));
// should still use the old port
ensure("Port Number is invalid", (port == host.getPort()));
port = 8084;
host.setPort(port);
ensure("Port Number is invalid", (port == host.getPort()));
// should still use the old address
ensure("IP address is invalid", (ip == host.getAddress()));
}
template<> template<>
void host_object::test<8>()
{
const std::string str("192.168.1.1");
U32 port = 8080;
LLHost host;
host.set(str,port);
std::string ip_string = host.getIPString();
ensure("Function Failed", (ip_string == str));
std::string ip_string_port = host.getIPandPort();
ensure("Function Failed", (ip_string_port == "192.168.1.1:8080"));
}
// getHostName() and setHostByName
template<> template<>
void host_object::test<9>()
{
std::string hostStr = "google.com";
LLHost host;
host.setHostByName(hostStr);
// reverse DNS will likely result in appending of some
// sub-domain to the main hostname. so look for
// the main domain name and not do the exact compare
std::string hostname = host.getHostName();
ensure("getHostName failed", hostname.find(hostStr) != std::string::npos);
}
// setHostByName for dotted IP
template<> template<>
void host_object::test<10>()
{
std::string hostStr = "64.233.167.99";
LLHost host;
host.setHostByName(hostStr);
ensure("SetHostByName for dotted IP Address failed", host.getAddress() == ip_string_to_u32(hostStr.c_str()));
}
template<> template<>
void host_object::test<11>()
{
LLHost host1(0xc098017d, 8080);
LLHost host2 = host1;
ensure("Both IP addresses are not same", (host1.getAddress() == host2.getAddress()));
ensure("Both port numbers are not same", (host1.getPort() == host2.getPort()));
}
template<> template<>
void host_object::test<12>()
{
LLHost host1("192.168.1.1", 8080);
std::string str1 = "192.168.1.1:8080";
std::ostringstream stream;
stream << host1;
ensure("Operator << failed", ( stream.str()== str1));
// There is no istream >> llhost operator.
//std::istringstream is(stream.str());
//LLHost host2;
//is >> host2;
//ensure("Operator >> failed. Not compatible with <<", host1 == host2);
}
// operators ==, !=, <
template<> template<>
void host_object::test<13>()
{
U32 ip_addr = 0xc098017d;
U32 port = 8080;
LLHost host1(ip_addr, port);
LLHost host2(ip_addr, port);
ensure("operator== failed", host1 == host2);
// change port
host2.setPort(7070);
ensure("operator!= failed", host1 != host2);
// set port back to 8080 and change IP address now
host2.setPort(8080);
host2.setAddress(ip_addr+10);
ensure("operator!= failed", host1 != host2);
ensure("operator< failed", host1 < host2);
// set IP address back to same value and change port
host2.setAddress(ip_addr);
host2.setPort(host1.getPort() + 10);
ensure("operator< failed", host1 < host2);
}
}

View File

@@ -0,0 +1,385 @@
/**
* @file llhttpclient_tut.cpp
* @brief Testing the HTTP client classes.
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
/**
*
* These classes test the HTTP client framework.
*
*/
#include <tut/tut.hpp>
#include "linden_common.h"
// These are too slow on Windows to actually include in the build. JC
#if !LL_WINDOWS
#include "lltut.h"
#include "llhttpclient.h"
#include "llformat.h"
#include "llpipeutil.h"
#include "llpumpio.h"
#include "llsdhttpserver.h"
#include "lliohttpserver.h"
#include "lliosocket.h"
namespace tut
{
LLSD storage;
class LLSDStorageNode : public LLHTTPNode
{
public:
LLSD get() const { return storage; }
LLSD put(const LLSD& value) const { storage = value; return LLSD(); }
};
class ErrorNode : public LLHTTPNode
{
public:
void get(ResponsePtr r, const LLSD& context) const
{ r->status(599, "Intentional error"); }
void post(ResponsePtr r, const LLSD& context, const LLSD& input) const
{ r->status(input["status"], input["reason"]); }
};
class TimeOutNode : public LLHTTPNode
{
public:
void get(ResponsePtr r, const LLSD& context) const
{
/* do nothing, the request will eventually time out */
}
};
LLHTTPRegistration<LLSDStorageNode> gStorageNode("/test/storage");
LLHTTPRegistration<ErrorNode> gErrorNode("/test/error");
LLHTTPRegistration<TimeOutNode> gTimeOutNode("/test/timeout");
struct HTTPClientTestData
{
public:
HTTPClientTestData()
{
apr_pool_create(&mPool, NULL);
mServerPump = new LLPumpIO(mPool);
mClientPump = new LLPumpIO(mPool);
LLHTTPClient::setPump(*mClientPump);
}
~HTTPClientTestData()
{
delete mServerPump;
delete mClientPump;
apr_pool_destroy(mPool);
}
void setupTheServer()
{
LLHTTPNode& root = LLIOHTTPServer::create(mPool, *mServerPump, 8888);
LLHTTPStandardServices::useServices();
LLHTTPRegistrar::buildAllServices(root);
}
void runThePump(float timeout = 100.0f)
{
LLTimer timer;
timer.setTimerExpirySec(timeout);
while(!mSawCompleted && !mSawCompletedHeader && !timer.hasExpired())
{
if (mServerPump)
{
mServerPump->pump();
mServerPump->callback();
}
if (mClientPump)
{
mClientPump->pump();
mClientPump->callback();
}
}
}
void killServer()
{
delete mServerPump;
mServerPump = NULL;
}
private:
apr_pool_t* mPool;
LLPumpIO* mServerPump;
LLPumpIO* mClientPump;
protected:
void ensureStatusOK()
{
if (mSawError)
{
std::string msg =
llformat("error() called when not expected, status %d",
mStatus);
fail(msg);
}
}
void ensureStatusError()
{
if (!mSawError)
{
fail("error() wasn't called");
}
}
LLSD getResult()
{
return mResult;
}
LLSD getHeader()
{
return mHeader;
}
protected:
bool mSawError;
U32 mStatus;
std::string mReason;
bool mSawCompleted;
bool mSawCompletedHeader;
LLSD mResult;
LLSD mHeader;
bool mResultDeleted;
class Result : public LLHTTPClient::Responder
{
protected:
Result(HTTPClientTestData& client)
: mClient(client)
{
}
public:
static boost::intrusive_ptr<Result> build(HTTPClientTestData& client)
{
return boost::intrusive_ptr<Result>(new Result(client));
}
~Result()
{
mClient.mResultDeleted = true;
}
virtual void error(U32 status, const std::string& reason)
{
mClient.mSawError = true;
mClient.mStatus = status;
mClient.mReason = reason;
}
virtual void result(const LLSD& content)
{
mClient.mResult = content;
}
virtual void completed(
U32 status, const std::string& reason,
const LLSD& content)
{
LLHTTPClient::Responder::completed(status, reason, content);
mClient.mSawCompleted = true;
}
virtual void completedHeader(
U32 status, const std::string& reason,
const LLSD& content)
{
mClient.mHeader = content;
mClient.mSawCompletedHeader = true;
}
private:
HTTPClientTestData& mClient;
};
friend class Result;
protected:
LLHTTPClient::ResponderPtr newResult()
{
mSawError = false;
mStatus = 0;
mSawCompleted = false;
mSawCompletedHeader = false;
mResult.clear();
mHeader.clear();
mResultDeleted = false;
return Result::build(*this);
}
};
typedef test_group<HTTPClientTestData> HTTPClientTestGroup;
typedef HTTPClientTestGroup::object HTTPClientTestObject;
HTTPClientTestGroup httpClientTestGroup("http_client");
template<> template<>
void HTTPClientTestObject::test<1>()
{
LLHTTPClient::get("http://www.google.com/", newResult());
runThePump();
ensureStatusOK();
ensure("result object wasn't destroyed", mResultDeleted);
}
template<> template<>
void HTTPClientTestObject::test<2>()
{
LLHTTPClient::get("http://www.invalid", newResult());
runThePump();
ensureStatusError();
}
template<> template<>
void HTTPClientTestObject::test<3>()
{
LLSD sd;
sd["list"][0]["one"] = 1;
sd["list"][0]["two"] = 2;
sd["list"][1]["three"] = 3;
sd["list"][1]["four"] = 4;
setupTheServer();
LLHTTPClient::post("http://localhost:8888/web/echo", sd, newResult());
runThePump();
ensureStatusOK();
ensure_equals("echoed result matches", getResult(), sd);
}
template<> template<>
void HTTPClientTestObject::test<4>()
{
LLSD sd;
sd["message"] = "This is my test message.";
setupTheServer();
LLHTTPClient::put("http://localhost:8888/test/storage", sd, newResult());
runThePump();
ensureStatusOK();
LLHTTPClient::get("http://localhost:8888/test/storage", newResult());
runThePump();
ensureStatusOK();
ensure_equals("echoed result matches", getResult(), sd);
}
template<> template<>
void HTTPClientTestObject::test<5>()
{
LLSD sd;
sd["status"] = 543;
sd["reason"] = "error for testing";
setupTheServer();
LLHTTPClient::post("http://localhost:8888/test/error", sd, newResult());
runThePump();
ensureStatusError();
ensure_contains("reason", mReason, sd["reason"]);
}
template<> template<>
void HTTPClientTestObject::test<6>()
{
setupTheServer();
LLHTTPClient::get("http://localhost:8888/test/timeout", newResult());
runThePump(1.0f);
killServer();
runThePump();
ensureStatusError();
ensure_equals("reason", mReason, "STATUS_ERROR");
}
template<> template<>
void HTTPClientTestObject::test<7>()
{
// Can not use the little mini server. The blocking request
// won't ever let it run. Instead get from a known LLSD
// source and compare results with the non-blocking get which
// is tested against the mini server earlier.
skip("secondlife.com is not reliable enough for unit tests.");
LLSD expected;
LLHTTPClient::get("http://secondlife.com/xmlhttp/homepage.php", newResult());
runThePump();
ensureStatusOK();
expected = getResult();
LLSD result;
result = LLHTTPClient::blockingGet("http://secondlife.com/xmlhttp/homepage.php");
LLSD body = result["body"];
ensure_equals("echoed result matches", body.size(), expected.size());
}
template<> template<>
void HTTPClientTestObject::test<8>()
{
// This is testing for the presence of the Header in the returned results
// from an HTTP::get call.
LLHTTPClient::get("http://www.google.com/", newResult());
runThePump();
ensureStatusOK();
LLSD header = getHeader();
ensure_equals("got a header", header.emptyMap().asBoolean(), FALSE);
}
template<> template<>
void HTTPClientTestObject::test<9>()
{
LLHTTPClient::head("http://www.google.com/", newResult());
runThePump();
ensureStatusOK();
ensure("result object wasn't destroyed", mResultDeleted);
}
}
#endif // !LL_WINDOWS

View File

@@ -0,0 +1,94 @@
/**
* @file llhttpdate_tut.cpp
* @author Kartic Krishnamurthy
* @date Wednesday, 18 Jul 2007 17:00:00 GMT :)
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "lltut.h"
#include "lldate.h"
#include "llframetimer.h"
namespace tut
{
struct httpdate_data
{
LLDate some_date;
};
typedef test_group<httpdate_data> httpdate_test;
typedef httpdate_test::object httpdate_object;
tut::httpdate_test httpdate("httpdate");
template<> template<>
void httpdate_object::test<1>()
{
static std::string epoch_expected = "Thursday, 01 Jan 1970 00:00:00 GMT" ;
ensure("Check Epoch in RFC 1123", ( epoch_expected == some_date.asRFC1123()));
}
template<> template<>
void httpdate_object::test<2>()
{
static std::string expected = "Wednesday, 18 Jul 2007 22:17:24 GMT" ;
some_date = LLDate(1184797044.037586);
ensure("Check some timestamp in RFC 1123", ( expected == some_date.asRFC1123()));
}
// This test of course most generic.. runs off current time
template<> template<>
void httpdate_object::test<3>()
{
//F64 sometime = LLFrameTimer::getTotalSeconds();
time_t sometime;
time(&sometime);
some_date = LLDate((F64) sometime);
struct tm *result;
char expected[255];
std::string actual;
result = gmtime(&sometime);
/*
std::cout << " seconds: "<< result->tm_sec
<< ", minutes: " << result->tm_min
<< ", hours: " << result->tm_hour
<< ", day of the month: " << result->tm_mday
<< ", month: " << result->tm_mon
<< ", year: " << result->tm_year
<< ", day of the week: " << result->tm_wday
<< ", day in the year: " << result->tm_yday
<< ", DST: " << result->tm_isdst << std::endl;
*/
strftime(expected, 255, "%A, %d %b %Y %H:%M:%S GMT", result);
actual = some_date.asRFC1123();
// probably not a good idea to use strcmp but this is just a unit test
ensure("Current time in RFC 1123", (strcmp(expected, actual.c_str()) == 0));
}
}

View File

@@ -0,0 +1,433 @@
/**
* @file lliohttpnode_tut.cpp
* @date May 2006
* @brief HTTP server unit tests
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "lltut.h"
#include "llhttpnode.h"
#include "llsdhttpserver.h"
namespace tut
{
struct HTTPNodeTestData
{
LLHTTPNode mRoot;
LLSD mContext;
const LLSD& context() { return mContext; }
std::string remainderPath()
{
std::ostringstream pathOutput;
bool addSlash = false;
LLSD& remainder = mContext["request"]["remainder"];
for (LLSD::array_const_iterator i = remainder.beginArray();
i != remainder.endArray();
++i)
{
if (addSlash) { pathOutput << '/'; }
pathOutput << i->asString();
addSlash = true;
}
return pathOutput.str();
}
void ensureRootTraversal(const std::string& path,
const LLHTTPNode* expectedNode,
const char* expectedRemainder)
{
mContext.clear();
const LLHTTPNode* actualNode = mRoot.traverse(path, mContext);
ensure_equals("traverse " + path + " node",
actualNode, expectedNode);
ensure_equals("traverse " + path + " remainder",
remainderPath(), expectedRemainder);
}
class Response : public LLHTTPNode::Response
{
public:
static LLPointer<Response> create() {return new Response();}
LLSD mResult;
void result(const LLSD& result) { mResult = result; }
void status(S32 code, const std::string& message) { }
void extendedResult(S32 code, const std::string& message, const LLSD& headers) { }
private:
Response() {;} // Must be accessed through LLPointer.
};
typedef LLPointer<Response> ResponsePtr;
LLSD get(const std::string& path)
{
mContext.clear();
const LLHTTPNode* node = mRoot.traverse(path, mContext);
ensure(path + " found", node != NULL);
ResponsePtr response = Response::create();
node->get(LLHTTPNode::ResponsePtr(response), mContext);
return response->mResult;
}
LLSD post(const std::string& path, const LLSD& input)
{
mContext.clear();
const LLHTTPNode* node = mRoot.traverse(path, mContext);
ensure(path + " found", node != NULL);
ResponsePtr response = Response::create();
node->post(LLHTTPNode::ResponsePtr(response), mContext, input);
return response->mResult;
}
void ensureMemberString(const std::string& name,
const LLSD& actualMap, const std::string& member,
const std::string& expectedValue)
{
ensure_equals(name + " " + member,
actualMap[member].asString(), expectedValue);
}
void ensureInArray(const LLSD& actualArray,
const std::string& expectedValue)
{
LLSD::array_const_iterator i = actualArray.beginArray();
LLSD::array_const_iterator end = actualArray.endArray();
for (; i != end; ++i)
{
std::string path = i->asString();
if (path == expectedValue)
{
return;
}
}
fail("didn't find " + expectedValue);
}
};
typedef test_group<HTTPNodeTestData> HTTPNodeTestGroup;
typedef HTTPNodeTestGroup::object HTTPNodeTestObject;
HTTPNodeTestGroup httpNodeTestGroup("http node");
template<> template<>
void HTTPNodeTestObject::test<1>()
{
// traversal of the lone node
ensureRootTraversal("", &mRoot, "");
ensureRootTraversal("/", &mRoot, "");
ensureRootTraversal("foo", NULL, "foo");
ensureRootTraversal("foo/bar", NULL, "foo/bar");
ensure_equals("root of root", mRoot.rootNode(), &mRoot);
}
template<> template<>
void HTTPNodeTestObject::test<2>()
{
// simple traversal of a single node
LLHTTPNode* helloNode = new LLHTTPNode;
mRoot.addNode("hello", helloNode);
ensureRootTraversal("hello", helloNode, "");
ensureRootTraversal("/hello", helloNode, "");
ensureRootTraversal("hello/", helloNode, "");
ensureRootTraversal("/hello/", helloNode, "");
ensureRootTraversal("hello/there", NULL, "there");
ensure_equals("root of hello", helloNode->rootNode(), &mRoot);
}
template<> template<>
void HTTPNodeTestObject::test<3>()
{
// traversal of mutli-branched tree
LLHTTPNode* greekNode = new LLHTTPNode;
LLHTTPNode* alphaNode = new LLHTTPNode;
LLHTTPNode* betaNode = new LLHTTPNode;
LLHTTPNode* gammaNode = new LLHTTPNode;
greekNode->addNode("alpha", alphaNode);
greekNode->addNode("beta", betaNode);
greekNode->addNode("gamma", gammaNode);
mRoot.addNode("greek", greekNode);
LLHTTPNode* hebrewNode = new LLHTTPNode;
LLHTTPNode* alephNode = new LLHTTPNode;
hebrewNode->addNode("aleph", alephNode);
mRoot.addNode("hebrew", hebrewNode);
ensureRootTraversal("greek/alpha", alphaNode, "");
ensureRootTraversal("greek/beta", betaNode, "");
ensureRootTraversal("greek/delta", NULL, "delta");
ensureRootTraversal("greek/gamma", gammaNode, "");
ensureRootTraversal("hebrew/aleph", alephNode, "");
ensure_equals("root of greek", greekNode->rootNode(), &mRoot);
ensure_equals("root of alpha", alphaNode->rootNode(), &mRoot);
ensure_equals("root of beta", betaNode->rootNode(), &mRoot);
ensure_equals("root of gamma", gammaNode->rootNode(), &mRoot);
ensure_equals("root of hebrew", hebrewNode->rootNode(), &mRoot);
ensure_equals("root of aleph", alephNode->rootNode(), &mRoot);
}
template<> template<>
void HTTPNodeTestObject::test<4>()
{
// automatic creation of parent nodes and not overriding existing nodes
LLHTTPNode* alphaNode = new LLHTTPNode;
LLHTTPNode* betaNode = new LLHTTPNode;
LLHTTPNode* gammaNode = new LLHTTPNode;
LLHTTPNode* gamma2Node = new LLHTTPNode;
mRoot.addNode("greek/alpha", alphaNode);
mRoot.addNode("greek/beta", betaNode);
mRoot.addNode("greek/gamma", gammaNode);
mRoot.addNode("greek/gamma", gamma2Node);
LLHTTPNode* alephNode = new LLHTTPNode;
mRoot.addNode("hebrew/aleph", alephNode);
ensureRootTraversal("greek/alpha", alphaNode, "");
ensureRootTraversal("greek/beta", betaNode, "");
ensureRootTraversal("greek/delta", NULL, "delta");
ensureRootTraversal("greek/gamma", gammaNode, "");
ensureRootTraversal("hebrew/aleph", alephNode, "");
ensure_equals("root of alpha", alphaNode->rootNode(), &mRoot);
ensure_equals("root of beta", betaNode->rootNode(), &mRoot);
ensure_equals("root of gamma", gammaNode->rootNode(), &mRoot);
ensure_equals("root of aleph", alephNode->rootNode(), &mRoot);
}
class IntegerNode : public LLHTTPNode
{
public:
virtual void get(ResponsePtr response, const LLSD& context) const
{
int n = context["extra"]["value"];
LLSD info;
info["value"] = n;
info["positive"] = n > 0;
info["zero"] = n == 0;
info["negative"] = n < 0;
response->result(info);
}
virtual bool validate(const std::string& name, LLSD& context) const
{
int n;
std::istringstream i_stream(name);
i_stream >> n;
if (i_stream.fail() || i_stream.get() != EOF)
{
return false;
}
context["extra"]["value"] = n;
return true;
}
};
class SquareNode : public LLHTTPNode
{
public:
virtual void get(ResponsePtr response, const LLSD& context) const
{
int n = context["extra"]["value"];
response->result(n*n);
}
};
template<> template<>
void HTTPNodeTestObject::test<5>()
{
// wildcard nodes
LLHTTPNode* miscNode = new LLHTTPNode;
LLHTTPNode* iNode = new IntegerNode;
LLHTTPNode* sqNode = new SquareNode;
mRoot.addNode("test/misc", miscNode);
mRoot.addNode("test/<int>", iNode);
mRoot.addNode("test/<int>/square", sqNode);
ensureRootTraversal("test/42", iNode, "");
ensure_equals("stored integer",
context()["extra"]["value"].asInteger(), 42);
ensureRootTraversal("test/bob", NULL, "bob");
ensure("nothing stored",
context()["extra"]["value"].isUndefined());
ensureRootTraversal("test/3/square", sqNode, "");
ResponsePtr response = Response::create();
sqNode->get(LLHTTPNode::ResponsePtr(response), context());
ensure_equals("square result", response->mResult.asInteger(), 9);
}
class AlphaNode : public LLHTTPNode
{
public:
virtual bool handles(const LLSD& remainder, LLSD& context) const
{
LLSD::array_const_iterator i = remainder.beginArray();
LLSD::array_const_iterator end = remainder.endArray();
for (; i != end; ++i)
{
std::string s = i->asString();
if (s.empty() || s[0] != 'a')
{
return false;
}
}
return true;
}
};
template<> template<>
void HTTPNodeTestObject::test<6>()
{
// nodes that handle remainders
LLHTTPNode* miscNode = new LLHTTPNode;
LLHTTPNode* aNode = new AlphaNode;
LLHTTPNode* zNode = new LLHTTPNode;
mRoot.addNode("test/misc", miscNode);
mRoot.addNode("test/alpha", aNode);
mRoot.addNode("test/alpha/zebra", zNode);
ensureRootTraversal("test/alpha", aNode, "");
ensureRootTraversal("test/alpha/abe", aNode, "abe");
ensureRootTraversal("test/alpha/abe/amy", aNode, "abe/amy");
ensureRootTraversal("test/alpha/abe/bea", NULL, "abe/bea");
ensureRootTraversal("test/alpha/bob", NULL, "bob");
ensureRootTraversal("test/alpha/zebra", zNode, "");
}
template<> template<>
void HTTPNodeTestObject::test<7>()
{
// test auto registration
LLHTTPStandardServices::useServices();
LLHTTPRegistrar::buildAllServices(mRoot);
{
LLSD result = get("web/hello");
ensure_equals("hello result", result.asString(), "hello");
}
{
LLSD stuff = 3.14159;
LLSD result = post("web/echo", stuff);
ensure_equals("echo result", result, stuff);
}
}
template<> template<>
void HTTPNodeTestObject::test<8>()
{
// test introspection
LLHTTPRegistrar::buildAllServices(mRoot);
mRoot.addNode("test/misc", new LLHTTPNode);
mRoot.addNode("test/<int>", new IntegerNode);
mRoot.addNode("test/<int>/square", new SquareNode);
const LLSD result = get("web/server/api");
ensure("result is array", result.isArray());
ensure("result size", result.size() >= 2);
ensureInArray(result, "web/echo");
ensureInArray(result, "web/hello");
ensureInArray(result, "test/misc");
ensureInArray(result, "test/<int>");
ensureInArray(result, "test/<int>/square");
}
template<> template<>
void HTTPNodeTestObject::test<9>()
{
// test introspection details
LLHTTPRegistrar::buildAllServices(mRoot);
const LLSD helloDetails = get("web/server/api/web/hello");
ensure_contains("hello description",
helloDetails["description"].asString(), "hello");
ensure_equals("method name", helloDetails["api"][0].asString(), std::string("GET"));
ensureMemberString("hello", helloDetails, "output", "\"hello\"");
ensure_contains("hello __file__",
helloDetails["__file__"].asString(), "llsdhttpserver.cpp");
ensure("hello line", helloDetails["__line__"].isInteger());
const LLSD echoDetails = get("web/server/api/web/echo");
ensure_contains("echo description",
echoDetails["description"].asString(), "echo");
ensure_equals("method name", echoDetails["api"][0].asString(), std::string("POST"));
ensureMemberString("echo", echoDetails, "input", "<any>");
ensureMemberString("echo", echoDetails, "output", "<the input>");
ensure_contains("echo __file__",
echoDetails["__file__"].asString(), "llsdhttpserver.cpp");
ensure("echo", echoDetails["__line__"].isInteger());
}
}

View File

@@ -0,0 +1,74 @@
/**
* @file llinventoryparcel_tut.cpp
* @author Moss
* @date 2007-04-17
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "lltut.h"
#include "llparcel.h"
#include <string>
namespace tut
{
struct llinventoryparcel_data
{
};
typedef test_group<llinventoryparcel_data> llinventoryparcel_test;
typedef llinventoryparcel_test::object llinventoryparcel_object;
tut::llinventoryparcel_test llinventoryparcel("llinventoryparcel");
template<> template<>
void llinventoryparcel_object::test<1>()
{
for (S32 i=0; i<LLParcel::C_COUNT; ++i)
{
const std::string& catstring = LLParcel::getCategoryString(LLParcel::ECategory(i));
ensure("LLParcel::getCategoryString(i)",
!catstring.empty());
const std::string& catuistring = LLParcel::getCategoryUIString(LLParcel::ECategory(i));
ensure("LLParcel::getCategoryUIString(i)",
!catuistring.empty());
ensure_equals("LLParcel::ECategory mapping of string back to enum", LLParcel::getCategoryFromString(catstring), i);
ensure_equals("LLParcel::ECategory mapping of uistring back to enum", LLParcel::getCategoryFromUIString(catuistring), i);
}
// test the C_ANY case, which has to work for UI strings
const std::string& catuistring = LLParcel::getCategoryUIString(LLParcel::C_ANY);
ensure("LLParcel::getCategoryUIString(C_ANY)",
!catuistring.empty());
ensure_equals("LLParcel::ECategory mapping of uistring back to enum", LLParcel::getCategoryFromUIString(catuistring), LLParcel::C_ANY);
}
}

View File

@@ -0,0 +1,351 @@
/**
* @file lliohttpserver_tut.cpp
* @date May 2006
* @brief HTTP server unit tests
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "lltut.h"
#include "llbufferstream.h"
#include "lliohttpserver.h"
#include "llsdhttpserver.h"
#include "llsdserialize.h"
#include "llpipeutil.h"
namespace tut
{
class HTTPServiceTestData
{
public:
class DelayedEcho : public LLHTTPNode
{
HTTPServiceTestData* mTester;
public:
DelayedEcho(HTTPServiceTestData* tester) : mTester(tester) { }
void post(ResponsePtr response, const LLSD& context, const LLSD& input) const
{
ensure("response already set", mTester->mResponse == ResponsePtr(NULL));
mTester->mResponse = response;
mTester->mResult = input;
}
};
class WireHello : public LLIOPipe
{
protected:
virtual EStatus process_impl(
const LLChannelDescriptors& channels,
buffer_ptr_t& buffer,
bool& eos,
LLSD& context,
LLPumpIO* pump)
{
if(!eos) return STATUS_BREAK;
LLSD sd = "yo!";
LLBufferStream ostr(channels, buffer.get());
ostr << LLSDXMLStreamer(sd);
return STATUS_DONE;
}
};
HTTPServiceTestData()
: mResponse(NULL)
{
LLHTTPStandardServices::useServices();
LLHTTPRegistrar::buildAllServices(mRoot);
mRoot.addNode("/delayed/echo", new DelayedEcho(this));
mRoot.addNode("/wire/hello", new LLHTTPNodeForPipe<WireHello>);
}
LLHTTPNode mRoot;
LLHTTPNode::ResponsePtr mResponse;
LLSD mResult;
void pumpPipe(LLPumpIO* pump, S32 iterations)
{
while(iterations > 0)
{
pump->pump();
pump->callback();
--iterations;
}
}
std::string makeRequest(
const std::string& name,
const std::string& httpRequest,
bool timeout = false)
{
LLPipeStringInjector* injector = new LLPipeStringInjector(httpRequest);
LLPipeStringExtractor* extractor = new LLPipeStringExtractor();
apr_pool_t* pool;
apr_pool_create(&pool, NULL);
LLPumpIO* pump;
pump = new LLPumpIO(pool);
LLPumpIO::chain_t chain;
LLSD context;
chain.push_back(LLIOPipe::ptr_t(injector));
LLIOHTTPServer::createPipe(chain, mRoot, LLSD());
chain.push_back(LLIOPipe::ptr_t(extractor));
pump->addChain(chain, DEFAULT_CHAIN_EXPIRY_SECS);
pumpPipe(pump, 10);
if(mResponse.notNull() && (! timeout))
{
mResponse->result(mResult);
mResponse = NULL;
}
pumpPipe(pump, 10);
std::string httpResult = extractor->string();
chain.clear();
delete pump;
apr_pool_destroy(pool);
if(mResponse.notNull() && timeout)
{
mResponse->result(mResult);
mResponse = NULL;
}
return httpResult;
}
std::string httpGET(const std::string& uri,
bool timeout = false)
{
std::string httpRequest = "GET " + uri + " HTTP/1.0\r\n\r\n";
return makeRequest(uri, httpRequest, timeout);
}
std::string httpPOST(const std::string& uri,
const std::string& body,
bool timeout,
const std::string& evilExtra = "")
{
std::ostringstream httpRequest;
httpRequest << "POST " + uri + " HTTP/1.0\r\n";
httpRequest << "Content-Length: " << body.size() << "\r\n";
httpRequest << "\r\n";
httpRequest << body;
httpRequest << evilExtra;
return makeRequest(uri, httpRequest.str(), timeout);
}
std::string httpPOST(const std::string& uri,
const std::string& body,
const std::string& evilExtra = "")
{
bool timeout = false;
return httpPOST(uri, body, timeout, evilExtra);
}
};
typedef test_group<HTTPServiceTestData> HTTPServiceTestGroup;
typedef HTTPServiceTestGroup::object HTTPServiceTestObject;
HTTPServiceTestGroup httpServiceTestGroup("http service");
template<> template<>
void HTTPServiceTestObject::test<1>()
{
std::string result = httpGET("web/hello");
ensure_starts_with("web/hello status", result,
"HTTP/1.0 200 OK\r\n");
ensure_contains("web/hello content type", result,
"Content-Type: application/llsd+xml\r\n");
ensure_contains("web/hello content length", result,
"Content-Length: 36\r\n");
ensure_contains("web/hello content", result,
"\r\n"
"<llsd><string>hello</string></llsd>"
);
}
template<> template<>
void HTTPServiceTestObject::test<2>()
{
// test various HTTP errors
std::string actual;
actual = httpGET("web/missing");
ensure_starts_with("web/missing 404", actual,
"HTTP/1.0 404 Not Found\r\n");
actual = httpGET("web/echo");
ensure_starts_with("web/echo 405", actual,
"HTTP/1.0 405 Method Not Allowed\r\n");
}
template<> template<>
void HTTPServiceTestObject::test<3>()
{
// test POST & content-length handling
std::string result;
result = httpPOST("web/echo",
"<llsd><integer>42</integer></llsd>");
ensure_starts_with("web/echo status", result,
"HTTP/1.0 200 OK\r\n");
ensure_contains("web/echo content type", result,
"Content-Type: application/llsd+xml\r\n");
ensure_contains("web/echo content length", result,
"Content-Length: 35\r\n");
ensure_contains("web/hello content", result,
"\r\n"
"<llsd><integer>42</integer></llsd>"
);
/* TO DO: this test doesn't pass!!
result = httpPOST("web/echo",
"<llsd><string>evil</string></llsd>",
"really! evil!!!");
ensure_equals("web/echo evil result", result,
"HTTP/1.0 200 OK\r\n"
"Content-Length: 34\r\n"
"\r\n"
"<llsd><string>evil</string></llsd>"
);
*/
}
template<> template<>
void HTTPServiceTestObject::test<4>()
{
// test calling things based on pipes
std::string result;
result = httpGET("wire/hello");
ensure_contains("wire/hello", result, "yo!");
}
template<> template<>
void HTTPServiceTestObject::test<5>()
{
// test timeout before async response
std::string result;
bool timeout = true;
result = httpPOST("delayed/echo",
"<llsd><string>agent99</string></llsd>", timeout);
ensure_equals("timeout delayed/echo status", result, std::string(""));
}
template<> template<>
void HTTPServiceTestObject::test<6>()
{
// test delayed service
std::string result;
result = httpPOST("delayed/echo",
"<llsd><string>agent99</string></llsd>");
ensure_starts_with("delayed/echo status", result,
"HTTP/1.0 200 OK\r\n");
ensure_contains("delayed/echo content", result,
"\r\n"
"<llsd><string>agent99</string></llsd>"
);
}
template<> template<>
void HTTPServiceTestObject::test<7>()
{
// test large request
std::stringstream stream;
//U32 size = 36 * 1024 * 1024;
//U32 size = 36 * 1024;
//std::vector<char> data(size);
//memset(&(data[0]), '1', size);
//data[size - 1] = '\0';
//std::string result = httpPOST("web/echo", &(data[0]));
stream << "<llsd><array>";
for(U32 i = 0; i < 1000000; ++i)
{
stream << "<integer>42</integer>";
}
stream << "</array></llsd>";
llinfos << "HTTPServiceTestObject::test<7>"
<< stream.str().length() << llendl;
std::string result = httpPOST("web/echo", stream.str());
ensure_starts_with("large echo status", result, "HTTP/1.0 200 OK\r\n");
}
template<> template<>
void HTTPServiceTestObject::test<8>()
{
// test the OPTIONS http method -- the default implementation
// should return the X-Documentation-URL
std::ostringstream http_request;
http_request << "OPTIONS / HTTP/1.0\r\nHost: localhost\r\n\r\n";
bool timeout = false;
std::string result = makeRequest("/", http_request.str(), timeout);
ensure_starts_with("OPTIONS verb ok", result, "HTTP/1.0 200 OK\r\n");
ensure_contains(
"Doc url header exists",
result,
"X-Documentation-URL: http://localhost");
}
/* TO DO:
test generation of not found and method not allowed errors
*/
}

248
indra/test/lljoint_tut.cpp Normal file
View File

@@ -0,0 +1,248 @@
/**
* @file lljoint_tut.cpp
* @author Adroit
* @date 2007=-03
* @brief lljoint test cases.
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifdef THIS_DOESNT_LINK
// THIS DOESN'T LINK!
#include <tut/tut.hpp>
#include "lltut.h"
#include "linden_common.h"
#include "m4math.h"
#include "v3math.h"
#include "lljoint.h"
namespace tut
{
struct lljoint_data
{
};
typedef test_group<lljoint_data> lljoint_test;
typedef lljoint_test::object lljoint_object;
tut::lljoint_test lljoint_testcase("lljoint");
template<> template<>
void lljoint_object::test<1>()
{
LLJoint lljoint;
LLJoint* jnt = lljoint.getParent();
ensure("getParent() failed ", (NULL == jnt));
ensure("getRoot() failed ", (&lljoint == lljoint.getRoot()));
}
template<> template<>
void lljoint_object::test<2>()
{
std::string str = "LLJoint";
LLJoint parent(str), child;
child.setup(str, &parent);
LLJoint* jnt = child.getParent();
ensure("setup() failed ", (&parent == jnt));
}
template<> template<>
void lljoint_object::test<3>()
{
LLJoint parent, child;
std::string str = "LLJoint";
child.setup(str, &parent);
LLJoint* jnt = parent.findJoint(str);
ensure("findJoint() failed ", (&child == jnt));
}
template<> template<>
void lljoint_object::test<4>()
{
LLJoint parent;
std::string str1 = "LLJoint", str2;
parent.setName(str1);
str2 = parent.getName();
ensure("setName() failed ", (str1 == str2));
}
template<> template<>
void lljoint_object::test<5>()
{
LLJoint lljoint;
LLVector3 vec3(2.3f,30.f,10.f);
lljoint.setPosition(vec3);
LLVector3 pos = lljoint.getPosition();
ensure("setPosition()/getPosition() failed ", (vec3 == pos));
}
template<> template<>
void lljoint_object::test<6>()
{
LLJoint lljoint;
LLVector3 vec3(2.3f,30.f,10.f);
lljoint.setWorldPosition(vec3);
LLVector3 pos = lljoint.getWorldPosition();
ensure("1:setWorldPosition()/getWorldPosition() failed ", (vec3 == pos));
LLVector3 lastPos = lljoint.getLastWorldPosition();
ensure("2:getLastWorldPosition failed ", (vec3 == lastPos));
}
template<> template<>
void lljoint_object::test<7>()
{
LLJoint lljoint("LLJoint");
LLQuaternion q(2.3f,30.f,10.f,1.f);
lljoint.setRotation(q);
LLQuaternion rot = lljoint.getRotation();
ensure("setRotation()/getRotation() failed ", (q == rot));
}
template<> template<>
void lljoint_object::test<8>()
{
LLJoint lljoint("LLJoint");
LLQuaternion q(2.3f,30.f,10.f,1.f);
lljoint.setWorldRotation(q);
LLQuaternion rot = lljoint.getWorldRotation();
ensure("1:setWorldRotation()/getWorldRotation() failed ", (q == rot));
LLQuaternion lastRot = lljoint.getLastWorldRotation();
ensure("2:getLastWorldRotation failed ", (q == lastRot));
}
template<> template<>
void lljoint_object::test<9>()
{
LLJoint lljoint;
LLVector3 vec3(2.3f,30.f,10.f);
lljoint.setScale(vec3);
LLVector3 scale = lljoint.getScale();
ensure("setScale()/getScale failed ", (vec3 == scale));
}
template<> template<>
void lljoint_object::test<10>()
{
LLJoint lljoint("LLJoint");
LLMatrix4 mat;
mat.identity();
lljoint.setWorldMatrix(mat);//giving warning setWorldMatrix not correctly implemented;
LLMatrix4 mat4 = lljoint.getWorldMatrix();
ensure("setWorldMatrix()/getWorldMatrix failed ", (mat4 == mat));
}
template<> template<>
void lljoint_object::test<11>()
{
LLJoint lljoint("parent");
S32 joint_num = 12;
lljoint.setJointNum(joint_num);
S32 jointNum = lljoint.getJointNum();
ensure("setJointNum()/getJointNum failed ", (jointNum == joint_num));
}
template<> template<>
void lljoint_object::test<12>()
{
LLJoint lljoint;
LLVector3 vec3(2.3f,30.f,10.f);
lljoint.setSkinOffset(vec3);
LLVector3 offset = lljoint.getSkinOffset();
ensure("1:setSkinOffset()/getSkinOffset() failed ", (vec3 == offset));
}
template<> template<>
void lljoint_object::test<13>()
{
LLJoint lljointgp("gparent");
LLJoint lljoint("parent");
LLJoint lljoint1("child1");
lljoint.addChild(&lljoint1);
LLJoint lljoint2("child2");
lljoint.addChild(&lljoint2);
LLJoint lljoint3("child3");
lljoint.addChild(&lljoint3);
LLJoint* jnt = NULL;
jnt = lljoint2.getParent();
ensure("addChild() failed ", (&lljoint == jnt));
LLJoint* jnt1 = lljoint.findJoint("child3");
ensure("findJoint() failed ", (&lljoint3 == jnt1));
lljoint.removeChild(&lljoint3);
LLJoint* jnt2 = lljoint.findJoint("child3");
ensure("removeChild() failed ", (NULL == jnt2));
lljointgp.addChild(&lljoint);
ensure("GetParent() failed ", (&lljoint== lljoint2.getParent()));
ensure("getRoot() failed ", (&lljointgp == lljoint2.getRoot()));
ensure("getRoot() failed ", &lljoint1 == lljoint.findJoint("child1"));
lljointgp.removeAllChildren();
// parent removed from grandparent - so should not be able to locate child
ensure("removeAllChildren() failed ", (NULL == lljointgp.findJoint("child1")));
// it should still exist in parent though
ensure("removeAllChildren() failed ", (&lljoint1 == lljoint.findJoint("child1")));
}
template<> template<>
void lljoint_object::test<14>()
{
LLJoint lljointgp("gparent");
LLJoint llparent1("parent1");
LLJoint llparent2("parent2");
LLJoint llchild("child1");
LLJoint lladoptedchild("child2");
llparent1.addChild(&llchild);
llparent1.addChild(&lladoptedchild);
llparent2.addChild(&lladoptedchild);
ensure("1. addChild failed to remove prior parent", lladoptedchild.getParent() == &llparent2);
ensure("2. addChild failed to remove prior parent", llparent1.findJoint("child2") == NULL);
}
//*
Test cases for the following not added. They perform operations
on underlying LLXformMatrix and LLVector3 elements which have
been unit tested separately.
Unit Testing these functions will basically require re-implementing
logic of these function in the test case itself
1) void WorldMatrixChildren();
2) void updateWorldMatrixParent();
3) void updateWorldPRSParent();
4) void updateWorldMatrix();
5) LLXformMatrix *getXform() { return &mXform; }
6) void setConstraintSilhouette(LLDynamicArray<LLVector3>& silhouette);
7) void clampRotation(LLQuaternion old_rot, LLQuaternion new_rot);
//*
}
#endif // THIS_DOESNT_LINK

View File

@@ -0,0 +1,242 @@
/**
* @file llmessageconfig_tut.cpp
* @date March 2007
* @brief LLMessageConfig unit tests
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llmessageconfig.h"
#include "lltut.h"
#include "llsdserialize.h"
#include "llfile.h"
#include "lltimer.h"
#include "llframetimer.h"
#include "llsdutil.h"
namespace tut
{
struct LLMessageConfigTestData {
std::string mTestConfigDir;
LLMessageConfigTestData()
{
LLUUID random;
random.generate();
// generate temp dir
std::ostringstream oStr;
#if LL_WINDOWS
oStr << "llmessage-config-test-" << random;
#else
oStr << "/tmp/llmessage-config-test-" << random;
#endif
mTestConfigDir = oStr.str();
LLFile::mkdir(mTestConfigDir);
writeConfigFile(LLSD());
LLMessageConfig::initClass("simulator", mTestConfigDir);
}
~LLMessageConfigTestData()
{
// rm contents of temp dir
int rmfile = LLFile::remove((mTestConfigDir + "/message.xml"));
ensure_equals("rmfile value", rmfile, 0);
// rm temp dir
int rmdir = LLFile::rmdir(mTestConfigDir);
ensure_equals("rmdir value", rmdir, 0);
}
void writeConfigFile(const LLSD& config)
{
llofstream file((mTestConfigDir + "/message.xml"));
if (file.is_open())
{
LLSDSerialize::toPrettyXML(config, file);
}
file.close();
}
};
typedef test_group<LLMessageConfigTestData> LLMessageConfigTestGroup;
typedef LLMessageConfigTestGroup::object LLMessageConfigTestObject;
LLMessageConfigTestGroup llMessageConfigTestGroup("LLMessageConfig");
template<> template<>
void LLMessageConfigTestObject::test<1>()
// tests server defaults
{
LLSD config;
config["serverDefaults"]["simulator"] = "template";
LLMessageConfig::useConfig(config);
ensure_equals("Ensure server default is not template",
LLMessageConfig::getServerDefaultFlavor(),
LLMessageConfig::TEMPLATE_FLAVOR);
}
template<> template<>
void LLMessageConfigTestObject::test<2>()
// tests message flavors
{
LLSD config;
config["serverDefaults"]["simulator"] = "template";
config["messages"]["msg1"]["flavor"] = "template";
config["messages"]["msg2"]["flavor"] = "llsd";
LLMessageConfig::useConfig(config);
ensure_equals("Ensure msg template flavor",
LLMessageConfig::getMessageFlavor("msg1"),
LLMessageConfig::TEMPLATE_FLAVOR);
ensure_equals("Ensure msg llsd flavor",
LLMessageConfig::getMessageFlavor("msg2"),
LLMessageConfig::LLSD_FLAVOR);
}
template<> template<>
void LLMessageConfigTestObject::test<4>()
// tests message flavor defaults
{
LLSD config;
config["serverDefaults"]["simulator"] = "llsd";
config["messages"]["msg1"]["trusted-sender"] = true;
LLMessageConfig::useConfig(config);
ensure_equals("Ensure missing message gives no flavor",
LLMessageConfig::getMessageFlavor("Test"),
LLMessageConfig::NO_FLAVOR);
ensure_equals("Ensure missing flavor is NO_FLAVOR even with sender trustedness set",
LLMessageConfig::getMessageFlavor("msg1"),
LLMessageConfig::NO_FLAVOR);
ensure_equals("Ensure server default is llsd",
LLMessageConfig::getServerDefaultFlavor(),
LLMessageConfig::LLSD_FLAVOR);
}
template<> template<>
void LLMessageConfigTestObject::test<3>()
// tests trusted/untrusted senders
{
LLSD config;
config["serverDefaults"]["simulator"] = "template";
config["messages"]["msg1"]["flavor"] = "llsd";
config["messages"]["msg1"]["trusted-sender"] = false;
config["messages"]["msg2"]["flavor"] = "llsd";
config["messages"]["msg2"]["trusted-sender"] = true;
LLMessageConfig::useConfig(config);
ensure_equals("Ensure untrusted is untrusted",
LLMessageConfig::getSenderTrustedness("msg1"),
LLMessageConfig::UNTRUSTED);
ensure_equals("Ensure trusted is trusted",
LLMessageConfig::getSenderTrustedness("msg2"),
LLMessageConfig::TRUSTED);
ensure_equals("Ensure missing trustedness is NOT_SET",
LLMessageConfig::getSenderTrustedness("msg3"),
LLMessageConfig::NOT_SET);
}
template<> template<>
void LLMessageConfigTestObject::test<5>()
// tests trusted/untrusted without flag, only flavor
{
LLSD config;
config["serverDefaults"]["simulator"] = "template";
config["messages"]["msg1"]["flavor"] = "llsd";
LLMessageConfig::useConfig(config);
ensure_equals("Ensure msg1 exists, has llsd flavor",
LLMessageConfig::getMessageFlavor("msg1"),
LLMessageConfig::LLSD_FLAVOR);
ensure_equals("Ensure missing trusted is not set",
LLMessageConfig::getSenderTrustedness("msg1"),
LLMessageConfig::NOT_SET);
}
template<> template<>
void LLMessageConfigTestObject::test<6>()
{
LLSD config;
config["capBans"]["MapLayer"] = true;
config["capBans"]["MapLayerGod"] = false;
LLMessageConfig::useConfig(config);
ensure_equals("Ensure cap ban true MapLayer",
LLMessageConfig::isCapBanned("MapLayer"),
true);
ensure_equals("Ensure cap ban false",
LLMessageConfig::isCapBanned("MapLayerGod"),
false);
}
template<> template<>
void LLMessageConfigTestObject::test<7>()
// tests that config changes are picked up/refreshed periodically
{
LLSD config;
config["serverDefaults"]["simulator"] = "llsd";
writeConfigFile(config);
// wait for it to reload after N seconds
ms_sleep(6*1000);
LLFrameTimer::updateFrameTime();
ensure_equals("Ensure reload after 6 seconds",
LLMessageConfig::getServerDefaultFlavor(),
LLMessageConfig::LLSD_FLAVOR);
}
template<> template<>
void LLMessageConfigTestObject::test<8>()
// tests that config changes are picked up/refreshed periodically
{
LLSD config;
config["serverDefaults"]["simulator"] = "template";
config["messages"]["msg1"]["flavor"] = "llsd";
config["messages"]["msg1"]["only-send-latest"] = true;
config["messages"]["msg2"]["flavor"] = "llsd";
config["messages"]["msg2"]["only-send-latest"] = false;
LLMessageConfig::useConfig(config);
ensure_equals("Ensure msg1 exists, sent latest-only",
LLMessageConfig::onlySendLatest("msg1"),
true);
ensure_equals("Ensure msg2 exists, sent latest-only",
LLMessageConfig::onlySendLatest("msg2"),
false);
}
template<> template<>
void LLMessageConfigTestObject::test<9>()
// tests that event queue max is reloaded
{
LLSD config;
config["maxQueuedEvents"] = 200;
LLMessageConfig::useConfig(config);
ensure_equals("Ensure setting maxQueuedEvents",
LLMessageConfig::getMaxQueuedEvents(),
200);
LLMessageConfig::useConfig(LLSD());
ensure_equals("Ensure default of event queue max 100",
LLMessageConfig::getMaxQueuedEvents(),
100);
}
}

View File

@@ -0,0 +1,374 @@
/**
* @file llmessagetemplateparser_tut.cpp
* @date April 2007
* @brief LLMessageTemplateParser unit tests
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llmessagetemplateparser.h"
#include "lltut.h"
namespace tut
{
struct LLMessageTemplateParserTestData {
LLMessageTemplateParserTestData() : mMessage("unset message")
{
}
~LLMessageTemplateParserTestData()
{
}
void ensure_next(LLTemplateTokenizer & tokens,
std::string value,
U32 line)
{
std::string next = tokens.next();
ensure_equals(mMessage + " token matches", next, value);
ensure_equals(mMessage + " line matches", tokens.line(), line);
}
char * prehash(const char * name)
{
return LLMessageStringTable::getInstance()->getString(name);
}
void ensure_block_attributes(std::string identifier,
const LLMessageTemplate * message,
const char * name,
EMsgBlockType type,
S32 number,
S32 total_size)
{
const LLMessageBlock * block = message->getBlock(prehash(name));
identifier = identifier + ":" + message->mName + ":" + name + " block";
ensure(identifier + " exists", block != NULL);
ensure_equals(identifier + " name", block->mName, prehash(name));
ensure_equals(identifier + " type", block->mType, type);
ensure_equals(identifier + " number", block->mNumber, number);
ensure_equals(identifier + " total size", block->mTotalSize, total_size);
}
void ensure_variable_attributes(std::string identifier,
const LLMessageBlock * block,
const char * name,
EMsgVariableType type,
S32 size)
{
const LLMessageVariable * var = block->getVariable(prehash(name));
identifier = identifier + ":" + block->mName + ":" + name + " variable";
ensure(identifier + " exists", var != NULL);
ensure_equals(
identifier + " name", var->getName(), prehash(name));
ensure_equals(
identifier + " type", var->getType(), type);
ensure_equals(identifier + " size", var->getSize(), size);
}
std::string mMessage;
};
typedef test_group<LLMessageTemplateParserTestData> LLMessageTemplateParserTestGroup;
typedef LLMessageTemplateParserTestGroup::object LLMessageTemplateParserTestObject;
LLMessageTemplateParserTestGroup llMessageTemplateParserTestGroup("LLMessageTemplateParser");
template<> template<>
void LLMessageTemplateParserTestObject::test<1>()
// tests tokenizer constructor and next methods
{
mMessage = "test method 1 walkthrough";
LLTemplateTokenizer tokens("first line\nnext\t line\n\nfourth");
ensure_next(tokens, "first", 1);
ensure_next(tokens, "line", 1);
ensure_next(tokens, "next", 2);
ensure_next(tokens, "line", 2);
ensure_next(tokens, "fourth", 4);
tokens = LLTemplateTokenizer("\n\t{ \t Test1 Fixed \n 523 }\n\n");
ensure(tokens.want("{"));
ensure_next(tokens, "Test1", 2);
ensure_next(tokens, "Fixed", 2);
ensure_next(tokens, "523", 3);
ensure(tokens.want("}"));
tokens = LLTemplateTokenizer("first line\nnext\t line\n\nfourth");
ensure(tokens.want("first"));
ensure_next(tokens, "line", 1);
ensure_next(tokens, "next", 2);
ensure_next(tokens, "line", 2);
ensure(tokens.want("fourth"));
}
template<> template<>
void LLMessageTemplateParserTestObject::test<2>()
// tests tokenizer want method
{
// *NOTE: order matters
LLTemplateTokenizer tokens("first line\nnext\t line\n\nfourth");
ensure_equals("wants first token", tokens.want("first"), true);
ensure_equals("doesn't want blar token", tokens.want("blar"), false);
ensure_equals("wants line token", tokens.want("line"), true);
}
template<> template<>
void LLMessageTemplateParserTestObject::test<3>()
// tests tokenizer eof methods
{
LLTemplateTokenizer tokens("single\n\n");
ensure_equals("is not at eof at beginning", tokens.atEOF(), false);
ensure_equals("doesn't want eof", tokens.wantEOF(), false);
ensure_equals("wants the first token just to consume it",
tokens.want("single"), true);
ensure_equals("is not at eof in middle", tokens.atEOF(), false);
ensure_equals("wants eof", tokens.wantEOF(), true);
ensure_equals("is at eof at end", tokens.atEOF(), true);
}
template<> template<>
void LLMessageTemplateParserTestObject::test<4>()
// tests variable parsing method
{
LLTemplateTokenizer tokens(std::string("{ Test0 \n\t\n U32 \n\n }"));
LLMessageVariable * var = LLTemplateParser::parseVariable(tokens);
ensure("test0 var parsed", var != 0);
ensure_equals("name of variable", std::string(var->getName()), std::string("Test0"));
ensure_equals("type of variable is U32", var->getType(), MVT_U32);
ensure_equals("size of variable", var->getSize(), 4);
delete var;
std::string message_string("\n\t{ \t Test1 Fixed \n 523 }\n\n");
tokens = LLTemplateTokenizer(message_string);
var = LLTemplateParser::parseVariable(tokens);
ensure("test1 var parsed", var != 0);
ensure_equals("name of variable", std::string(var->getName()), std::string("Test1"));
ensure_equals("type of variable is Fixed", var->getType(), MVT_FIXED);
ensure_equals("size of variable", var->getSize(), 523);
delete var;
// *NOTE: the parsers call llerrs on invalid input, so we can't really
// test that :-(
}
template<> template<>
void LLMessageTemplateParserTestObject::test<5>()
// tests block parsing method
{
LLTemplateTokenizer tokens("{ BlockA Single { VarX F32 } }");
LLMessageBlock * block = LLTemplateParser::parseBlock(tokens);
ensure("blockA block parsed", block != 0);
ensure_equals("name of block", std::string(block->mName), std::string("BlockA"));
ensure_equals("type of block is Single", block->mType, MBT_SINGLE);
ensure_equals("total size of block", block->mTotalSize, 4);
ensure_equals("number of block defaults to 1", block->mNumber, 1);
ensure_equals("variable type of VarX is F32",
block->getVariableType(prehash("VarX")), MVT_F32);
ensure_equals("variable size of VarX",
block->getVariableSize(prehash("VarX")), 4);
delete block;
tokens = LLTemplateTokenizer("{ Stuff Variable { Id LLUUID } }");
block = LLTemplateParser::parseBlock(tokens);
ensure("stuff block parsed", block != 0);
ensure_equals("name of block", std::string(block->mName), std::string("Stuff"));
ensure_equals("type of block is Multiple", block->mType, MBT_VARIABLE);
ensure_equals("total size of block", block->mTotalSize, 16);
ensure_equals("number of block defaults to 1", block->mNumber, 1);
ensure_equals("variable type of Id is LLUUID",
block->getVariableType(prehash("Id")), MVT_LLUUID);
ensure_equals("variable size of Id",
block->getVariableSize(prehash("Id")), 16);
delete block;
tokens = LLTemplateTokenizer("{ Stuff2 Multiple 45 { Shid LLVector3d } }");
block = LLTemplateParser::parseBlock(tokens);
ensure("stuff2 block parsed", block != 0);
ensure_equals("name of block", std::string(block->mName), std::string("Stuff2"));
ensure_equals("type of block is Multiple", block->mType, MBT_MULTIPLE);
ensure_equals("total size of block", block->mTotalSize, 24);
ensure_equals("number of blocks", block->mNumber, 45);
ensure_equals("variable type of Shid is Vector3d",
block->getVariableType(prehash("Shid")), MVT_LLVector3d);
ensure_equals("variable size of Shid",
block->getVariableSize(prehash("Shid")), 24);
delete block;
}
template<> template<>
void LLMessageTemplateParserTestObject::test<6>()
// tests message parsing method on a simple message
{
std::string message_skel(
"{\n"
"TestMessage Low 1 NotTrusted Zerocoded\n"
"// comment \n"
" {\n"
"TestBlock1 Single\n"
" { Test1 U32 }\n"
" }\n"
" {\n"
" NeighborBlock Multiple 4\n"
" { Test0 U32 }\n"
" { Test1 U32 }\n"
" { Test2 U32 }\n"
" }\n"
"}");
LLTemplateTokenizer tokens(message_skel);
LLMessageTemplate * message = LLTemplateParser::parseMessage(tokens);
ensure("simple message parsed", message != 0);
ensure_equals("name of message", std::string(message->mName), std::string("TestMessage"));
ensure_equals("frequency is Low", message->mFrequency, MFT_LOW);
ensure_equals("trust is untrusted", message->mTrust, MT_NOTRUST);
ensure_equals("message number", message->mMessageNumber, (U32)((255 << 24) | (255 << 16) | 1));
ensure_equals("message encoding is zerocoded", message->mEncoding, ME_ZEROCODED);
ensure_equals("message deprecation is notdeprecated", message->mDeprecation, MD_NOTDEPRECATED);
LLMessageBlock * block = message->getBlock(prehash("NonexistantBlock"));
ensure("Nonexistant block does not exist", block == 0);
delete message;
}
template<> template<>
void LLMessageTemplateParserTestObject::test<7>()
// tests message parsing method on a deprecated message
{
std::string message_skel(
"{\n"
"TestMessageDeprecated High 34 Trusted Unencoded Deprecated\n"
" {\n"
"TestBlock2 Single\n"
" { Test2 S32 }\n"
" }\n"
"}");
LLTemplateTokenizer tokens(message_skel);
LLMessageTemplate * message = LLTemplateParser::parseMessage(tokens);
ensure("deprecated message parsed", message != 0);
ensure_equals("name of message", std::string(message->mName), std::string("TestMessageDeprecated"));
ensure_equals("frequency is High", message->mFrequency, MFT_HIGH);
ensure_equals("trust is trusted", message->mTrust, MT_TRUST);
ensure_equals("message number", message->mMessageNumber, (U32)34);
ensure_equals("message encoding is unencoded", message->mEncoding, ME_UNENCODED);
ensure_equals("message deprecation is deprecated", message->mDeprecation, MD_DEPRECATED);
delete message;
}
template<> template<> void LLMessageTemplateParserTestObject::test<8>()
// tests message parsing on RezMultipleAttachmentsFromInv, a possibly-faulty message
{
std::string message_skel(
"{\n\
RezMultipleAttachmentsFromInv Low 452 NotTrusted Zerocoded\n\
{\n\
AgentData Single\n\
{ AgentID LLUUID }\n\
{ SessionID LLUUID }\n\
} \n\
{\n\
HeaderData Single\n\
{ CompoundMsgID LLUUID } // All messages a single \"compound msg\" must have the same id\n\
{ TotalObjects U8 }\n\
{ FirstDetachAll BOOL }\n\
}\n\
{\n\
ObjectData Variable // 1 to 4 of these per packet\n\
{ ItemID LLUUID }\n\
{ OwnerID LLUUID }\n\
{ AttachmentPt U8 } // 0 for default\n\
{ ItemFlags U32 }\n\
{ GroupMask U32 }\n\
{ EveryoneMask U32 }\n\
{ NextOwnerMask U32 }\n\
{ Name Variable 1 }\n\
{ Description Variable 1 }\n\
}\n\
}\n\
");
LLTemplateTokenizer tokens(message_skel);
LLMessageTemplate * message = LLTemplateParser::parseMessage(tokens);
ensure("RezMultipleAttachmentsFromInv message parsed", message != 0);
ensure_equals("name of message", message->mName, prehash("RezMultipleAttachmentsFromInv"));
ensure_equals("frequency is low", message->mFrequency, MFT_LOW);
ensure_equals("trust is not trusted", message->mTrust, MT_NOTRUST);
ensure_equals("message number", message->mMessageNumber, (U32)((255 << 24) | (255 << 16) | 452));
ensure_equals("message encoding is zerocoded", message->mEncoding, ME_ZEROCODED);
ensure_block_attributes(
"RMAFI", message, "AgentData", MBT_SINGLE, 1, 16+16);
LLMessageBlock * block = message->getBlock(prehash("AgentData"));
ensure_variable_attributes("RMAFI",
block, "AgentID", MVT_LLUUID, 16);
ensure_variable_attributes("RMAFI",
block, "SessionID", MVT_LLUUID, 16);
ensure_block_attributes(
"RMAFI", message, "HeaderData", MBT_SINGLE, 1, 16+1+1);
block = message->getBlock(prehash("HeaderData"));
ensure_variable_attributes(
"RMAFI", block, "CompoundMsgID", MVT_LLUUID, 16);
ensure_variable_attributes(
"RMAFI", block, "TotalObjects", MVT_U8, 1);
ensure_variable_attributes(
"RMAFI", block, "FirstDetachAll", MVT_BOOL, 1);
ensure_block_attributes(
"RMAFI", message, "ObjectData", MBT_VARIABLE, 1, -1);
block = message->getBlock(prehash("ObjectData"));
ensure_variable_attributes("RMAFI", block, "ItemID", MVT_LLUUID, 16);
ensure_variable_attributes("RMAFI", block, "OwnerID", MVT_LLUUID, 16);
ensure_variable_attributes("RMAFI", block, "AttachmentPt", MVT_U8, 1);
ensure_variable_attributes("RMAFI", block, "ItemFlags", MVT_U32, 4);
ensure_variable_attributes("RMAFI", block, "GroupMask", MVT_U32, 4);
ensure_variable_attributes("RMAFI", block, "EveryoneMask", MVT_U32, 4);
ensure_variable_attributes("RMAFI", block, "NextOwnerMask", MVT_U32, 4);
ensure_variable_attributes("RMAFI", block, "Name", MVT_VARIABLE, 1);
ensure_variable_attributes("RMAFI", block, "Description", MVT_VARIABLE, 1);
delete message;
}
}

448
indra/test/llmime_tut.cpp Normal file
View File

@@ -0,0 +1,448 @@
/**
* @file llmime_tut.cpp
* @author Phoenix
* @date 2006-12-24
* @brief BRIEF_DESC of llmime_tut.cpp
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "llmime.h"
#include "llsdserialize.h"
namespace tut
{
struct mime_index
{
};
typedef test_group<mime_index> mime_index_t;
typedef mime_index_t::object mime_index_object_t;
tut::mime_index_t tut_mime_index("mime_index");
template<> template<>
void mime_index_object_t::test<1>()
{
LLMimeIndex mime;
ensure("no headers", mime.headers().isUndefined());
ensure_equals("invalid offset", mime.offset(), -1);
ensure_equals("invalid content length", mime.contentLength(), -1);
ensure("no content type", mime.contentType().empty());
ensure("not multipart", !mime.isMultipart());
ensure_equals("no attachments", mime.subPartCount(), 0);
}
template<> template<>
void mime_index_object_t::test<2>()
{
const S32 CONTENT_LENGTH = 6000;
const S32 CONTENT_OFFSET = 100;
const std::string CONTENT_TYPE = std::string("image/j2c");
LLSD headers;
headers["Content-Length"] = CONTENT_LENGTH;
headers["Content-Type"] = CONTENT_TYPE;
LLMimeIndex mime(headers, CONTENT_OFFSET);
ensure("headers are map", mime.headers().isMap());
ensure_equals("offset", mime.offset(), CONTENT_OFFSET);
ensure_equals("content length", mime.contentLength(), CONTENT_LENGTH);
ensure_equals("type is image/j2c", mime.contentType(), CONTENT_TYPE);
ensure("not multipart", !mime.isMultipart());
ensure_equals("no attachments", mime.subPartCount(), 0);
}
template<> template<>
void mime_index_object_t::test<3>()
{
const S32 MULTI_CONTENT_LENGTH = 8000;
const S32 MULTI_CONTENT_OFFSET = 100;
const std::string MULTI_CONTENT_TYPE = std::string("multipart/mixed");
LLSD headers;
headers["Content-Length"] = MULTI_CONTENT_LENGTH;
headers["Content-Type"] = MULTI_CONTENT_TYPE;
LLMimeIndex mime(headers, MULTI_CONTENT_OFFSET);
llinfos << "headers: " << LLSDOStreamer<LLSDNotationFormatter>(headers)
<< llendl;
const S32 META_CONTENT_LENGTH = 700;
const S32 META_CONTENT_OFFSET = 69;
const std::string META_CONTENT_TYPE = std::string(
"text/llsd+xml");
headers = LLSD::emptyMap();
headers["Content-Length"] = META_CONTENT_LENGTH;
headers["Content-Type"] = META_CONTENT_TYPE;
LLMimeIndex meta(headers, META_CONTENT_OFFSET);
mime.attachSubPart(meta);
const S32 IMAGE_CONTENT_LENGTH = 6000;
const S32 IMAGE_CONTENT_OFFSET = 200;
const std::string IMAGE_CONTENT_TYPE = std::string("image/j2c");
headers = LLSD::emptyMap();
headers["Content-Length"] = IMAGE_CONTENT_LENGTH;
headers["Content-Type"] = IMAGE_CONTENT_TYPE;
LLMimeIndex image(headers, IMAGE_CONTENT_OFFSET);
mime.attachSubPart(image);
// make sure we have a valid multi-part
ensure("is multipart", mime.isMultipart());
ensure_equals("multi offset", mime.offset(), MULTI_CONTENT_OFFSET);
ensure_equals(
"multi content length",
mime.contentLength(),
MULTI_CONTENT_LENGTH);
ensure_equals("two attachments", mime.subPartCount(), 2);
// make sure ranged gets do the right thing with out of bounds
// sub-parts.
LLMimeIndex invalid_child(mime.subPart(-1));
ensure("no headers", invalid_child.headers().isUndefined());
ensure_equals("invalid offset", invalid_child.offset(), -1);
ensure_equals(
"invalid content length", invalid_child.contentLength(), -1);
ensure("no content type", invalid_child.contentType().empty());
ensure("not multipart", !invalid_child.isMultipart());
ensure_equals("no attachments", invalid_child.subPartCount(), 0);
invalid_child = mime.subPart(2);
ensure("no headers", invalid_child.headers().isUndefined());
ensure_equals("invalid offset", invalid_child.offset(), -1);
ensure_equals(
"invalid content length", invalid_child.contentLength(), -1);
ensure("no content type", invalid_child.contentType().empty());
ensure("not multipart", !invalid_child.isMultipart());
ensure_equals("no attachments", invalid_child.subPartCount(), 0);
}
template<> template<>
void mime_index_object_t::test<4>()
{
const S32 MULTI_CONTENT_LENGTH = 8000;
const S32 MULTI_CONTENT_OFFSET = 100;
const std::string MULTI_CONTENT_TYPE = std::string("multipart/mixed");
LLSD headers;
headers["Content-Length"] = MULTI_CONTENT_LENGTH;
headers["Content-Type"] = MULTI_CONTENT_TYPE;
LLMimeIndex mime(headers, MULTI_CONTENT_OFFSET);
const S32 META_CONTENT_LENGTH = 700;
const S32 META_CONTENT_OFFSET = 69;
const std::string META_CONTENT_TYPE = std::string(
"application/llsd+xml");
headers = LLSD::emptyMap();
headers["Content-Length"] = META_CONTENT_LENGTH;
headers["Content-Type"] = META_CONTENT_TYPE;
LLMimeIndex meta(headers, META_CONTENT_OFFSET);
mime.attachSubPart(meta);
const S32 IMAGE_CONTENT_LENGTH = 6000;
const S32 IMAGE_CONTENT_OFFSET = 200;
const std::string IMAGE_CONTENT_TYPE = std::string("image/j2c");
headers = LLSD::emptyMap();
headers["Content-Length"] = IMAGE_CONTENT_LENGTH;
headers["Content-Type"] = IMAGE_CONTENT_TYPE;
LLMimeIndex image(headers, IMAGE_CONTENT_OFFSET);
mime.attachSubPart(image);
// check what we have
ensure("is multipart", mime.isMultipart());
ensure_equals("multi offset", mime.offset(), MULTI_CONTENT_OFFSET);
ensure_equals(
"multi content length",
mime.contentLength(),
MULTI_CONTENT_LENGTH);
ensure_equals("two attachments", mime.subPartCount(), 2);
LLMimeIndex actual_meta = mime.subPart(0);
ensure_equals(
"meta type", actual_meta.contentType(), META_CONTENT_TYPE);
ensure_equals(
"meta offset", actual_meta.offset(), META_CONTENT_OFFSET);
ensure_equals(
"meta content length",
actual_meta.contentLength(),
META_CONTENT_LENGTH);
LLMimeIndex actual_image = mime.subPart(1);
ensure_equals(
"image type", actual_image.contentType(), IMAGE_CONTENT_TYPE);
ensure_equals(
"image offset", actual_image.offset(), IMAGE_CONTENT_OFFSET);
ensure_equals(
"image content length",
actual_image.contentLength(),
IMAGE_CONTENT_LENGTH);
}
/*
template<> template<>
void mime_index_object_t::test<5>()
{
}
template<> template<>
void mime_index_object_t::test<6>()
{
}
template<> template<>
void mime_index_object_t::test<7>()
{
}
template<> template<>
void mime_index_object_t::test<8>()
{
}
template<> template<>
void mime_index_object_t::test<>()
{
}
*/
}
namespace tut
{
struct mime_parse
{
};
typedef test_group<mime_parse> mime_parse_t;
typedef mime_parse_t::object mime_parse_object_t;
tut::mime_parse_t tut_mime_parse("mime_parse");
template<> template<>
void mime_parse_object_t::test<1>()
{
// parse one mime object
const std::string SERIALIZED_MIME("Content-Length: 200\r\nContent-Type: text/plain\r\n\r\naaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccc\r\n");
std::stringstream istr;
istr.str(SERIALIZED_MIME);
LLMimeIndex mime;
LLMimeParser parser;
bool ok = parser.parseIndex(istr, mime);
ensure("Parse successful.", ok);
ensure_equals("content type", mime.contentType(), "text/plain");
ensure_equals("content length", mime.contentLength(), 200);
ensure_equals("offset", mime.offset(), 49);
}
template<> template<>
void mime_parse_object_t::test<2>()
{
// make sure we only parse one.
const std::string SERIALIZED_MIME("Content-Length: 200\r\nContent-Type: text/plain\r\n\r\naaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccc\r\n\r\nContent-Length: 200\r\nContent-Type: text/plain\r\n\r\naaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccc\r\n\r\n");
std::stringstream istr;
istr.str(SERIALIZED_MIME);
LLMimeIndex mime;
LLMimeParser parser;
bool ok = parser.parseIndex(istr, mime);
ensure("Parse successful.", ok);
ensure("not multipart.", !mime.isMultipart());
ensure_equals("content type", mime.contentType(), "text/plain");
ensure_equals("content length", mime.contentLength(), 200);
ensure_equals("offset", mime.offset(), 49);
}
template<> template<>
void mime_parse_object_t::test<3>()
{
// test multi-part and lack of content length for some of it.
/*
Content-Type: multipart/mixed; boundary="segment"rnContent-Length: 148rnrn--segmentrnContent-Type: text/plainrnrnsome datarnrn--segmentrnContent-Type: text/xml; charset=UTF-8rnContent-Length: 22rnrn<llsd><undef /></llsd>rnrn
*/
const std::string SERIALIZED_MIME("Content-Type: multipart/mixed; boundary=\"segment\"\r\nContent-Length: 150\r\n\r\n--segment\r\nContent-Type: text/plain\r\n\r\nsome data\r\n\r\n--segment\r\nContent-Type: text/xml; charset=UTF-8\r\nContent-Length: 22\r\n\r\n<llsd><undef /></llsd>\r\n\r\n");
std::stringstream istr;
istr.str(SERIALIZED_MIME);
LLMimeIndex mime;
LLMimeParser parser;
bool ok = parser.parseIndex(istr, mime);
ensure("Parse successful.", ok);
ensure("is multipart.", mime.isMultipart());
ensure_equals("sub-part count", mime.subPartCount(), 2);
ensure_equals("content length", mime.contentLength(), 150);
ensure_equals("data offset for multipart", mime.offset(), 74);
LLMimeIndex mime_plain(mime.subPart(0));
ensure_equals(
"first part type",
mime_plain.contentType(),
"text/plain");
ensure_equals(
"first part content length not known.",
mime_plain.contentLength(),
-1);
ensure_equals("first part offset", mime_plain.offset(), 113);
LLMimeIndex mime_xml(mime.subPart(1));
ensure_equals(
"second part type",
mime_xml.contentType(),
"text/xml; charset=UTF-8");
ensure_equals(
"second part content length",
mime_xml.contentLength(),
22);
ensure_equals("second part offset", mime_xml.offset(), 198);
}
template<> template<>
void mime_parse_object_t::test<4>()
{
// test multi-part, unquoted separator, and premature eof conditions
/*
Content-Type: multipart/mixed; boundary=segmentrnContent-Length: 220rnrn--segmentrnContent-Type: text/plainrnContent-Length: 55rnrnhow are you today?rnI do not know. I guess I am:n'fine'rnrn--segmentrnContent-Type: text/xml; charset=UTF-8rnContent-Length: 22rnrn<llsd><undef /></llsd>rnrn */
const std::string SERIALIZED_MIME("Content-Type: multipart/mixed; boundary=segment\r\nContent-Length: 220\r\n\r\n--segment\r\nContent-Type: text/plain\r\nContent-Length: 55\r\n\r\nhow are you today?\r\nI do not know. I guess I am:\n'fine'\r\n\r\n--segment\r\nContent-Type: text/xml; charset=UTF-8\r\nContent-Length: 22\r\n\r\n<llsd><undef /></llsd>\r\n\r\n");
std::stringstream istr;
istr.str(SERIALIZED_MIME);
LLMimeIndex mime;
LLMimeParser parser;
bool ok = parser.parseIndex(istr, mime);
ensure("Parse successful.", ok);
ensure("is multipart.", mime.isMultipart());
ensure_equals("sub-part count", mime.subPartCount(), 2);
ensure_equals("content length", mime.contentLength(), 220);
ensure_equals("data offset for multipart", mime.offset(), 72);
LLMimeIndex mime_plain(mime.subPart(0));
ensure_equals(
"first part type",
mime_plain.contentType(),
"text/plain");
ensure_equals(
"first part content length",
mime_plain.contentLength(),
55);
ensure_equals("first part offset", mime_plain.offset(), 131);
LLMimeIndex mime_xml(mime.subPart(1));
ensure_equals(
"second part type",
mime_xml.contentType(),
"text/xml; charset=UTF-8");
ensure_equals(
"second part content length",
mime_xml.contentLength(),
22);
ensure_equals("second part offset", mime_xml.offset(), 262);
}
template<> template<>
void mime_parse_object_t::test<5>()
{
// test multi-part with multiple params
const std::string SERIALIZED_MIME("Content-Type: multipart/mixed; boundary=segment; comment=\"testing multiple params.\"\r\nContent-Length: 220\r\n\r\n--segment\r\nContent-Type: text/plain\r\nContent-Length: 55\r\n\r\nhow are you today?\r\nI do not know. I guess I am:\n'fine'\r\n\r\n--segment\r\nContent-Type: text/xml; charset=UTF-8\r\nContent-Length: 22\r\n\r\n<llsd><undef /></llsd>\r\n\r\n");
std::stringstream istr;
istr.str(SERIALIZED_MIME);
LLMimeIndex mime;
LLMimeParser parser;
bool ok = parser.parseIndex(istr, mime);
ensure("Parse successful.", ok);
ensure("is multipart.", mime.isMultipart());
ensure_equals("sub-part count", mime.subPartCount(), 2);
ensure_equals("content length", mime.contentLength(), 220);
LLMimeIndex mime_plain(mime.subPart(0));
ensure_equals(
"first part type",
mime_plain.contentType(),
"text/plain");
ensure_equals(
"first part content length",
mime_plain.contentLength(),
55);
LLMimeIndex mime_xml(mime.subPart(1));
ensure_equals(
"second part type",
mime_xml.contentType(),
"text/xml; charset=UTF-8");
ensure_equals(
"second part content length",
mime_xml.contentLength(),
22);
}
template<> template<>
void mime_parse_object_t::test<6>()
{
// test multi-part with no specified boundary and eof
/*
Content-Type: multipart/relatedrnContent-Length: 220rnrn--rnContent-Type: text/plainrnContent-Length: 55rnrnhow are you today?rnI do not know. I guess I am:n'fine'rnrn--rnContent-Type: text/xml; charset=UTF-8rnContent-Length: 22rnrn<llsd><undef /></llsd>rnrn
*/
const std::string SERIALIZED_MIME("Content-Type: multipart/related\r\nContent-Length: 500\r\n\r\n--\r\nContent-Type: text/plain\r\nContent-Length: 55\r\n\r\nhow are you today?\r\nI do not know. I guess I am:\n'fine'\r\n\r\n--\r\nContent-Type: text/xml; charset=UTF-8\r\nContent-Length: 22\r\n\r\n<llsd><undef /></llsd>\r\n\r\n");
std::stringstream istr;
istr.str(SERIALIZED_MIME);
LLMimeIndex mime;
LLMimeParser parser;
bool ok = parser.parseIndex(istr, mime);
ensure("Parse successful.", ok);
ensure("is multipart.", mime.isMultipart());
ensure_equals("sub-part count", mime.subPartCount(), 2);
ensure_equals("content length", mime.contentLength(), 500);
ensure_equals("data offset for multipart", mime.offset(), 56);
LLMimeIndex mime_plain(mime.subPart(0));
ensure_equals(
"first part type",
mime_plain.contentType(),
"text/plain");
ensure_equals(
"first part content length",
mime_plain.contentLength(),
55);
ensure_equals("first part offset", mime_plain.offset(), 108);
LLMimeIndex mime_xml(mime.subPart(1));
ensure_equals(
"second part type",
mime_xml.contentType(),
"text/xml; charset=UTF-8");
ensure_equals(
"second part content length",
mime_xml.contentLength(),
22);
ensure_equals("second part offset", mime_xml.offset(), 232);
}
/*
template<> template<>
void mime_parse_object_t::test<>()
{
}
template<> template<>
void mime_parse_object_t::test<>()
{
}
template<> template<>
void mime_parse_object_t::test<>()
{
}
template<> template<>
void mime_parse_object_t::test<>()
{
}
*/
}

View File

@@ -0,0 +1,81 @@
/**
* @file modularmath_tut.cpp
* @author babbage
* @date 2008-09
* @brief llcircuit tests
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "lltut.h"
#include "llmodularmath.h"
namespace tut
{
struct modularmath_data
{
};
typedef test_group<modularmath_data> modularmath_test;
typedef modularmath_test::object modularmath_object;
tut::modularmath_test modularmath_testcase("modularmath");
template<> template<>
void modularmath_object::test<1>()
{
// lhs < rhs
const U32 lhs = 0x000001;
const U32 rhs = 0xFFFFFF;
const U32 width = 24;
U32 result = LLModularMath::subtract<width>(lhs, rhs);
ensure_equals("diff(0x000001, 0xFFFFFF, 24)", result, 2);
}
template<> template<>
void modularmath_object::test<2>()
{
// lhs > rhs
const U32 lhs = 0x000002;
const U32 rhs = 0x000001;
const U32 width = 24;
U32 result = LLModularMath::subtract<width>(lhs, rhs);
ensure_equals("diff(0x000002, 0x000001, 24)", result, 1);
}
template<> template<>
void modularmath_object::test<3>()
{
// lhs == rhs
const U32 lhs = 0xABCDEF;
const U32 rhs = 0xABCDEF;
const U32 width = 24;
U32 result = LLModularMath::subtract<width>(lhs, rhs);
ensure_equals("diff(0xABCDEF, 0xABCDEF, 24)", result, 0);
}
}

View File

@@ -0,0 +1,409 @@
/**
* @file llnamevalue_tut.cpp
* @author Adroit
* @date 2007-02
* @brief LLNameValue unit test
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "lltut.h"
#include "llnamevalue.h"
#include "llsdserialize.h"
#if LL_WINDOWS
// disable unreachable code warnings
#pragma warning(disable: 4702)
#endif
namespace tut
{
struct namevalue_test
{
namevalue_test()
{
}
};
typedef test_group<namevalue_test> namevalue_t;
typedef namevalue_t::object namevalue_object_t;
tut::namevalue_t tut_namevalue("namevalue_test");
template<> template<>
void namevalue_object_t::test<1>()
{
// LLNameValue()
LLNameValue nValue;
ensure("mName should have been NULL", nValue.mName == NULL);
ensure("getTypeEnum failed",nValue.getTypeEnum() == NVT_NULL);
ensure("getClassEnum failed",nValue.getClassEnum() == NVC_NULL);
ensure("getSendtoEnum failed",nValue.getSendtoEnum() == NVS_NULL);
LLNameValue nValue1(" SecondLife ASSET RW SIM 232324343");
}
// LLNameValue(const char* data);
// LLNameValue(const char* name, const char* data, const char* type, const char* nvclass, const char* nvsendto,
// TNameValueCallback nvcb = NULL, void** user_data = NULL);
template<> template<>
void namevalue_object_t::test<2>()
{
LLNameValue nValue(" SecondLife ASSET RW S 232324343");
ensure("mName not set correctly", (0 == strcmp(nValue.mName,"SecondLife")));
ensure("getTypeEnum failed", nValue.getTypeEnum() == NVT_ASSET);
ensure("getClassEnum failed", nValue.getClassEnum() == NVC_READ_WRITE);
ensure("getSendtoEnum failed", nValue.getSendtoEnum() == NVS_SIM);
ensure("getString failed", (0==strcmp(nValue.getAsset(),"232324343")));
ensure("sendToData or sendToViewer failed", !nValue.sendToData() && !nValue.sendToViewer());
LLNameValue nValue1("\n\r SecondLife_1 STRING READ_WRITE SIM 232324343");
ensure("1. mName not set correctly", (0 == strcmp(nValue1.mName,"SecondLife_1")));
ensure("1. getTypeEnum failed", nValue1.getTypeEnum() == NVT_STRING);
ensure("1. getClassEnum failed", nValue1.getClassEnum() == NVC_READ_WRITE);
ensure("1. getSendtoEnum failed", nValue1.getSendtoEnum() == NVS_SIM);
ensure("1. getString failed", (0==strcmp(nValue1.getString(),"232324343")));
ensure("1. sendToData or sendToViewer failed", !nValue1.sendToData() && !nValue1.sendToViewer());
LLNameValue nValue2("SecondLife", "23.5", "F32", "R", "DS");
ensure("2. getTypeEnum failed", nValue2.getTypeEnum() == NVT_F32);
ensure("2. getClassEnum failed", nValue2.getClassEnum() == NVC_READ_ONLY);
ensure("2. getSendtoEnum failed", nValue2.getSendtoEnum() == NVS_DATA_SIM);
ensure("2. getF32 failed", *nValue2.getF32() == 23.5f);
ensure("2. sendToData or sendToViewer failed", nValue2.sendToData() && !nValue2.sendToViewer());
LLNameValue nValue3("SecondLife", "-43456787", "S32", "READ_ONLY", "SIM_SPACE");
ensure("3. getTypeEnum failed", nValue3.getTypeEnum() == NVT_S32);
ensure("3. getClassEnum failed", nValue3.getClassEnum() == NVC_READ_ONLY);
ensure("3. getSendtoEnum failed", nValue3.getSendtoEnum() == NVS_DATA_SIM);
ensure("3. getS32 failed", *nValue3.getS32() == -43456787);
ensure("sendToData or sendToViewer failed", nValue3.sendToData() && !nValue3.sendToViewer());
LLNameValue nValue4("SecondLife", "<1.0, 2.0, 3.0>", "VEC3", "RW", "SV");
LLVector3 llvec4(1.0, 2.0, 3.0);
ensure("4. getTypeEnum failed", nValue4.getTypeEnum() == NVT_VEC3);
ensure("4. getClassEnum failed", nValue4.getClassEnum() == NVC_READ_WRITE);
ensure("4. getSendtoEnum failed", nValue4.getSendtoEnum() == NVS_SIM_VIEWER);
ensure("4. getVec3 failed", *nValue4.getVec3() == llvec4);
ensure("4. sendToData or sendToViewer failed", !nValue4.sendToData() && nValue4.sendToViewer());
LLNameValue nValue5("SecondLife", "-1.0, 2.4, 3", "VEC3", "RW", "SIM_VIEWER");
LLVector3 llvec5(-1.0f, 2.4f, 3);
ensure("5. getTypeEnum failed", nValue5.getTypeEnum() == NVT_VEC3);
ensure("5. getClassEnum failed", nValue5.getClassEnum() == NVC_READ_WRITE);
ensure("5. getSendtoEnum failed", nValue5.getSendtoEnum() == NVS_SIM_VIEWER);
ensure("5. getVec3 failed", *nValue5.getVec3() == llvec5);
ensure("5. sendToData or sendToViewer failed", !nValue5.sendToData() && nValue5.sendToViewer());
LLNameValue nValue6("SecondLife", "89764323", "U32", "RW", "DSV");
ensure("6. getTypeEnum failed", nValue6.getTypeEnum() == NVT_U32);
ensure("6. getClassEnum failed", nValue6.getClassEnum() == NVC_READ_WRITE);
ensure("6. getSendtoEnum failed", nValue6.getSendtoEnum() == NVS_DATA_SIM_VIEWER);
ensure("6. getU32 failed", *nValue6.getU32() == 89764323);
ensure("6. sendToData or sendToViewer failed", nValue6.sendToData() && nValue6.sendToViewer());
LLNameValue nValue7("SecondLife", "89764323323232", "U64", "RW", "SIM_SPACE_VIEWER");
U64 u64_7 = U64L(89764323323232);
ensure("7. getTypeEnum failed", nValue7.getTypeEnum() == NVT_U64);
ensure("7. getClassEnum failed", nValue7.getClassEnum() == NVC_READ_WRITE);
ensure("7. getSendtoEnum failed", nValue7.getSendtoEnum() == NVS_DATA_SIM_VIEWER);
ensure("7. getU32 failed", *nValue7.getU64() == u64_7);
ensure("7. sendToData or sendToViewer failed", nValue7.sendToData() && nValue7.sendToViewer());
}
// LLNameValue(const char* name, const char* data, const char* type, const char* nvclass,
// TNameValueCallback nvcb = NULL, void** user_data = NULL);
template<> template<>
void namevalue_object_t::test<3>()
{
LLNameValue nValue("SecondLife", "232324343", "ASSET", "READ_WRITE");
ensure("mName not set correctly", (0 == strcmp(nValue.mName,"SecondLife")));
ensure("getTypeEnum failed", nValue.getTypeEnum() == NVT_ASSET);
ensure("getClassEnum failed", nValue.getClassEnum() == NVC_READ_WRITE);
ensure("getSendtoEnum failed", nValue.getSendtoEnum() == NVS_SIM);
ensure("getString failed", (0==strcmp(nValue.getAsset(),"232324343")));
LLNameValue nValue1("SecondLife", "232324343", "STRING", "READ_WRITE");
ensure("1. mName not set correctly", (0 == strcmp(nValue1.mName,"SecondLife")));
ensure("1. getTypeEnum failed", nValue1.getTypeEnum() == NVT_STRING);
ensure("1. getClassEnum failed", nValue1.getClassEnum() == NVC_READ_WRITE);
ensure("1. getSendtoEnum failed", nValue1.getSendtoEnum() == NVS_SIM);
ensure("1. getString failed", (0==strcmp(nValue1.getString(),"232324343")));
LLNameValue nValue2("SecondLife", "23.5", "F32", "R");
ensure("2. getTypeEnum failed", nValue2.getTypeEnum() == NVT_F32);
ensure("2. getClassEnum failed", nValue2.getClassEnum() == NVC_READ_ONLY);
ensure("2. getSendtoEnum failed", nValue2.getSendtoEnum() == NVS_SIM);
ensure("2. getF32 failed", *nValue2.getF32() == 23.5f);
LLNameValue nValue3("SecondLife", "-43456787", "S32", "READ_ONLY");
ensure("3. getTypeEnum failed", nValue3.getTypeEnum() == NVT_S32);
ensure("3. getClassEnum failed", nValue3.getClassEnum() == NVC_READ_ONLY);
ensure("3. getSendtoEnum failed", nValue3.getSendtoEnum() == NVS_SIM);
ensure("3. getS32 failed", *nValue3.getS32() == -43456787);
LLNameValue nValue4("SecondLife", "<1.0, 2.0, 3.0>", "VEC3", "RW");
LLVector3 llvec4(1.0, 2.0, 3.0);
ensure("4. getTypeEnum failed", nValue4.getTypeEnum() == NVT_VEC3);
ensure("4. getClassEnum failed", nValue4.getClassEnum() == NVC_READ_WRITE);
ensure("4. getSendtoEnum failed", nValue4.getSendtoEnum() == NVS_SIM);
ensure("4. getVec3 failed", *nValue4.getVec3() == llvec4);
LLNameValue nValue5("SecondLife", "-1.0, 2.4, 3", "VEC3", "RW");
LLVector3 llvec5(-1.0f, 2.4f, 3);
ensure("5. getTypeEnum failed", nValue5.getTypeEnum() == NVT_VEC3);
ensure("5. getClassEnum failed", nValue5.getClassEnum() == NVC_READ_WRITE);
ensure("5. getSendtoEnum failed", nValue5.getSendtoEnum() == NVS_SIM);
ensure("5. getVec3 failed", *nValue5.getVec3() == llvec5);
LLNameValue nValue6("SecondLife", "89764323", "U32", "RW");
ensure("6. getTypeEnum failed", nValue6.getTypeEnum() == NVT_U32);
ensure("6. getClassEnum failed", nValue6.getClassEnum() == NVC_READ_WRITE);
ensure("6. getSendtoEnum failed", nValue6.getSendtoEnum() == NVS_SIM);
ensure("6. getU32 failed", *nValue6.getU32() == 89764323);
LLNameValue nValue7("SecondLife", "89764323323232", "U64", "RW");
U64 u64_7 = U64L(89764323323232);
ensure("7. getTypeEnum failed", nValue7.getTypeEnum() == NVT_U64);
ensure("7. getClassEnum failed", nValue7.getClassEnum() == NVC_READ_WRITE);
ensure("7. getSendtoEnum failed", nValue7.getSendtoEnum() == NVS_SIM);
ensure("7. getU32 failed", *nValue7.getU64() == u64_7);
}
// LLNameValue(const char* name, const char* type, const char* nvclass,
// TNameValueCallback nvcb = NULL, void** user_data = NULL);
template<> template<>
void namevalue_object_t::test<4>()
{
LLNameValue nValue("SecondLife", "STRING", "READ_WRITE");
ensure("mName not set correctly", (0 == strcmp(nValue.mName,"SecondLife")));
ensure("getTypeEnum failed", nValue.getTypeEnum() == NVT_STRING);
ensure("getClassEnum failed", nValue.getClassEnum() == NVC_READ_WRITE);
ensure("getSendtoEnum failed", nValue.getSendtoEnum() == NVS_SIM);
LLNameValue nValue1("SecondLife", "ASSET", "READ_WRITE");
ensure("1. mName not set correctly", (0 == strcmp(nValue1.mName,"SecondLife")));
ensure("1. getTypeEnum for RW failed", nValue1.getTypeEnum() == NVT_ASSET);
ensure("1. getClassEnum for RW failed", nValue1.getClassEnum() == NVC_READ_WRITE);
ensure("1. getSendtoEnum for RW failed", nValue1.getSendtoEnum() == NVS_SIM);
LLNameValue nValue2("SecondLife", "F32", "READ_ONLY");
ensure("2. getTypeEnum failed", nValue2.getTypeEnum() == NVT_F32);
ensure("2. getClassEnum failed", nValue2.getClassEnum() == NVC_READ_ONLY);
ensure("2. getSendtoEnum failed", nValue2.getSendtoEnum() == NVS_SIM);
LLNameValue nValue3("SecondLife", "S32", "READ_ONLY");
ensure("3. getTypeEnum failed", nValue3.getTypeEnum() == NVT_S32);
ensure("3. getClassEnum failed", nValue3.getClassEnum() == NVC_READ_ONLY);
ensure("3. getSendtoEnum failed", nValue3.getSendtoEnum() == NVS_SIM);
LLNameValue nValue4("SecondLife", "VEC3", "READ_WRITE");
ensure("4. getTypeEnum failed", nValue4.getTypeEnum() == NVT_VEC3);
ensure("4. getClassEnum failed", nValue4.getClassEnum() == NVC_READ_WRITE);
ensure("4. getSendtoEnum failed", nValue4.getSendtoEnum() == NVS_SIM);
LLNameValue nValue6("SecondLife", "U32", "READ_WRITE");
ensure("6. getTypeEnum failed", nValue6.getTypeEnum() == NVT_U32);
ensure("6. getClassEnum failed", nValue6.getClassEnum() == NVC_READ_WRITE);
ensure("6. getSendtoEnum failed", nValue6.getSendtoEnum() == NVS_SIM);
LLNameValue nValue7("SecondLife", "U64", "READ_WRITE");
ensure("7. getTypeEnum failed", nValue7.getTypeEnum() == NVT_U64);
ensure("7. getClassEnum failed", nValue7.getClassEnum() == NVC_READ_WRITE);
ensure("7. getSendtoEnum failed", nValue7.getSendtoEnum() == NVS_SIM);
}
template<> template<>
void namevalue_object_t::test<5>()
{
LLNameValue nValue("SecondLife", "This is a test", "STRING", "RW", "SIM");
ensure("getString failed", (0 == strcmp(nValue.getString(),"This is a test")));
}
template<> template<>
void namevalue_object_t::test<6>()
{
LLNameValue nValue("SecondLife", "This is a test", "ASSET", "RW", "S");
ensure("getAsset failed", (0 == strcmp(nValue.getAsset(),"This is a test")));
}
template<> template<>
void namevalue_object_t::test<7>()
{
LLNameValue nValue("SecondLife", "555555", "F32", "RW", "SIM");
ensure("getF32 failed",*nValue.getF32() == 555555.f);
}
template<> template<>
void namevalue_object_t::test<8>()
{
LLNameValue nValue("SecondLife", "-5555", "S32", "RW", "SIM");
ensure("getS32 failed", *nValue.getS32() == -5555);
S32 sVal = 0x7FFFFFFF;
nValue.setS32(sVal);
ensure("getS32 failed", *nValue.getS32() == sVal);
sVal = -0x7FFFFFFF;
nValue.setS32(sVal);
ensure("getS32 failed", *nValue.getS32() == sVal);
sVal = 0;
nValue.setS32(sVal);
ensure("getS32 failed", *nValue.getS32() == sVal);
}
template<> template<>
void namevalue_object_t::test<9>()
{
LLNameValue nValue("SecondLife", "<-3, 2, 1>", "VEC3", "RW", "SIM");
LLVector3 vecExpected(-3, 2, 1);
LLVector3 vec;
nValue.getVec3(vec);
ensure("getVec3 failed", vec == vecExpected);
}
template<> template<>
void namevalue_object_t::test<10>()
{
LLNameValue nValue("SecondLife", "12345678", "U32", "RW", "SIM");
ensure("getU32 failed",*nValue.getU32() == 12345678);
U32 val = 0xFFFFFFFF;
nValue.setU32(val);
ensure("U32 max", *nValue.getU32() == val);
val = 0;
nValue.setU32(val);
ensure("U32 min", *nValue.getU32() == val);
}
template<> template<>
void namevalue_object_t::test<11>()
{
//skip_fail("incomplete support for U64.");
LLNameValue nValue("SecondLife", "44444444444", "U64", "RW", "SIM");
ensure("getU64 failed",*nValue.getU64() == U64L(44444444444));
// there is no LLNameValue::setU64()
}
template<> template<>
void namevalue_object_t::test<12>()
{
//skip_fail("incomplete support for U64.");
LLNameValue nValue("SecondLife U64 RW DSV 44444444444");
std::string ret_str = nValue.printNameValue();
ensure_equals("1:printNameValue failed",ret_str,"SecondLife U64 RW DSV 44444444444");
LLNameValue nValue1(ret_str.c_str());
ensure_equals("Serialization of printNameValue failed", *nValue.getU64(), *nValue1.getU64());
}
template<> template<>
void namevalue_object_t::test<13>()
{
LLNameValue nValue("SecondLife STRING RW DSV 44444444444");
std::string ret_str = nValue.printData();
ensure_equals("1:printData failed",ret_str,"44444444444");
LLNameValue nValue1("SecondLife S32 RW DSV 44444");
ret_str = nValue1.printData();
ensure_equals("2:printData failed",ret_str,"44444");
}
template<> template<>
void namevalue_object_t::test<14>()
{
LLNameValue nValue("SecodLife STRING RW SIM 22222");
std::ostringstream stream1,stream2,stream3, stream4, stream5;
stream1 << nValue;
ensure_equals("STRING << failed",stream1.str(),"22222");
LLNameValue nValue1("SecodLife F32 RW SIM 22222");
stream2 << nValue1;
ensure_equals("F32 << failed",stream2.str(),"22222");
LLNameValue nValue2("SecodLife S32 RW SIM 22222");
stream3<< nValue2;
ensure_equals("S32 << failed",stream3.str(),"22222");
LLNameValue nValue3("SecodLife U32 RW SIM 122222");
stream4<< nValue3;
ensure_equals("U32 << failed",stream4.str(),"122222");
// I don't think we use U64 name value pairs. JC
//skip_fail("incomplete support for U64.");
//LLNameValue nValue4("SecodLife U64 RW SIM 22222");
//stream5<< nValue4;
//ensure("U64 << failed",0 == strcmp((stream5.str()).c_str(),"22222"));
}
template<> template<>
void namevalue_object_t::test<15>()
{
LLNameValue nValue("SecondLife", "This is a test", "ASSET", "R", "S");
ensure("getAsset failed", (0 == strcmp(nValue.getAsset(),"This is a test")));
// this should not have updated as it is read only.
nValue.setAsset("New Value should not be updated");
ensure("setAsset on ReadOnly failed", (0 == strcmp(nValue.getAsset(),"This is a test")));
LLNameValue nValue1("SecondLife", "1234", "U32", "R", "S");
// this should not have updated as it is read only.
nValue1.setU32(4567);
ensure("setU32 on ReadOnly failed", *nValue1.getU32() == 1234);
LLNameValue nValue2("SecondLife", "1234", "S32", "R", "S");
// this should not have updated as it is read only.
nValue2.setS32(4567);
ensure("setS32 on ReadOnly failed", *nValue2.getS32() == 1234);
LLNameValue nValue3("SecondLife", "1234", "F32", "R", "S");
// this should not have updated as it is read only.
nValue3.setF32(4567);
ensure("setF32 on ReadOnly failed", *nValue3.getF32() == 1234);
LLNameValue nValue4("SecondLife", "<1,2,3>", "VEC3", "R", "S");
// this should not have updated as it is read only.
LLVector3 vec(4,5,6);
nValue3.setVec3(vec);
LLVector3 vec1(1,2,3);
ensure("setVec3 on ReadOnly failed", *nValue4.getVec3() == vec1);
// cant test for U64 as no set64 exists nor any operators support U64 type
}
}

View File

@@ -0,0 +1,221 @@
/**
* @file llpartdata_tut.cpp
* @author Adroit
* @date March 2007
* @brief LLPartData and LLPartSysData test cases.
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "lltut.h"
#include "linden_common.h"
#include "lldatapacker.h"
#include "llpartdata.h"
#include "v3math.h"
#include "llsdserialize.h"
#include "message.h"
namespace tut
{
struct partdata_test
{
};
typedef test_group<partdata_test> partdata_test_t;
typedef partdata_test_t::object partdata_test_object_t;
tut::partdata_test_t tut_partdata_test("partdata_test");
template<> template<>
void partdata_test_object_t::test<1>()
{
LLPartData llpdata,llpdata1;
U8 pkbuf[128];
llpdata.setFlags(LLPartData::LL_PART_INTERP_COLOR_MASK | LLPartData::LL_PART_INTERP_SCALE_MASK |
LLPartData::LL_PART_BOUNCE_MASK | LLPartData::LL_PART_WIND_MASK | LLPartData::LL_PART_FOLLOW_SRC_MASK |
LLPartData::LL_PART_FOLLOW_VELOCITY_MASK | LLPartData::LL_PART_TARGET_POS_MASK | LLPartData::LL_PART_TARGET_LINEAR_MASK |
LLPartData::LL_PART_EMISSIVE_MASK | LLPartData::LL_PART_BEAM_MASK | LLPartData::LL_PART_DEAD_MASK);
llpdata.setMaxAge(29.3f);
LLVector3 llvec1(1.0f, .5f, .25f);
llpdata.setStartColor(llvec1);
llpdata.setStartAlpha(.7f);
LLVector3 llvec2(.2f, .3f, 1.0f);
llpdata.setEndColor(llvec2);
llpdata.setEndAlpha(1.0f);
llpdata.setStartScale(3.23f, 4.0f);
llpdata.setEndScale(2.4678f, 1.0f);
LLDataPackerBinaryBuffer dp((U8*)pkbuf, 128);
llpdata.pack(dp);
S32 cur_size = dp.getCurrentSize();
LLDataPackerBinaryBuffer dp1((U8*)pkbuf, cur_size);
llpdata1.unpack(dp1);
ensure("1.mFlags values are different after unpacking", llpdata1.mFlags == llpdata.mFlags);
ensure_approximately_equals("2.mMaxAge values are different after unpacking", llpdata1.mMaxAge, llpdata.mMaxAge, 8);
ensure_approximately_equals("3.mStartColor[0] values are different after unpacking", llpdata1.mStartColor.mV[0], llpdata.mStartColor.mV[0], 8);
ensure_approximately_equals("4.mStartColor[1] values are different after unpacking", llpdata1.mStartColor.mV[1], llpdata.mStartColor.mV[1], 8);
ensure_approximately_equals("5.mStartColor[2] values are different after unpacking", llpdata1.mStartColor.mV[2], llpdata.mStartColor.mV[2], 8);
ensure_approximately_equals("6.mStartColor[3] values are different after unpacking", llpdata1.mStartColor.mV[3], llpdata.mStartColor.mV[3], 8);
ensure_approximately_equals("7.mEndColor[0] values are different after unpacking", llpdata1.mEndColor.mV[0], llpdata.mEndColor.mV[0], 8);
ensure_approximately_equals("8.mEndColor[1] values are different after unpacking", llpdata1.mEndColor.mV[1], llpdata.mEndColor.mV[1], 8);
ensure_approximately_equals("9.mEndColor[2] values are different after unpacking", llpdata1.mEndColor.mV[2], llpdata.mEndColor.mV[2], 8);
ensure_approximately_equals("10.mEndColor[2] values are different after unpacking", llpdata1.mEndColor.mV[3], llpdata.mEndColor.mV[3], 8);
ensure_approximately_equals("11.mStartScale[0] values are different after unpacking", llpdata1.mStartScale.mV[0], llpdata.mStartScale.mV[0], 5);
ensure_approximately_equals("12.mStartScale[1] values are different after unpacking", llpdata1.mStartScale.mV[1], llpdata.mStartScale.mV[1], 5);
ensure_approximately_equals("13.mEndScale[0] values are different after unpacking", llpdata1.mEndScale.mV[0], llpdata.mEndScale.mV[0], 5);
ensure_approximately_equals("14.mEndScale[1] values are different after unpacking", llpdata1.mEndScale.mV[1], llpdata.mEndScale.mV[1], 5);
}
template<> template<>
void partdata_test_object_t::test<2>()
{
LLPartData llpdata,llpdata1;
llpdata.setFlags(LLPartData::LL_PART_INTERP_COLOR_MASK | LLPartData::LL_PART_INTERP_SCALE_MASK |
LLPartData::LL_PART_BOUNCE_MASK | LLPartData::LL_PART_WIND_MASK | LLPartData::LL_PART_FOLLOW_SRC_MASK |
LLPartData::LL_PART_FOLLOW_VELOCITY_MASK | LLPartData::LL_PART_TARGET_POS_MASK | LLPartData::LL_PART_TARGET_LINEAR_MASK |
LLPartData::LL_PART_EMISSIVE_MASK | LLPartData::LL_PART_BEAM_MASK | LLPartData::LL_PART_DEAD_MASK);
llpdata.setMaxAge(29.3f);
LLVector3 llvec1(1.0f, .5f, .25f);
llpdata.setStartColor(llvec1);
llpdata.setStartAlpha(.7f);
LLVector3 llvec2(.2f, .3f, 1.0f);
llpdata.setEndColor(llvec2);
llpdata.setEndAlpha(1.0f);
llpdata.setStartScale(3.23f, 4.0f);
llpdata.setEndScale(2.4678f, 1.0f);
LLSD llsd = llpdata.asLLSD();
llpdata1.fromLLSD(llsd);
ensure("1.mFlags values are different after unpacking", llpdata1.mFlags == llpdata.mFlags);
ensure_approximately_equals("2.mMaxAge values are different after unpacking", llpdata1.mMaxAge, llpdata.mMaxAge, 8);
ensure_approximately_equals("3.mStartColor[0] values are different after unpacking", llpdata1.mStartColor.mV[0], llpdata.mStartColor.mV[0], 8);
ensure_approximately_equals("4.mStartColor[1] values are different after unpacking", llpdata1.mStartColor.mV[1], llpdata.mStartColor.mV[1], 8);
ensure_approximately_equals("5.mStartColor[2] values are different after unpacking", llpdata1.mStartColor.mV[2], llpdata.mStartColor.mV[2], 8);
ensure_approximately_equals("6.mStartColor[3] values are different after unpacking", llpdata1.mStartColor.mV[3], llpdata.mStartColor.mV[3], 8);
ensure_approximately_equals("7.mEndColor[0] values are different after unpacking", llpdata1.mEndColor.mV[0], llpdata.mEndColor.mV[0], 8);
ensure_approximately_equals("8.mEndColor[1] values are different after unpacking", llpdata1.mEndColor.mV[1], llpdata.mEndColor.mV[1], 8);
ensure_approximately_equals("9.mEndColor[2] values are different after unpacking", llpdata1.mEndColor.mV[2], llpdata.mEndColor.mV[2], 8);
ensure_approximately_equals("10.mEndColor[2] values are different after unpacking", llpdata1.mEndColor.mV[3], llpdata.mEndColor.mV[3], 8);
ensure_approximately_equals("11.mStartScale[0] values are different after unpacking", llpdata1.mStartScale.mV[0], llpdata.mStartScale.mV[0], 5);
ensure_approximately_equals("12.mStartScale[1] values are different after unpacking", llpdata1.mStartScale.mV[1], llpdata.mStartScale.mV[1], 5);
ensure_approximately_equals("13.mEndScale[0] values are different after unpacking", llpdata1.mEndScale.mV[0], llpdata.mEndScale.mV[0], 5);
ensure_approximately_equals("14.mEndScale[1] values are different after unpacking", llpdata1.mEndScale.mV[1], llpdata.mEndScale.mV[1], 5);
}
//*********llpartsysdata***********
template<> template<>
void partdata_test_object_t::test<3>()
{
LLPartSysData llpsysdata, llpsysdata1;
U8 pkbuf[256];
llpsysdata.setBurstSpeedMin(33.33f);
ensure("1.mBurstSpeedMin coudnt be set", 33.33f == llpsysdata.mBurstSpeedMin);
llpsysdata.setBurstSpeedMax(44.44f);
ensure("2.mBurstSpeedMax coudnt be set", 44.44f == llpsysdata.mBurstSpeedMax);
llpsysdata.setBurstRadius(45.55f);
ensure("3.mBurstRadius coudnt be set", 45.55f == llpsysdata.mBurstRadius);
LLVector3 llvec(44.44f, 111.11f, -40.4f);
llpsysdata.setPartAccel(llvec);
llpsysdata.mCRC = 0xFFFFFFFF;
llpsysdata.mFlags = 0x20;
llpsysdata.mPattern = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE_EMPTY;
llpsysdata.mMaxAge = 99.99f;
llpsysdata.mStartAge = 18.5f;
llpsysdata.mInnerAngle = 4.234f;
llpsysdata.mOuterAngle = 7.123f;
llpsysdata.mBurstRate = 245.53f;
llpsysdata.mBurstPartCount = 0xFF;
llpsysdata.mAngularVelocity = llvec;
llpsysdata.mPartImageID.generate();
llpsysdata.mTargetUUID.generate();
LLDataPackerBinaryBuffer dp((U8*)pkbuf, 256);
llpsysdata.pack(dp);
S32 cur_size = dp.getCurrentSize();
LLDataPackerBinaryBuffer dp1((U8*)pkbuf, cur_size);
llpsysdata1.unpack(dp1);
ensure("1.mCRC's not equal", llpsysdata.mCRC == llpsysdata1.mCRC);
ensure("2.mFlags's not equal", llpsysdata.mFlags == llpsysdata1.mFlags);
ensure("3.mPattern's not equal", llpsysdata.mPattern == llpsysdata1.mPattern);
ensure_approximately_equals("4.mMaxAge's not equal", llpsysdata.mMaxAge , llpsysdata1.mMaxAge, 8);
ensure_approximately_equals("5.mStartAge's not equal", llpsysdata.mStartAge, llpsysdata1.mStartAge, 8);
ensure_approximately_equals("6.mOuterAngle's not equal", llpsysdata.mOuterAngle, llpsysdata1.mOuterAngle, 5);
ensure_approximately_equals("7.mInnerAngles's not equal", llpsysdata.mInnerAngle, llpsysdata1.mInnerAngle, 5);
ensure_approximately_equals("8.mBurstRate's not equal", llpsysdata.mBurstRate, llpsysdata1.mBurstRate, 8);
ensure("9.mBurstPartCount's not equal", llpsysdata.mBurstPartCount == llpsysdata1.mBurstPartCount);
ensure_approximately_equals("10.mBurstSpeedMin's not equal", llpsysdata.mBurstSpeedMin, llpsysdata1.mBurstSpeedMin, 8);
ensure_approximately_equals("11.mBurstSpeedMax's not equal", llpsysdata.mBurstSpeedMax, llpsysdata1.mBurstSpeedMax, 8);
ensure_approximately_equals("12.mAngularVelocity's not equal", llpsysdata.mAngularVelocity.mV[0], llpsysdata1.mAngularVelocity.mV[0], 7);
ensure_approximately_equals("13.mAngularVelocity's not equal", llpsysdata.mAngularVelocity.mV[1], llpsysdata1.mAngularVelocity.mV[1], 7);
ensure_approximately_equals("14.mAngularVelocity's not equal", llpsysdata.mAngularVelocity.mV[2], llpsysdata1.mAngularVelocity.mV[2], 7);
ensure_approximately_equals("15.mPartAccel's not equal", llpsysdata.mPartAccel.mV[0], llpsysdata1.mPartAccel.mV[0], 7);
ensure_approximately_equals("16.mPartAccel's not equal", llpsysdata.mPartAccel.mV[1], llpsysdata1.mPartAccel.mV[1], 7);
ensure_approximately_equals("17.mPartAccel's not equal", llpsysdata.mPartAccel.mV[2], llpsysdata1.mPartAccel.mV[2], 7);
ensure("18.mPartImageID's not equal", llpsysdata.mPartImageID == llpsysdata1.mPartImageID);
ensure("19.mTargetUUID's not equal", llpsysdata.mTargetUUID == llpsysdata1.mTargetUUID);
ensure_approximately_equals("20.mBurstRadius's not equal", llpsysdata.mBurstRadius, llpsysdata1.mBurstRadius, 8);
}
}

View File

@@ -0,0 +1,558 @@
/**
* @file llpermissions_tut.cpp
* @author Adroit
* @date March 2007
* @brief llpermissions test cases.
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "lltut.h"
#include "message.h"
#include "llpermissions.h"
namespace tut
{
struct permission
{
};
typedef test_group<permission> permission_t;
typedef permission_t::object permission_object_t;
tut::permission_t tut_permission("permission");
template<> template<>
void permission_object_t::test<1>()
{
LLPermissions permissions;
LLUUID uuid = permissions.getCreator();
LLUUID uuid1 = permissions.getOwner();
LLUUID uuid2 = permissions.getGroup();
LLUUID uuid3 = permissions.getLastOwner();
ensure("LLPermission Get Functions failed", (uuid == LLUUID::null && uuid1 == LLUUID::null &&
uuid2 == LLUUID::null && uuid3 == LLUUID::null));
ensure("LLPermission Get Functions failed", (permissions.getMaskBase() == PERM_ALL && permissions.getMaskOwner() == PERM_ALL &&
permissions.getMaskGroup() == PERM_ALL && permissions.getMaskEveryone() == PERM_ALL && permissions.getMaskNextOwner() == PERM_ALL));
ensure("Ownership functions failed", (permissions.isGroupOwned() == FALSE && permissions.isOwned() == FALSE));
}
template<> template<>
void permission_object_t::test<2>()
{
LLPermissions permissions;
LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
permissions.init(creator, owner, lastOwner, group);
ensure_equals("init/getCreator():failed to return the creator ", creator, permissions.getCreator());
ensure_equals("init/getOwner():failed to return the owner ", owner, permissions.getOwner());
ensure_equals("init/getLastOwner():failed to return the group ", lastOwner, permissions.getLastOwner());
ensure_equals("init/getGroup():failed to return the group ", group, permissions.getGroup());
}
template<> template<>
void permission_object_t::test<3>()
{
LLPermissions permissions;
U32 base = PERM_ALL;
U32 owner = PERM_ITEM_UNRESTRICTED; //PERM_ITEM_UNRESTRICTED = PERM_MODIFY | PERM_COPY | PERM_TRANSFER;
U32 group = PERM_TRANSFER | PERM_MOVE | PERM_COPY|PERM_MODIFY;
U32 everyone = PERM_TRANSFER | PERM_MOVE | PERM_MODIFY;
U32 next = PERM_NONE;
U32 fixedbase = base;
U32 fixedowner = PERM_ITEM_UNRESTRICTED; //owner & fixedbase
U32 fixedgroup = PERM_ITEM_UNRESTRICTED; // no PERM_MOVE as owner does not have that perm either
U32 fixedeveryone = PERM_TRANSFER; // no PERM_MOVE. Everyone can never modify.
U32 fixednext = PERM_NONE;
permissions.initMasks(base, owner, everyone, group, next); // will fix perms if not allowed.
ensure_equals("initMasks/getMaskBase():failed to return the MaskBase ", fixedbase, permissions.getMaskBase());
ensure_equals("initMasks/getMaskOwner():failed to return the MaskOwner ", fixedowner, permissions.getMaskOwner());
ensure_equals("initMasks/getMaskEveryone():failed to return the MaskGroup ", fixedgroup, permissions.getMaskGroup());
ensure_equals("initMasks/getMaskEveryone():failed to return the MaskEveryone ", fixedeveryone, permissions.getMaskEveryone());
ensure_equals("initMasks/getMaskNextOwner():failed to return the MaskNext ", fixednext, permissions.getMaskNextOwner());
// explictly set should maintain the values
permissions.setMaskBase(base); //no fixing
ensure_equals("setMaskBase/getMaskBase():failed to return the MaskBase ", base, permissions.getMaskBase());
permissions.setMaskOwner(owner);
ensure_equals("setMaskOwner/getMaskOwner():failed to return the MaskOwner ", owner, permissions.getMaskOwner());
permissions.setMaskEveryone(everyone);
ensure_equals("setMaskEveryone/getMaskEveryone():failed to return the MaskEveryone ", everyone, permissions.getMaskEveryone());
permissions.setMaskGroup(group);
ensure_equals("setMaskGroup/getMaskEveryone():failed to return the MaskGroup ", group, permissions.getMaskGroup());
permissions.setMaskNext(next);
ensure_equals("setMaskNext/getMaskNextOwner():failed to return the MaskNext ", next, permissions.getMaskNextOwner());
// further tests can be added to ensure perms for owner/group/everyone etc. get properly fixed.
// code however suggests that there is no explict check if the perms are correct and the user of this
// class is expected to know how to use them correctly. skipping further test cases for now for various
// perm combinations.
}
template<> template<>
void permission_object_t::test<4>()
{
LLPermissions perm,perm1;
LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
perm1.init(creator,owner,lastOwner,group);
perm.set(perm1);
ensure("set():failed to set ", (creator == perm.getCreator()) && (owner == perm.getOwner())&&
(lastOwner == perm.getLastOwner())&& (group == perm.getGroup()));
}
template<> template<>
void permission_object_t::test<5>()
{
LLPermissions perm,perm1;
LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
perm1.init(creator,owner,lastOwner,group);
U32 base = PERM_TRANSFER;
U32 ownerp = PERM_TRANSFER;
U32 groupp = PERM_TRANSFER;
U32 everyone = PERM_TRANSFER;
U32 next = PERM_NONE;
perm1.initMasks(base, ownerp, everyone, groupp, next);
base = PERM_ALL;
ownerp = PERM_ITEM_UNRESTRICTED; //PERM_ITEM_UNRESTRICTED = PERM_MODIFY | PERM_COPY | PERM_TRANSFER;
groupp = PERM_TRANSFER | PERM_COPY|PERM_MODIFY;
everyone = PERM_TRANSFER;
next = PERM_NONE;
perm.init(creator,owner,lastOwner,group);
perm.initMasks(base, ownerp, everyone, groupp, next);
// restrict permissions by accumulation
perm.accumulate(perm1);
U32 fixedbase = PERM_TRANSFER | PERM_MOVE;
U32 fixedowner = PERM_TRANSFER;
U32 fixedgroup = PERM_TRANSFER;
U32 fixedeveryone = PERM_TRANSFER;
U32 fixednext = PERM_NONE;
ensure_equals("accumulate failed ", fixedbase, perm.getMaskBase());
ensure_equals("accumulate failed ", fixedowner, perm.getMaskOwner());
ensure_equals("accumulate failed ", fixedgroup, perm.getMaskGroup());
ensure_equals("accumulate failed ", fixedeveryone, perm.getMaskEveryone());
ensure_equals("accumulate failed ", fixednext, perm.getMaskNextOwner());
}
template<> template<>
void permission_object_t::test<6>()
{
LLPermissions perm;
LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
perm.init(creator,owner,lastOwner,group);
ensure_equals("getSafeOwner:failed ", owner,perm.getSafeOwner());
///NULL Owner
perm.init(creator,LLUUID::null,lastOwner,group);
ensure_equals("getSafeOwner:failed ", group, perm.getSafeOwner());
}
template<> template<>
void permission_object_t::test<7>()
{
LLPermissions perm1;
LLUUID uuid;
BOOL is_group_owned = FALSE;
ensure("1:getOwnership:failed ", (FALSE == perm1.getOwnership(uuid,is_group_owned)));
LLPermissions perm;
LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
perm.init(creator,owner,lastOwner,group);
perm.getOwnership(uuid,is_group_owned);
ensure("2:getOwnership:failed ", ((uuid == owner) && (FALSE == is_group_owned)));
perm.init(creator,LLUUID::null,lastOwner,group);
perm.getOwnership(uuid,is_group_owned);
ensure("3:getOwnership:failed ", ((uuid == group) && (TRUE == is_group_owned)));
}
template<> template<>
void permission_object_t::test<8>()
{
LLPermissions perm,perm1;
LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
perm.init(creator,owner,lastOwner,group);
perm1.init(creator,owner,lastOwner,group);
ensure_equals("getCRC32:failed ", perm.getCRC32(),perm1.getCRC32());
}
template<> template<>
void permission_object_t::test<9>()
{
LLPermissions perm;
LLUUID agent("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
bool is_atomic = TRUE;
ensure("setOwnerAndGroup():failed ", (TRUE == perm.setOwnerAndGroup(agent,owner,group,is_atomic)));
LLUUID owner2("68edcf47-ccd7-45b8-9f90-1649d7f12807");
LLUUID group2("9c8eca51-53d5-42a7-bb58-cef070395db9");
// cant change - agent need to be current owner
ensure("setOwnerAndGroup():failed ", (FALSE == perm.setOwnerAndGroup(agent,owner2,group2,is_atomic)));
// should be able to change - agent and owner same as current owner
ensure("setOwnerAndGroup():failed ", (TRUE == perm.setOwnerAndGroup(owner,owner,group2,is_atomic)));
}
template<> template<>
void permission_object_t::test<10>()
{
LLPermissions perm;
LLUUID agent;
LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
ensure("deedToGroup():failed ", (TRUE == perm.deedToGroup(agent,group)));
}
template<> template<>
void permission_object_t::test<11>()
{
LLPermissions perm;
LLUUID agent;
BOOL set = 1;
U32 bits = PERM_TRANSFER | PERM_MODIFY;
ensure("setBaseBits():failed ", (TRUE == perm.setBaseBits(agent, set, bits)));
ensure("setOwnerBits():failed ", (TRUE == perm.setOwnerBits(agent, set, bits)));
LLUUID agent1("9c8eca51-53d5-42a7-bb58-cef070395db8");
ensure("setBaseBits():failed ", (FALSE == perm.setBaseBits(agent1, set, bits)));
ensure("setOwnerBits():failed ", (FALSE == perm.setOwnerBits(agent1, set, bits)));
}
template<> template<>
void permission_object_t::test<12>()
{
LLPermissions perm;
LLUUID agent;
LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
BOOL set = 1;
U32 bits = 10;
ensure("setGroupBits():failed ", (TRUE == perm.setGroupBits(agent,group, set, bits)));
ensure("setEveryoneBits():failed ", (TRUE == perm.setEveryoneBits(agent,group, set, bits)));
ensure("setNextOwnerBits():failed ", (TRUE == perm.setNextOwnerBits(agent,group, set, bits)));
LLUUID agent1("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
ensure("setGroupBits():failed ", (FALSE == perm.setGroupBits(agent1,group, set, bits)));
ensure("setEveryoneBits():failed ", (FALSE == perm.setEveryoneBits(agent1,group, set, bits)));
ensure("setNextOwnerBits():failed ", (FALSE == perm.setNextOwnerBits(agent1,group, set, bits)));
}
template<> template<>
void permission_object_t::test<13>()
{
LLPermissions perm;
LLUUID agent;
LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
U32 bits = 10;
ensure("allowOperationBy():failed ", (TRUE == perm.allowOperationBy(bits,agent,group)));
LLUUID agent1("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
perm.init(creator,owner,lastOwner,group);
ensure("allowOperationBy():failed ", (TRUE == perm.allowOperationBy(bits,agent1,group)));
}
template<> template<>
void permission_object_t::test<14>()
{
LLPermissions perm;
LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
LLUUID owner;
LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
perm.init(creator,owner,lastOwner,group);
LLUUID agent;
ensure("1:allowModifyBy():failed ", (TRUE == perm.allowModifyBy(agent)));
ensure("2:allowModifyBy():failed ", (TRUE == perm.allowModifyBy(agent,group)));
U32 val1 = 0x7FFFFFFF;
S32 sVal = 1 << 14;
sVal = val1 & sVal;
LLUUID agent1("9c8eca51-53d5-42a7-bb58-cef070395db8");
ensure("3:allowModifyBy():failed ", (sVal == perm.allowModifyBy(agent1)));
ensure("4:allowModifyBy():failed ", (sVal == perm.allowModifyBy(agent1,group)));
}
template<> template<>
void permission_object_t::test<15>()
{
LLPermissions perm;
LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
LLUUID owner;
LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
perm.init(creator,owner,lastOwner,group);
LLUUID agent;
ensure("1:allowCopyBy():failed ", (TRUE == perm.allowModifyBy(agent)));
ensure("2:allowCopyBy():failed ", (TRUE == perm.allowModifyBy(agent,group)));
U32 val1 = 0x7FFFFFFF;
S32 sVal = 1 << 15;
sVal = val1 & sVal;
LLUUID agent1("9c8eca51-53d5-42a7-bb58-cef070395db8");
ensure("3:allowCopyBy():failed ", (sVal == perm.allowCopyBy(agent1)));
ensure("4:allowCopyBy():failed ", (sVal == perm.allowCopyBy(agent1,group)));
}
template<> template<>
void permission_object_t::test<16>()
{
LLPermissions perm;
LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
LLUUID owner;
LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
perm.init(creator,owner,lastOwner,group);
LLUUID agent;
ensure("1:allowMoveBy():failed ", (TRUE == perm.allowMoveBy(agent)));
ensure("2:allowMoveBy():failed ", (TRUE == perm.allowMoveBy(agent,group)));
U32 val1 = 0x7FFFFFFF;
S32 sVal = 1 << 19;
sVal = val1 & sVal;
LLUUID agent1("9c8eca51-53d5-42a7-bb58-cef070395db8");
ensure("3:allowMoveBy():failed ", (sVal == perm.allowMoveBy(agent1)));
ensure("4:allowMoveBy():failed ", (sVal == perm.allowMoveBy(agent1,group)));
}
template<> template<>
void permission_object_t::test<17>()
{
LLPermissions perm;
LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
LLUUID owner;
LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
LLUUID agent;
ensure("1:allowMoveBy():failed ", (TRUE == perm.allowTransferTo(agent)));
perm.init(creator,owner,lastOwner,group);
U32 val1 = 0x7FFFFFFF;
S32 sVal = 1 << 13;
sVal = val1 & sVal;
ensure("2:allowMoveBy():failed ", (sVal == perm.allowTransferTo(agent)));
}
template<> template<>
void permission_object_t::test<18>()
{
LLPermissions perm,perm1;
ensure("1:Operator==:failed ", perm == perm1);
LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
perm.init(creator,owner,lastOwner,group);
perm = perm1;
ensure("2:Operator==:failed ", perm == perm1);
}
template<> template<>
void permission_object_t::test<19>()
{
LLPermissions perm,perm1;
LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
perm.init(creator,owner,lastOwner,group);
ensure("2:Operator==:failed ", perm != perm1);
}
template<> template<>
void permission_object_t::test<20>()
{
LLFILE* fp = LLFile::fopen("linden_file.dat","w+");
if(!fp)
{
llerrs << "file coudnt be opened\n" << llendl;
return;
}
LLPermissions perm,perm1;
LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
perm.init(creator,owner,lastOwner,group);
U32 base = PERM_TRANSFER | PERM_COPY;
U32 ownerp = PERM_TRANSFER;
U32 groupp = PERM_TRANSFER;
U32 everyone = PERM_TRANSFER;
U32 next = PERM_NONE;
perm.initMasks(base, ownerp, everyone, groupp, next);
perm.exportFile(fp);
fclose(fp);
fp = LLFile::fopen("linden_file.dat","r+");
if(!fp)
{
llerrs << "file coudnt be opened\n" << llendl;
return;
}
perm1.importFile(fp);
fclose(fp);
ensure("exportFile()/importFile():failed to export and import the data ", perm1 == perm);
}
template<> template<>
void permission_object_t::test<21>()
{
LLPermissions perm,perm1;
LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
perm.init(creator,owner,lastOwner,group);
U32 base = PERM_TRANSFER | PERM_COPY;
U32 ownerp = PERM_TRANSFER;
U32 groupp = PERM_TRANSFER;
U32 everyone = PERM_TRANSFER;
U32 next = PERM_NONE;
perm.initMasks(base, ownerp, everyone, groupp, next);
std::ostringstream ostream;
perm.exportLegacyStream(ostream);
std::istringstream istream(ostream.str());
perm1.importLegacyStream(istream);
ensure("exportLegacyStream()/importLegacyStream():failed to export and import the data ", perm1 == perm);
}
template<> template<>
void permission_object_t::test<22>()
{
LLPermissions perm,perm1;
LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
perm.init(creator,owner,lastOwner,group);
LLXMLNode* xml_node = perm.exportFileXML();
perm1.importXML(xml_node);
ensure("exportFileXML()/importXML():failed to export and import the data ", perm1 == perm);
}
template<> template<>
void permission_object_t::test<23>()
{
LLPermissions perm,perm1;
LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
perm.init(creator,owner,lastOwner,group);
std::ostringstream stream1, stream2;
stream1 << perm;
perm1.init(creator,owner,lastOwner,group);
stream2 << perm1;
ensure("1:operator << failed",(stream1.str() == stream2.str()));
}
template<> template<>
void permission_object_t::test<24>()
{
LLPermissions perm,perm1;
LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
perm.init(creator,owner,lastOwner,group);
U32 base = PERM_TRANSFER | PERM_COPY;
U32 ownerp = PERM_TRANSFER;
U32 groupp = PERM_TRANSFER;
U32 everyone = PERM_TRANSFER;
U32 next = PERM_NONE;
perm.initMasks(base, ownerp, everyone, groupp, next);
LLSD sd = ll_create_sd_from_permissions(perm);
perm1 = ll_permissions_from_sd(sd);
ensure_equals("ll_permissions_from_sd() and ll_create_sd_from_permissions()functions failed", perm, perm1);
}
template<> template<>
void permission_object_t::test<25>()
{
LLAggregatePermissions AggrPermission;
LLAggregatePermissions AggrPermission1;
ensure("getU8() function failed", (AggrPermission.getU8() == 0));
ensure("isEmpty() function failed", (AggrPermission.isEmpty() == TRUE));
AggrPermission.getValue(PERM_TRANSFER);
ensure_equals("getValue() function failed", AggrPermission.getValue(PERM_TRANSFER), 0x00);
AggrPermission.aggregate(PERM_ITEM_UNRESTRICTED);
ensure("aggregate() function failed", (AggrPermission.isEmpty() == FALSE));
AggrPermission1.aggregate(AggrPermission);
ensure("aggregate() function failed", (AggrPermission1.isEmpty() == FALSE));
std::ostringstream stream1;
stream1 << AggrPermission;
ensure("operator<< failed", (stream1.str() == "{PI_COPY=All, PI_MODIFY=All, PI_TRANSFER=All}"));
}
}

189
indra/test/llpipeutil.cpp Normal file
View File

@@ -0,0 +1,189 @@
/**
* @file llpipeutil.cpp
* @date 2006-05-18
* @brief Utility pipe fittings for injecting and extracting strings
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llpipeutil.h"
#include <stdlib.h>
#include <sstream>
#include "llbufferstream.h"
#include "lldefs.h"
#include "llframetimer.h"
#include "llpumpio.h"
#include "llrand.h"
#include "lltimer.h"
F32 pump_loop(LLPumpIO* pump, F32 seconds)
{
LLTimer timer;
timer.setTimerExpirySec(seconds);
while(!timer.hasExpired())
{
LLFrameTimer::updateFrameTime();
pump->pump();
pump->callback();
}
return timer.getElapsedTimeF32();
}
//virtual
LLIOPipe::EStatus LLPipeStringInjector::process_impl(
const LLChannelDescriptors& channels,
buffer_ptr_t& buffer,
bool& eos,
LLSD& context,
LLPumpIO* pump)
{
buffer->append(channels.out(), (U8*) mString.data(), mString.size());
eos = true;
return STATUS_DONE;
}
LLIOPipe::EStatus LLPipeStringExtractor::process_impl(
const LLChannelDescriptors& channels,
buffer_ptr_t& buffer,
bool& eos,
LLSD& context,
LLPumpIO* pump)
{
if(!eos) return STATUS_BREAK;
if(!pump || !buffer) return STATUS_PRECONDITION_NOT_MET;
LLBufferStream istr(channels, buffer.get());
std::ostringstream ostr;
while (istr.good())
{
char buf[1024]; /* Flawfinder: ignore */
istr.read(buf, sizeof(buf)); /* Flawfinder: ignore */
ostr.write(buf, istr.gcount());
}
mString = ostr.str();
mDone = true;
return STATUS_DONE;
}
// virtual
LLIOPipe::EStatus LLIOFuzz::process_impl(
const LLChannelDescriptors& channels,
buffer_ptr_t& buffer,
bool& eos,
LLSD& context,
LLPumpIO* pump)
{
while(mByteCount)
{
std::vector<U8> data;
data.reserve(10000);
int size = llmin(10000, mByteCount);
std::generate_n(
std::back_insert_iterator< std::vector<U8> >(data),
size,
rand);
buffer->append(channels.out(), &data[0], size);
mByteCount -= size;
}
return STATUS_OK;
}
struct random_ascii_generator
{
random_ascii_generator() {}
U8 operator()()
{
int rv = rand();
rv %= (127 - 32);
rv += 32;
return rv;
}
};
// virtual
LLIOPipe::EStatus LLIOASCIIFuzz::process_impl(
const LLChannelDescriptors& channels,
buffer_ptr_t& buffer,
bool& eos,
LLSD& context,
LLPumpIO* pump)
{
while(mByteCount)
{
std::vector<U8> data;
data.reserve(10000);
int size = llmin(10000, mByteCount);
std::generate_n(
std::back_insert_iterator< std::vector<U8> >(data),
size,
random_ascii_generator());
buffer->append(channels.out(), &data[0], size);
mByteCount -= size;
}
return STATUS_OK;
}
// virtual
LLIOPipe::EStatus LLIONull::process_impl(
const LLChannelDescriptors& channels,
buffer_ptr_t& buffer,
bool& eos,
LLSD& context,
LLPumpIO* pump)
{
return STATUS_OK;
}
// virtual
LLIOPipe::EStatus LLIOSleeper::process_impl(
const LLChannelDescriptors& channels,
buffer_ptr_t& buffer,
bool& eos,
LLSD& context,
LLPumpIO* pump)
{
if(!mRespond)
{
lldebugs << "LLIOSleeper::process_impl() sleeping." << llendl;
mRespond = true;
static const F64 SLEEP_TIME = 2.0;
pump->sleepChain(SLEEP_TIME);
return STATUS_BREAK;
}
lldebugs << "LLIOSleeper::process_impl() responding." << llendl;
LLBufferStream ostr(channels, buffer.get());
ostr << "huh? sorry, I was sleeping." << std::endl;
return STATUS_DONE;
}

169
indra/test/llpipeutil.h Normal file
View File

@@ -0,0 +1,169 @@
/**
* @file llpipeutil.h
* @date 2006-05-18
* @brief Utility pipe fittings for injecting and extracting strings
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLPIPEUTIL_H
#define LL_LLPIPEUTIL_H
#include "lliopipe.h"
/**
* @brief Simple function which pumps for the specified time.
*/
F32 pump_loop(LLPumpIO* pump, F32 seconds);
/**
* @brief Simple class which writes a string and then marks the stream
* as done.
*/
class LLPipeStringInjector : public LLIOPipe
{
public:
LLPipeStringInjector(const std::string& string)
: mString(string)
{ }
protected:
virtual EStatus process_impl(
const LLChannelDescriptors& channels,
buffer_ptr_t& buffer,
bool& eos,
LLSD& context,
LLPumpIO* pump);
private:
std::string mString;
};
class LLPipeStringExtractor : public LLIOPipe
{
public:
LLPipeStringExtractor() : mDone(false) { }
bool done() { return mDone; }
std::string string() { return mString; }
protected:
// LLIOPipe API implementation.
virtual EStatus process_impl(
const LLChannelDescriptors& channels,
LLIOPipe::buffer_ptr_t& buffer,
bool& eos,
LLSD& context,
LLPumpIO* pump);
private:
bool mDone;
std::string mString;
};
/**
* @brief Generate a specified number of bytes of random data
*/
class LLIOFuzz : public LLIOPipe
{
public:
LLIOFuzz(int byte_count) : mByteCount(byte_count) {}
protected:
virtual EStatus process_impl(
const LLChannelDescriptors& channels,
buffer_ptr_t& buffer,
bool& eos,
LLSD& context,
LLPumpIO* pump);
private:
int mByteCount;
};
/**
* @brief Generate some ascii fuz
*/
class LLIOASCIIFuzz : public LLIOPipe
{
public:
LLIOASCIIFuzz(int byte_count) : mByteCount(byte_count) {}
protected:
virtual EStatus process_impl(
const LLChannelDescriptors& channels,
buffer_ptr_t& buffer,
bool& eos,
LLSD& context,
LLPumpIO* pump);
private:
int mByteCount;
};
/**
* @brief Pipe that does nothing except return STATUS_OK
*/
class LLIONull : public LLIOPipe
{
public:
LLIONull() {}
protected:
virtual EStatus process_impl(
const LLChannelDescriptors& channels,
buffer_ptr_t& buffer,
bool& eos,
LLSD& context,
LLPumpIO* pump);
};
/**
* @brief Pipe that sleeps, and then responds later.
*/
class LLIOSleeper : public LLIOPipe
{
public:
LLIOSleeper() : mRespond(false) {}
protected:
virtual EStatus process_impl(
const LLChannelDescriptors& channels,
buffer_ptr_t& buffer,
bool& eos,
LLSD& context,
LLPumpIO* pump);
private:
bool mRespond;
};
#endif // LL_LLPIPEUTIL_H

View File

@@ -0,0 +1,668 @@
/**
* @file llquaternion_tut.cpp
* @author Adroit
* @date 2007-03
* @brief Test cases of llquaternion.h
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "lltut.h"
#include "llquaternion.h"
#include "v4math.h"
#include "v3math.h"
#include "v3dmath.h"
#include "m4math.h"
#include "m3math.h"
#include "math.h"
namespace tut
{
struct llquat_test
{
};
typedef test_group<llquat_test> llquat_test_t;
typedef llquat_test_t::object llquat_test_object_t;
tut::llquat_test_t tut_llquat_test("llquat");
//test case for LLQuaternion::LLQuaternion(void) fn.
template<> template<>
void llquat_test_object_t::test<1>()
{
LLQuaternion llquat;
ensure("LLQuaternion::LLQuaternion() failed", 0.f == llquat.mQ[0] &&
0.f == llquat.mQ[1] &&
0.f == llquat.mQ[2] &&
1.f == llquat.mQ[3]);
}
//test case for explicit LLQuaternion(const LLMatrix4 &mat) fn.
template<> template<>
void llquat_test_object_t::test<2>()
{
LLMatrix4 llmat;
LLVector4 vector1(2.0f, 1.0f, 3.0f, 6.0f);
LLVector4 vector2(5.0f, 6.0f, 0.0f, 1.0f);
LLVector4 vector3(2.0f, 1.0f, 2.0f, 9.0f);
LLVector4 vector4(3.0f, 8.0f, 1.0f, 5.0f);
llmat.initRows(vector1, vector2, vector3, vector4);
ensure("explicit LLQuaternion(const LLMatrix4 &mat) failed", 2.0f == llmat.mMatrix[0][0] &&
1.0f == llmat.mMatrix[0][1] &&
3.0f == llmat.mMatrix[0][2] &&
6.0f == llmat.mMatrix[0][3] &&
5.0f == llmat.mMatrix[1][0] &&
6.0f == llmat.mMatrix[1][1] &&
0.0f == llmat.mMatrix[1][2] &&
1.0f == llmat.mMatrix[1][3] &&
2.0f == llmat.mMatrix[2][0] &&
1.0f == llmat.mMatrix[2][1] &&
2.0f == llmat.mMatrix[2][2] &&
9.0f == llmat.mMatrix[2][3] &&
3.0f == llmat.mMatrix[3][0] &&
8.0f == llmat.mMatrix[3][1] &&
1.0f == llmat.mMatrix[3][2] &&
5.0f == llmat.mMatrix[3][3]);
}
template<> template<>
void llquat_test_object_t::test<3>()
{
LLMatrix3 llmat;
LLVector3 vect1(3.4028234660000000f , 234.56f, 4234.442234f);
LLVector3 vect2(741.434f, 23.00034f, 6567.223423f);
LLVector3 vect3(566.003034f, 12.98705f, 234.764423f);
llmat.setRows(vect1, vect2, vect3);
ensure("LLMatrix3::setRows fn failed.", 3.4028234660000000f == llmat.mMatrix[0][0] &&
234.56f == llmat.mMatrix[0][1] &&
4234.442234f == llmat.mMatrix[0][2] &&
741.434f == llmat.mMatrix[1][0] &&
23.00034f == llmat.mMatrix[1][1] &&
6567.223423f == llmat.mMatrix[1][2] &&
566.003034f == llmat.mMatrix[2][0] &&
12.98705f == llmat.mMatrix[2][1] &&
234.764423f == llmat.mMatrix[2][2]);
}
//test case for LLQuaternion(F32 x, F32 y, F32 z, F32 w), setQuatInit() and normQuat() fns.
template<> template<>
void llquat_test_object_t::test<4>()
{
F32 x_val = 3.0f;
F32 y_val = 2.0f;
F32 z_val = 6.0f;
F32 w_val = 1.0f;
LLQuaternion res_quat;
res_quat.setQuatInit(x_val, y_val, z_val, w_val);
res_quat.normQuat();
ensure("LLQuaternion::normQuat() fn failed",
is_approx_equal(0.42426407f, res_quat.mQ[0]) &&
is_approx_equal(0.28284273f, res_quat.mQ[1]) &&
is_approx_equal(0.84852815f, res_quat.mQ[2]) &&
is_approx_equal(0.14142136f, res_quat.mQ[3]));
x_val = 0.0f;
y_val = 0.0f;
z_val = 0.0f;
w_val = 0.0f;
res_quat.setQuatInit(x_val, y_val, z_val, w_val);
res_quat.normQuat();
ensure("LLQuaternion::normQuat() fn. failed.",
is_approx_equal(0.0f, res_quat.mQ[0]) &&
is_approx_equal(0.0f, res_quat.mQ[1]) &&
is_approx_equal(0.0f, res_quat.mQ[2]) &&
is_approx_equal(1.0f, res_quat.mQ[3]));
ensure("LLQuaternion::normQuat() fn. failed.",
is_approx_equal(0.0f, res_quat.mQ[0]) &&
is_approx_equal(0.0f, res_quat.mQ[1]) &&
is_approx_equal(0.0f, res_quat.mQ[2]) &&
is_approx_equal(1.0f, res_quat.mQ[3]));
}
//test case for conjQuat() and transQuat() fns.
template<> template<>
void llquat_test_object_t::test<5>()
{
F32 x_val = 3.0f;
F32 y_val = 2.0f;
F32 z_val = 6.0f;
F32 w_val = 1.0f;
LLQuaternion res_quat;
LLQuaternion result, result1;
result1 = result = res_quat.setQuatInit(x_val, y_val, z_val, w_val);
result.conjQuat();
result1.transQuat();
ensure("LLQuaternion::conjQuat and LLQuaternion::transQuat failed ",
is_approx_equal(result1.mQ[0], result.mQ[0]) &&
is_approx_equal(result1.mQ[1], result.mQ[1]) &&
is_approx_equal(result1.mQ[2], result.mQ[2]));
}
//test case for dot(const LLQuaternion &a, const LLQuaternion &b) fn.
template<> template<>
void llquat_test_object_t::test<6>()
{
LLQuaternion quat1(3.0f, 2.0f, 6.0f, 0.0f), quat2(1.0f, 1.0f, 1.0f, 1.0f);
ensure("1. The two values are different", llround(12.000000f, 2) == llround(dot(quat1, quat2), 2));
LLQuaternion quat0(3.0f, 9.334f, 34.5f, 23.0f), quat(34.5f, 23.23f, 2.0f, 45.5f);
ensure("2. The two values are different", llround(1435.828807f, 2) == llround(dot(quat0, quat), 2));
}
//test case for LLQuaternion &LLQuaternion::constrain(F32 radians) fn.
template<> template<>
void llquat_test_object_t::test<7>()
{
F32 radian = 60.0f;
LLQuaternion quat(3.0f, 2.0f, 6.0f, 0.0f);
LLQuaternion quat1;
quat1 = quat.constrain(radian);
ensure("1. LLQuaternion::constrain(F32 radians) failed",
is_approx_equal_fraction(-0.423442f, quat1.mQ[0], 8) &&
is_approx_equal_fraction(-0.282295f, quat1.mQ[1], 8) &&
is_approx_equal_fraction(-0.846884f, quat1.mQ[2], 8) &&
is_approx_equal_fraction(0.154251f, quat1.mQ[3], 8));
radian = 30.0f;
LLQuaternion quat0(37.50f, 12.0f, 86.023f, 40.32f);
quat1 = quat0.constrain(radian);
ensure("2. LLQuaternion::constrain(F32 radians) failed",
is_approx_equal_fraction(37.500000f, quat1.mQ[0], 8) &&
is_approx_equal_fraction(12.0000f, quat1.mQ[1], 8) &&
is_approx_equal_fraction(86.0230f, quat1.mQ[2], 8) &&
is_approx_equal_fraction(40.320000f, quat1.mQ[3], 8));
}
template<> template<>
void llquat_test_object_t::test<8>()
{
F32 value1 = 15.0f;
LLQuaternion quat1(1.0f, 2.0f, 4.0f, 1.0f);
LLQuaternion quat2(4.0f, 3.0f, 6.5f, 9.7f);
LLQuaternion res_lerp, res_slerp, res_nlerp;
//test case for lerp(F32 t, const LLQuaternion &q) fn.
res_lerp = lerp(value1, quat1);
ensure("1. LLQuaternion lerp(F32 t, const LLQuaternion &q) failed",
is_approx_equal_fraction(0.181355f, res_lerp.mQ[0], 16) &&
is_approx_equal_fraction(0.362711f, res_lerp.mQ[1], 16) &&
is_approx_equal_fraction(0.725423f, res_lerp.mQ[2], 16) &&
is_approx_equal_fraction(0.556158f, res_lerp.mQ[3], 16));
//test case for lerp(F32 t, const LLQuaternion &p, const LLQuaternion &q) fn.
res_lerp = lerp(value1, quat1, quat2);
ensure("2. LLQuaternion lerp(F32 t, const LLQuaternion &p, const LLQuaternion &q) failed",
is_approx_equal_fraction(0.314306f, res_lerp.mQ[0], 16) &&
is_approx_equal_fraction(0.116156f, res_lerp.mQ[1], 16) &&
is_approx_equal_fraction(0.283559f, res_lerp.mQ[2], 16) &&
is_approx_equal_fraction(0.898506f, res_lerp.mQ[3], 16));
//test case for slerp( F32 u, const LLQuaternion &a, const LLQuaternion &b ) fn.
res_slerp = slerp(value1, quat1, quat2);
ensure("3. LLQuaternion slerp( F32 u, const LLQuaternion &a, const LLQuaternion &b) failed",
is_approx_equal_fraction(46.000f, res_slerp.mQ[0], 16) &&
is_approx_equal_fraction(17.00f, res_slerp.mQ[1], 16) &&
is_approx_equal_fraction(41.5f, res_slerp.mQ[2], 16) &&
is_approx_equal_fraction(131.5f, res_slerp.mQ[3], 16));
//test case for nlerp(F32 t, const LLQuaternion &a, const LLQuaternion &b) fn.
res_nlerp = nlerp(value1, quat1, quat2);
ensure("4. LLQuaternion nlerp(F32 t, const LLQuaternion &a, const LLQuaternion &b) failed",
is_approx_equal_fraction(0.314306f, res_nlerp.mQ[0], 16) &&
is_approx_equal_fraction(0.116157f, res_nlerp.mQ[1], 16) &&
is_approx_equal_fraction(0.283559f, res_nlerp.mQ[2], 16) &&
is_approx_equal_fraction(0.898506f, res_nlerp.mQ[3], 16));
//test case for nlerp(F32 t, const LLQuaternion &q) fn.
res_slerp = slerp(value1, quat1);
ensure("5. LLQuaternion slerp(F32 t, const LLQuaternion &q) failed",
is_approx_equal_fraction(1.0f, res_slerp.mQ[0], 16) &&
is_approx_equal_fraction(2.0f, res_slerp.mQ[1], 16) &&
is_approx_equal_fraction(4.0000f, res_slerp.mQ[2], 16) &&
is_approx_equal_fraction(1.000f, res_slerp.mQ[3], 16));
LLQuaternion quat3(2.0f, 1.0f, 5.5f, 10.5f);
LLQuaternion res_nlerp1;
value1 = 100.0f;
res_nlerp1 = nlerp(value1, quat3);
ensure("6. LLQuaternion nlerp(F32 t, const LLQuaternion &q) failed",
is_approx_equal_fraction(0.268245f, res_nlerp1.mQ[0], 16) && is_approx_equal_fraction(0.134122f, res_nlerp1.mQ[1], 2) &&
is_approx_equal_fraction(0.737673f, res_nlerp1.mQ[2], 16) &&
is_approx_equal_fraction(0.604892f, res_nlerp1.mQ[3], 16));
//test case for lerp(F32 t, const LLQuaternion &q) fn.
res_lerp = lerp(value1, quat2);
ensure("7. LLQuaternion lerp(F32 t, const LLQuaternion &q) failed",
is_approx_equal_fraction(0.404867f, res_lerp.mQ[0], 16) &&
is_approx_equal_fraction(0.303650f, res_lerp.mQ[1], 16) &&
is_approx_equal_fraction(0.657909f, res_lerp.mQ[2], 16) &&
is_approx_equal_fraction(0.557704f, res_lerp.mQ[3], 16));
}
template<> template<>
void llquat_test_object_t::test<9>()
{
//test case for LLQuaternion operator*(const LLQuaternion &a, const LLQuaternion &b) fn
LLQuaternion quat1(1.0f, 2.5f, 3.5f, 5.5f);
LLQuaternion quat2(4.0f, 3.0f, 5.0f, 1.0f);
LLQuaternion result = quat1 * quat2;
ensure("1. LLQuaternion Operator* failed", (21.0f == result.mQ[0]) &&
(10.0f == result.mQ[1]) &&
(38.0f == result.mQ[2]) &&
(-23.5f == result.mQ[3]));
LLQuaternion quat3(2341.340f, 2352.345f, 233.25f, 7645.5f);
LLQuaternion quat4(674.067f, 893.0897f, 578.0f, 231.0f);
result = quat3 * quat4;
ensure("2. LLQuaternion Operator* failed", (4543086.5f == result.mQ[0]) &&
(8567578.0f == result.mQ[1]) &&
(3967591.25f == result.mQ[2]) &&
is_approx_equal(-2047783.25f, result.mQ[3]));
//inline LLQuaternion operator+(const LLQuaternion &a, const LLQuaternion &b)fn.
result = quat1 + quat2;
ensure("3. LLQuaternion operator+ failed", (5.0f == result.mQ[0]) &&
(5.5f == result.mQ[1]) &&
(8.5f == result.mQ[2]) &&
(6.5f == result.mQ[3]));
result = quat3 + quat4;
ensure(
"4. LLQuaternion operator+ failed",
is_approx_equal(3015.407227f, result.mQ[0]) &&
is_approx_equal(3245.434570f, result.mQ[1]) &&
(811.25f == result.mQ[2]) &&
(7876.5f == result.mQ[3]));
//inline LLQuaternion operator-(const LLQuaternion &a, const LLQuaternion &b) fn
result = quat1 - quat2;
ensure(
"5. LLQuaternion operator-(const LLQuaternion &a, const LLQuaternion &b) failed",
(-3.0f == result.mQ[0]) &&
(-0.5f == result.mQ[1]) &&
(-1.5f == result.mQ[2]) &&
(4.5f == result.mQ[3]));
result = quat3 - quat4;
ensure(
"6. LLQuaternion operator-(const LLQuaternion &a, const LLQuaternion &b) failed",
is_approx_equal(1667.273071f, result.mQ[0]) &&
is_approx_equal(1459.255249f, result.mQ[1]) &&
(-344.75f == result.mQ[2]) &&
(7414.50f == result.mQ[3]));
}
//test case for LLVector4 operator*(const LLVector4 &a, const LLQuaternion &rot) fn.
template<> template<>
void llquat_test_object_t::test<10>()
{
LLVector4 vect(12.0f, 5.0f, 60.0f, 75.1f);
LLQuaternion quat(2323.034f, 23.5f, 673.23f, 57667.5f);
LLVector4 result = vect * quat;
ensure(
"1. LLVector4 operator*(const LLVector4 &a, const LLQuaternion &rot) failed",
is_approx_equal(39928406016.0f, result.mV[0]) &&
// gcc on x86 actually gives us more precision than we were expecting, verified with -ffloat-store - we forgive this
(1457802240.0f >= result.mV[1]) && // gcc+x86+linux
(1457800960.0f <= result.mV[1]) && // elsewhere
is_approx_equal(200580612096.0f, result.mV[2]) &&
(75.099998f == result.mV[3]));
LLVector4 vect1(22.0f, 45.0f, 40.0f, 78.1f);
LLQuaternion quat1(2.034f, 45.5f, 37.23f, 7.5f);
result = vect1 * quat1;
ensure(
"2. LLVector4 operator*(const LLVector4 &a, const LLQuaternion &rot) failed",
is_approx_equal(-58153.5390f, result.mV[0]) &&
(183787.8125f == result.mV[1]) &&
(116864.164063f == result.mV[2]) &&
(78.099998f == result.mV[3]));
}
//test case for LLVector3 operator*(const LLVector3 &a, const LLQuaternion &rot) fn.
template<> template<>
void llquat_test_object_t::test<11>()
{
LLVector3 vect(12.0f, 5.0f, 60.0f);
LLQuaternion quat(23.5f, 6.5f, 3.23f, 56.5f);
LLVector3 result = vect * quat;
ensure(
"1. LLVector3 operator*(const LLVector3 &a, const LLQuaternion &rot) failed",
is_approx_equal(97182.953125f,result.mV[0]) &&
is_approx_equal(-135405.640625f, result.mV[1]) &&
is_approx_equal(162986.140f, result.mV[2]));
LLVector3 vect1(5.0f, 40.0f, 78.1f);
LLQuaternion quat1(2.034f, 45.5f, 37.23f, 7.5f);
result = vect1 * quat1;
ensure(
"2. LLVector3 operator*(const LLVector3 &a, const LLQuaternion &rot) failed",
is_approx_equal(33217.703f, result.mV[0]) &&
is_approx_equal(295383.8125f, result.mV[1]) &&
is_approx_equal(84718.140f, result.mV[2]));
}
//test case for LLVector3d operator*(const LLVector3d &a, const LLQuaternion &rot) fn.
template<> template<>
void llquat_test_object_t::test<12>()
{
LLVector3d vect(-2.0f, 5.0f, -6.0f);
LLQuaternion quat(-3.5f, 4.5f, 3.5f, 6.5f);
LLVector3d result = vect * quat;
ensure(
"1. LLVector3d operator*(const LLVector3d &a, const LLQuaternion &rot) failed ",
(-633.0f == result.mdV[0]) &&
(-300.0f == result.mdV[1]) &&
(-36.0f == result.mdV[2]));
LLVector3d vect1(5.0f, -4.5f, 8.21f);
LLQuaternion quat1(2.0f, 4.5f, -7.2f, 9.5f);
result = vect1 * quat1;
ensure(
"2. LLVector3d operator*(const LLVector3d &a, const LLQuaternion &rot) failed",
is_approx_equal_fraction(-120.29f, (F32) result.mdV[0], 8) &&
is_approx_equal_fraction(-1683.958f, (F32) result.mdV[1], 8) &&
is_approx_equal_fraction(516.56f, (F32) result.mdV[2], 8));
LLVector3d vect2(2.0f, 3.5f, 1.1f);
LLQuaternion quat2(1.0f, 4.0f, 2.0f, 5.0f);
result = vect2 * quat2;
ensure(
"3. LLVector3d operator*(const LLVector3d &a, const LLQuaternion &rot) failed",
is_approx_equal_fraction(18.400001f, (F32) result.mdV[0], 8) &&
is_approx_equal_fraction(188.6f, (F32) result.mdV[1], 8) &&
is_approx_equal_fraction(32.20f, (F32) result.mdV[2], 8));
}
//test case for inline LLQuaternion operator-(const LLQuaternion &a) fn.
template<> template<>
void llquat_test_object_t::test<13>()
{
LLQuaternion quat(23.5f, 34.5f, 16723.4f, 324.7f);
LLQuaternion result = -quat;
ensure(
"1. LLQuaternion operator-(const LLQuaternion &a) failed",
(-23.5f == result.mQ[0]) &&
(-34.5f == result.mQ[1]) &&
(-16723.4f == result.mQ[2]) &&
(-324.7f == result.mQ[3]));
LLQuaternion quat1(-3.5f, -34.5f, -16.4f, -154.7f);
result = -quat1;
ensure(
"2. LLQuaternion operator-(const LLQuaternion &a) failed.",
(3.5f == result.mQ[0]) &&
(34.5f == result.mQ[1]) &&
(16.4f == result.mQ[2]) &&
(154.7f == result.mQ[3]));
}
//test case for inline LLQuaternion operator*(F32 a, const LLQuaternion &q) and
//inline LLQuaternion operator*(F32 a, const LLQuaternion &q) fns.
template<> template<>
void llquat_test_object_t::test<14>()
{
LLQuaternion quat_value(9.0f, 8.0f, 7.0f, 6.0f);
F32 a =3.5f;
LLQuaternion result = a * quat_value;
LLQuaternion result1 = quat_value * a;
ensure(
"1. LLQuaternion operator* failed",
(result.mQ[0] == result1.mQ[0]) &&
(result.mQ[1] == result1.mQ[1]) &&
(result.mQ[2] == result1.mQ[2]) &&
(result.mQ[3] == result1.mQ[3]));
LLQuaternion quat_val(9454.0f, 43568.3450f, 456343247.0343f, 2346.03434f);
a =-3324.3445f;
result = a * quat_val;
result1 = quat_val * a;
ensure(
"2. LLQuaternion operator* failed",
(result.mQ[0] == result1.mQ[0]) &&
(result.mQ[1] == result1.mQ[1]) &&
(result.mQ[2] == result1.mQ[2]) &&
(result.mQ[3] == result1.mQ[3]));
}
template<> template<>
void llquat_test_object_t::test<15>()
{
// test cases for inline LLQuaternion operator~(const LLQuaternion &a)
LLQuaternion quat_val(2323.634f, -43535.4f, 3455.88f, -32232.45f);
LLQuaternion result = ~quat_val;
ensure(
"1. LLQuaternion operator~(const LLQuaternion &a) failed ",
(-2323.634f == result.mQ[0]) &&
(43535.4f == result.mQ[1]) &&
(-3455.88f == result.mQ[2]) &&
(-32232.45f == result.mQ[3]));
//test case for inline bool LLQuaternion::operator==(const LLQuaternion &b) const
LLQuaternion quat_val1(2323.634f, -43535.4f, 3455.88f, -32232.45f);
LLQuaternion quat_val2(2323.634f, -43535.4f, 3455.88f, -32232.45f);
ensure(
"2. LLQuaternion::operator==(const LLQuaternion &b) failed",
quat_val1 == quat_val2);
}
template<> template<>
void llquat_test_object_t::test<16>()
{
//test case for inline bool LLQuaternion::operator!=(const LLQuaternion &b) const
LLQuaternion quat_val1(2323.634f, -43535.4f, 3455.88f, -32232.45f);
LLQuaternion quat_val2(0, -43535.4f, 3455.88f, -32232.45f);
ensure("LLQuaternion::operator!=(const LLQuaternion &b) failed", quat_val1 != quat_val2);
}
template<> template<>
void llquat_test_object_t::test<17>()
{
//test case for LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order)
F32 x = 2.0f;
F32 y = 1.0f;
F32 z = 3.0f;
LLQuaternion result = mayaQ(x, y, z, LLQuaternion::XYZ);
ensure(
"1. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for XYZ",
is_approx_equal_fraction(0.0172174f, result.mQ[0], 16) &&
is_approx_equal_fraction(0.009179f, result.mQ[1], 16) &&
is_approx_equal_fraction(0.026020f, result.mQ[2], 16) &&
is_approx_equal_fraction(0.999471f, result.mQ[3], 16));
LLQuaternion result1 = mayaQ(x, y, z, LLQuaternion::YZX);
ensure(
"2. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for XYZ",
is_approx_equal_fraction(0.017217f, result1.mQ[0], 16) &&
is_approx_equal_fraction(0.008265f, result1.mQ[1], 16) &&
is_approx_equal_fraction(0.026324f, result1.mQ[2], 16) &&
is_approx_equal_fraction(0.999471f, result1.mQ[3], 16));
LLQuaternion result2 = mayaQ(x, y, z, LLQuaternion::ZXY);
ensure(
"3. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for ZXY",
is_approx_equal_fraction(0.017674f, result2.mQ[0], 16) &&
is_approx_equal_fraction(0.008265f, result2.mQ[1], 16) &&
is_approx_equal_fraction(0.026020f, result2.mQ[2], 16) &&
is_approx_equal_fraction(0.999471f, result2.mQ[3], 16));
LLQuaternion result3 = mayaQ(x, y, z, LLQuaternion::XZY);
ensure(
"4. TLLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for XZY",
is_approx_equal_fraction(0.017674f, result3.mQ[0], 16) &&
is_approx_equal_fraction(0.009179f, result3.mQ[1], 16) &&
is_approx_equal_fraction(0.026020f, result3.mQ[2], 16) &&
is_approx_equal_fraction(0.999463f, result3.mQ[3], 16));
LLQuaternion result4 = mayaQ(x, y, z, LLQuaternion::YXZ);
ensure(
"5. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for YXZ",
is_approx_equal_fraction(0.017217f, result4.mQ[0], 16) &&
is_approx_equal_fraction(0.009179f, result4.mQ[1], 16) &&
is_approx_equal_fraction(0.026324f, result4.mQ[2], 16) &&
is_approx_equal_fraction(0.999463f, result4.mQ[3], 16));
LLQuaternion result5 = mayaQ(x, y, z, LLQuaternion::ZYX);
ensure(
"6. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for ZYX",
is_approx_equal_fraction(0.017674f, result5.mQ[0], 16) &&
is_approx_equal_fraction(0.008265f, result5.mQ[1], 16) &&
is_approx_equal_fraction(0.026324f, result5.mQ[2], 16) &&
is_approx_equal_fraction(0.999463f, result5.mQ[3], 16));
}
template<> template<>
void llquat_test_object_t::test<18>()
{
// test case for friend std::ostream& operator<<(std::ostream &s, const LLQuaternion &a) fn
LLQuaternion a(1.0f, 1.0f, 1.0f, 1.0f);
std::ostringstream result_value;
result_value << a;
ensure_equals("1. Operator << failed", result_value.str(), "{ 1, 1, 1, 1 }");
LLQuaternion b(-31.034f, 231.2340f, 3451.344320f, -341.0f);
std::ostringstream result_value1;
result_value1 << b;
ensure_equals("2. Operator << failed", result_value1.str(), "{ -31.034, 231.234, 3451.34, -341 }");
LLQuaternion c(1.0f, 2.2f, 3.3f, 4.4f);
result_value << c;
ensure_equals("3. Operator << failed", result_value.str(), "{ 1, 1, 1, 1 }{ 1, 2.2, 3.3, 4.4 }");
}
template<> template<>
void llquat_test_object_t::test<19>()
{
//test case for const char *OrderToString( const LLQuaternion::Order order ) fn
const char* result = OrderToString(LLQuaternion::XYZ);
ensure("1. OrderToString failed for XYZ", (0 == strcmp("XYZ", result)));
result = OrderToString(LLQuaternion::YZX);
ensure("2. OrderToString failed for YZX", (0 == strcmp("YZX", result)));
result = OrderToString(LLQuaternion::ZXY);
ensure(
"3. OrderToString failed for ZXY",
(0 == strcmp("ZXY", result)) &&
(0 != strcmp("XYZ", result)) &&
(0 != strcmp("YXZ", result)) &&
(0 != strcmp("ZYX", result)) &&
(0 != strcmp("XYZ", result)));
result = OrderToString(LLQuaternion::XZY);
ensure("4. OrderToString failed for XZY", (0 == strcmp("XZY", result)));
result = OrderToString(LLQuaternion::ZYX);
ensure("5. OrderToString failed for ZYX", (0 == strcmp("ZYX", result)));
result = OrderToString(LLQuaternion::YXZ);
ensure("6.OrderToString failed for YXZ", (0 == strcmp("YXZ", result)));
}
template<> template<>
void llquat_test_object_t::test<20>()
{
//test case for LLQuaternion::Order StringToOrder( const char *str ) fn
int result = StringToOrder("XYZ");
ensure("1. LLQuaternion::Order StringToOrder(const char *str ) failed for XYZ", 0 == result);
result = StringToOrder("YZX");
ensure("2. LLQuaternion::Order StringToOrder(const char *str) failed for YZX", 1 == result);
result = StringToOrder("ZXY");
ensure("3. LLQuaternion::Order StringToOrder(const char *str) failed for ZXY", 2 == result);
result = StringToOrder("XZY");
ensure("4. LLQuaternion::Order StringToOrder(const char *str) failed for XZY", 3 == result);
result = StringToOrder("YXZ");
ensure("5. LLQuaternion::Order StringToOrder(const char *str) failed for YXZ", 4 == result);
result = StringToOrder("ZYX");
ensure("6. LLQuaternion::Order StringToOrder(const char *str) failed for ZYX", 5 == result);
}
template<> template<>
void llquat_test_object_t::test<21>()
{
//void LLQuaternion::getAngleAxis(F32* angle, LLVector3 &vec) const fn
F32 angle_value = 90.0f;
LLVector3 vect(12.0f, 4.0f, 1.0f);
LLQuaternion llquat(angle_value, vect);
llquat.getAngleAxis(&angle_value, vect);
ensure(
"LLQuaternion::getAngleAxis(F32* angle, LLVector3 &vec) failed",
is_approx_equal_fraction(2.035406f, angle_value, 16) &&
is_approx_equal_fraction(0.315244f, vect.mV[1], 16) &&
is_approx_equal_fraction(0.078811f, vect.mV[2], 16) &&
is_approx_equal_fraction(0.945733f, vect.mV[0], 16));
}
template<> template<>
void llquat_test_object_t::test<22>()
{
//test case for void LLQuaternion::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) const fn
F32 roll = -12.0f;
F32 pitch = -22.43f;
F32 yaw = 11.0f;
LLQuaternion llquat;
llquat.getEulerAngles(&roll, &pitch, &yaw);
ensure(
"LLQuaternion::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) failed",
is_approx_equal(0.000f, llquat.mQ[0]) &&
is_approx_equal(0.000f, llquat.mQ[1]) &&
is_approx_equal(0.000f, llquat.mQ[2]) &&
is_approx_equal(1.000f, llquat.mQ[3]));
}
}

134
indra/test/llrandom_tut.cpp Executable file
View File

@@ -0,0 +1,134 @@
/**
* @file llrandom_tut.cpp
* @author Phoenix
* @date 2007-01-25
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "llrand.h"
#include "lltut.h"
namespace tut
{
struct random
{
};
typedef test_group<random> random_t;
typedef random_t::object random_object_t;
tut::random_t tut_random("random");
template<> template<>
void random_object_t::test<1>()
{
F32 number = 0.0f;
for(S32 ii = 0; ii < 100000; ++ii)
{
number = ll_frand();
ensure("frand >= 0", (number >= 0.0f));
ensure("frand < 1", (number < 1.0f));
}
}
template<> template<>
void random_object_t::test<2>()
{
F64 number = 0.0f;
for(S32 ii = 0; ii < 100000; ++ii)
{
number = ll_drand();
ensure("drand >= 0", (number >= 0.0));
ensure("drand < 1", (number < 1.0));
}
}
template<> template<>
void random_object_t::test<3>()
{
F32 number = 0.0f;
for(S32 ii = 0; ii < 100000; ++ii)
{
number = ll_frand(2.0f) - 1.0f;
ensure("frand >= 0", (number >= -1.0f));
ensure("frand < 1", (number <= 1.0f));
}
}
template<> template<>
void random_object_t::test<4>()
{
F32 number = 0.0f;
for(S32 ii = 0; ii < 100000; ++ii)
{
number = ll_frand(-7.0);
ensure("drand <= 0", (number <= 0.0));
ensure("drand > -7", (number > -7.0));
}
}
template<> template<>
void random_object_t::test<5>()
{
F64 number = 0.0f;
for(S32 ii = 0; ii < 100000; ++ii)
{
number = ll_drand(-2.0);
ensure("drand <= 0", (number <= 0.0));
ensure("drand > -2", (number > -2.0));
}
}
template<> template<>
void random_object_t::test<6>()
{
S32 number = 0;
for(S32 ii = 0; ii < 100000; ++ii)
{
number = ll_rand(100);
ensure("rand >= 0", (number >= 0));
ensure("rand < 100", (number < 100));
}
}
template<> template<>
void random_object_t::test<7>()
{
S32 number = 0;
for(S32 ii = 0; ii < 100000; ++ii)
{
number = ll_rand(-127);
ensure("rand <= 0", (number <= 0));
ensure("rand > -127", (number > -127));
}
}
}

View File

@@ -0,0 +1,252 @@
/**
* @file LLSaleInfo_tut.cpp
* @author Adroit
* @date 2007-03
* @brief Test cases of llsaleinfo.h
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "lltut.h"
#include "llsaleinfo.h"
namespace tut
{
struct llsaleinfo_tut
{
};
typedef test_group<llsaleinfo_tut> llsaleinfo_tut_t;
typedef llsaleinfo_tut_t::object llsaleinfo_test_t;
tut::llsaleinfo_tut_t tut_llsaleinfo_test("llsaleinfo");
template<> template<>
void llsaleinfo_test_t::test<1>()
{
//test case for getSaleType(), getSalePrice(), getCRC32() fn.
//test case for setSaleType(), setSalePrice() fn.
S32 sale_price = 10000;
LLSaleInfo llsaleinfo(LLSaleInfo::FS_COPY, sale_price);
const char* sale= "copy";
LLSD llsd_obj1 = ll_create_sd_from_sale_info(llsaleinfo);
LLSaleInfo saleinfo1 = ll_sale_info_from_sd(llsd_obj1);
ensure("1. The getSaleType() fn failed", LLSaleInfo::FS_COPY == llsaleinfo.getSaleType());
ensure("2. LLSaleInfo::isForSale() fn failed", TRUE == llsaleinfo.isForSale());
ensure("3. The getSalePrice() fn failed", sale_price == llsaleinfo.getSalePrice());
ensure("4. The getCRC32() fn failed", 235833404 == llsaleinfo.getCRC32());
ensure("5. LLSaleInfo::lookup(const char* name) fn failed", LLSaleInfo::FS_COPY == llsaleinfo.lookup(sale));
ensure_equals("6. ll_create_sd_from_sale_info() fn failed", llsaleinfo.getSalePrice(), saleinfo1.getSalePrice());
ensure_equals("7. ll_create_sd_from_sale_info() fn failed", llsaleinfo.getSaleType(), saleinfo1.getSaleType());
llsaleinfo.setSalePrice(10000000);
llsaleinfo.setSaleType(LLSaleInfo::FS_ORIGINAL);
sale = "cntn";
llsd_obj1 = ll_create_sd_from_sale_info(llsaleinfo);
saleinfo1 = ll_sale_info_from_sd(llsd_obj1);
ensure("8. The getSaleType() and setSaleType() fn failed", LLSaleInfo::FS_ORIGINAL == llsaleinfo.getSaleType());
ensure("9. LLSaleInfo::isForSale() fn failed", TRUE == llsaleinfo.isForSale());
ensure("10. The getSalePrice() fn failed", 10000000 == llsaleinfo.getSalePrice());
ensure("11. The getCRC32() fn failed", 127911702 == llsaleinfo.getCRC32());
ensure("12. LLSaleInfo::lookup(const char* name) fn failed", LLSaleInfo::FS_CONTENTS == llsaleinfo.lookup(sale));
ensure_equals("13. ll_create_sd_from_sale_info() fn failed", llsaleinfo.getSalePrice(), saleinfo1.getSalePrice());
ensure_equals("14. ll_create_sd_from_sale_info() fn failed", llsaleinfo.getSaleType(), saleinfo1.getSaleType());
llsaleinfo.setSalePrice(55000550);
llsaleinfo.setSaleType(LLSaleInfo::FS_CONTENTS);
sale = "orig";
llsd_obj1 = ll_create_sd_from_sale_info(llsaleinfo);
saleinfo1 = ll_sale_info_from_sd(llsd_obj1);
ensure("15. The getSaleType() and setSaleType() fn failed", LLSaleInfo::FS_CONTENTS == llsaleinfo.getSaleType());
ensure("16. LLSaleInfo::isForSale() fn failed", TRUE == llsaleinfo.isForSale());
ensure("17. The getSalePrice() fn failed", 55000550 == llsaleinfo.getSalePrice());
ensure("18. The getCRC32() fn failed", 408735656 == llsaleinfo.getCRC32());
ensure("19. LLSaleInfo::lookup(const char* name) fn failed", LLSaleInfo::FS_ORIGINAL == llsaleinfo.lookup(sale));
ensure_equals("20. ll_create_sd_from_sale_info() fn failed", llsaleinfo.getSalePrice(), saleinfo1.getSalePrice());
ensure_equals("21. ll_create_sd_from_sale_info() fn failed", llsaleinfo.getSaleType(), saleinfo1.getSaleType());
llsaleinfo.setSalePrice(-6432);
llsaleinfo.setSaleType(LLSaleInfo::FS_NOT);
sale = "not";
llsd_obj1 = ll_create_sd_from_sale_info(llsaleinfo);
saleinfo1 = ll_sale_info_from_sd(llsd_obj1);
ensure("22. The getSaleType() and setSaleType() fn failed", LLSaleInfo::FS_NOT == llsaleinfo.getSaleType());
ensure("23. LLSaleInfo::isForSale() fn failed", FALSE == llsaleinfo.isForSale());
ensure("24. The getSalePrice() fn failed", 0 == llsaleinfo.getSalePrice());
ensure("25. The getCRC32() fn failed", 0 == llsaleinfo.getCRC32());
ensure("26. LLSaleInfo::lookup(const char* name) fn failed", LLSaleInfo::FS_NOT == llsaleinfo.lookup(sale));
ensure_equals("27. ll_create_sd_from_sale_info() fn failed", llsaleinfo.getSalePrice(), saleinfo1.getSalePrice());
ensure_equals("28. ll_create_sd_from_sale_info() fn failed", llsaleinfo.getSaleType(), saleinfo1.getSaleType());
}
template<> template<>
void llsaleinfo_test_t::test<2>()
{
LLFILE* fp = LLFile::fopen("linden_file.dat","w+");
if(!fp)
{
llerrs << "file could not be opened\n" << llendl;
return;
}
S32 sale_price = 43500;
LLSaleInfo llsaleinfo(LLSaleInfo::FS_COPY, sale_price);
llsaleinfo.exportFile(fp);
fclose(fp);
LLSaleInfo llsaleinfo1;
U32 perm_mask;
BOOL has_perm_mask;
fp = LLFile::fopen("linden_file.dat","r");
if(!fp)
{
llerrs << "file coudnt be opened\n" << llendl;
return;
}
llsaleinfo1.importFile(fp, has_perm_mask, perm_mask);
fclose(fp);
ensure("importFile() fn failed ", llsaleinfo.getSaleType() == llsaleinfo1.getSaleType() &&
llsaleinfo.getSalePrice() == llsaleinfo1.getSalePrice());
}
template<> template<>
void llsaleinfo_test_t::test<3>()
{
S32 sale_price = 525452;
LLSaleInfo llsaleinfo(LLSaleInfo::FS_ORIGINAL, sale_price);
std::ostringstream ostream;
llsaleinfo.exportLegacyStream(ostream);
std::istringstream istream(ostream.str());
LLSaleInfo llsaleinfo1;
U32 perm_mask = 0;
BOOL has_perm_mask = FALSE;
llsaleinfo1.importLegacyStream(istream, has_perm_mask, perm_mask);
ensure("importLegacyStream() fn failed ", llsaleinfo.getSalePrice() == llsaleinfo1.getSalePrice() &&
llsaleinfo.getSaleType() == llsaleinfo1.getSaleType());
}
template<> template<>
void llsaleinfo_test_t::test<4>()
{
// LLXMLNode is teh suck.
#if 0
S32 sale_price = 23445;
LLSaleInfo saleinfo(LLSaleInfo::FS_CONTENTS, sale_price);
LLXMLNode* x_node = saleinfo.exportFileXML();
LLSaleInfo saleinfo1(LLSaleInfo::FS_NOT, 0);
saleinfo1.importXML(x_node);
ensure_equals("1.importXML() fn failed", saleinfo.getSalePrice(), saleinfo1.getSalePrice());
ensure_equals("2.importXML() fn failed", saleinfo.getSaleType(), saleinfo1.getSaleType());
#endif
}
template<> template<>
void llsaleinfo_test_t::test<5>()
{
S32 sale_price = 99000;
LLSaleInfo saleinfo(LLSaleInfo::FS_ORIGINAL, sale_price);
LLSD sd_result = saleinfo.asLLSD();
U32 perm_mask = 0 ;
BOOL has_perm_mask = FALSE;
LLSaleInfo saleinfo1;
saleinfo1.fromLLSD( sd_result, has_perm_mask, perm_mask);
ensure_equals("asLLSD and fromLLSD failed", saleinfo.getSalePrice(), saleinfo1.getSalePrice());
ensure_equals("asLLSD and fromLLSD failed", saleinfo.getSaleType(), saleinfo1.getSaleType());
}
//static EForSale lookup(const char* name) fn test
template<> template<>
void llsaleinfo_test_t::test<6>()
{
S32 sale_price = 233223;
LLSaleInfo::EForSale ret_type = LLSaleInfo::lookup("orig");
ensure_equals("lookup(const char* name) fn failed", ret_type, LLSaleInfo::FS_ORIGINAL);
LLSaleInfo saleinfo(LLSaleInfo::FS_COPY, sale_price);
const char* result = LLSaleInfo::lookup(LLSaleInfo::FS_COPY);
ensure("char* lookup(EForSale type) fn failed", 0 == strcmp("copy", result));
}
//void LLSaleInfo::accumulate(const LLSaleInfo& sale_info) fn test
template<> template<>
void llsaleinfo_test_t::test<7>()
{
S32 sale_price = 20;
LLSaleInfo saleinfo(LLSaleInfo::FS_COPY, sale_price);
LLSaleInfo saleinfo1(LLSaleInfo::FS_COPY, sale_price);
saleinfo1.accumulate(saleinfo);
ensure_equals("LLSaleInfo::accumulate(const LLSaleInfo& sale_info) fn failed", saleinfo1.getSalePrice(), 40);
}
// test cases of bool operator==(const LLSaleInfo &rhs) fn
// test case of bool operator!=(const LLSaleInfo &rhs) fn
template<> template<>
void llsaleinfo_test_t::test<8>()
{
S32 sale_price = 55000;
LLSaleInfo saleinfo(LLSaleInfo::FS_ORIGINAL, sale_price);
LLSaleInfo saleinfoequal(LLSaleInfo::FS_ORIGINAL, sale_price);
LLSaleInfo saleinfonotequal(LLSaleInfo::FS_ORIGINAL, sale_price*2);
ensure("operator == fn. failed", true == (saleinfo == saleinfoequal));
ensure("operator != fn. failed", true == (saleinfo != saleinfonotequal));
}
template<> template<>
void llsaleinfo_test_t::test<9>()
{
//TBD: void LLSaleInfo::packMessage(LLMessageSystem* msg) const
//TBD: void LLSaleInfo::unpackMessage(LLMessageSystem* msg, const char* block)
//TBD: void LLSaleInfo::unpackMultiMessage(LLMessageSystem* msg, const char* block, S32 block_num)
}
}

View File

@@ -0,0 +1,204 @@
/**
* @file llscriptresource_tut.cpp
* @brief Test LLScriptResource
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
* Copyright (c) 2008-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
//#include <tut/tut.h>
#include "linden_common.h"
#include "lltut.h"
#include "llscriptresource.h"
#include "llscriptresourceconsumer.h"
#include "llscriptresourcepool.h"
class TestConsumer : public LLScriptResourceConsumer
{
public:
TestConsumer()
: mUsedURLs(0)
{ }
// LLScriptResourceConsumer interface:
S32 getUsedPublicURLs() const
{
return mUsedURLs;
}
// Test details:
S32 mUsedURLs;
};
namespace tut
{
class LLScriptResourceTestData
{
};
typedef test_group<LLScriptResourceTestData> LLScriptResourceTestGroup;
typedef LLScriptResourceTestGroup::object LLScriptResourceTestObject;
LLScriptResourceTestGroup scriptResourceTestGroup("scriptResource");
template<> template<>
void LLScriptResourceTestObject::test<1>()
{
LLScriptResource resource;
U32 total = 42;
resource.setTotal(total);
ensure_equals("Verify set/get total", resource.getTotal(), total);
ensure_equals("Verify all resources are initially available",resource.getAvailable(),total);
// Requesting too many, releasing non-allocated
ensure("Request total + 1 resources should fail",!resource.request(total + 1));
ensure_equals("Verify all resources available after failed request",resource.getAvailable(),total);
ensure("Releasing resources when none allocated should fail",!resource.release());
ensure_equals("All resources should be available after failed release",resource.getAvailable(),total);
ensure("Request one resource", resource.request());
ensure_equals("Verify available resources after successful request",resource.getAvailable(),total - 1);
// Is this right? Or should we release all used resources if we try to release more than are currently used?
ensure("Release more resources than allocated",!resource.release(2));
ensure_equals("Verify resource availability after failed release",resource.getAvailable(),total - 1);
ensure("Release a resource",resource.release());
ensure_equals("Verify all resources available after successful release",resource.getAvailable(),total);
}
template<> template<>
void LLScriptResourceTestObject::test<2>()
{
LLScriptResource resource;
U32 total = 42;
resource.setTotal(total);
S32 resources_to_request = 30;
ensure("Get multiple resources resources",resource.request(resources_to_request));
ensure_equals("Verify available resources is correct after request of multiple resources",resource.getAvailable(), total - resources_to_request);
S32 resources_to_release = (resources_to_request / 2);
ensure("Release some resources",resource.release(resources_to_release));
S32 expected_available = (total - resources_to_request + resources_to_release);
ensure_equals("Verify available resources after release of some resources",resource.getAvailable(), expected_available);
resources_to_release = (resources_to_request - resources_to_release);
ensure("Release remaining resources",resource.release(resources_to_release));
ensure_equals("Verify available resources after release of remaining resources",resource.getAvailable(), total);
}
template<> template<>
void LLScriptResourceTestObject::test<3>()
{
LLScriptResource resource;
U32 total = 42;
resource.setTotal(total);
ensure("Request all resources",resource.request(total));
U32 low_total = 10;
ensure("Release all resources",resource.release(total));
ensure_equals("Verify all resources available after releasing",resource.getAvailable(),total);
resource.setTotal(low_total);
ensure_equals("Verify low total resources are available after set",resource.getAvailable(),low_total);
}
template<> template<>
void LLScriptResourceTestObject::test<4>()
{
S32 big_resource_total = 100;
S32 small_resource_total = 10;
LLScriptResourcePool big_pool;
big_pool.getPublicURLResource().setTotal(big_resource_total);
LLScriptResourcePool small_pool;
small_pool.getPublicURLResource().setTotal(small_resource_total);
TestConsumer consumer;
LLScriptResourcePool& initial_pool = consumer.getScriptResourcePool();
ensure("Initial resource pool is 'null'.", (&initial_pool == &LLScriptResourcePool::null));
consumer.switchScriptResourcePools(big_pool);
LLScriptResourcePool& get_pool = consumer.getScriptResourcePool();
ensure("Get resource that was set.", (&big_pool == &get_pool));
ensure_equals("No public urls in use yet.", consumer.getUsedPublicURLs(),0);
S32 request_urls = 5;
consumer.mUsedURLs = request_urls;
consumer.getScriptResourcePool().getPublicURLResource().request(request_urls);
ensure_equals("Available urls on big_pool is 5 less than total.",
big_pool.getPublicURLResource().getAvailable(), big_resource_total - request_urls);
ensure("Switching from big pool to small pool",
consumer.switchScriptResourcePools(small_pool));
ensure_equals("All resources available to big pool again",
big_pool.getPublicURLResource().getAvailable(), big_resource_total);
ensure_equals("Available urls on small pool is 5 less than total.",
small_pool.getPublicURLResource().getAvailable(), small_resource_total - request_urls);
ensure("Switching from small pool to big pool",
consumer.switchScriptResourcePools(big_pool));
consumer.getScriptResourcePool().getPublicURLResource().release(request_urls);
request_urls = 50; // Too many for the small_pool
consumer.mUsedURLs = request_urls;
consumer.getScriptResourcePool().getPublicURLResource().request(request_urls);
// Verify big pool has them
ensure_equals("Available urls on big pool is 50 less than total.",
big_pool.getPublicURLResource().getAvailable(), big_resource_total - request_urls);
// Verify can't switch to small_pool
ensure("Switching to small pool with too many resources",
!consumer.switchScriptResourcePools(small_pool));
// Verify big pool still accounting for used resources
ensure_equals("Available urls on big_pool is still 50 less than total.",
big_pool.getPublicURLResource().getAvailable(), big_resource_total - request_urls);
// Verify small pool still has all resources available.
ensure_equals("All resources in small pool are still available.",
small_pool.getPublicURLResource().getAvailable(), small_resource_total);
}
}

778
indra/test/llsd_new_tut.cpp Normal file
View File

@@ -0,0 +1,778 @@
/**
* @file llsd_new_tut.cpp
* @date February 2006
* @brief LLSD unit tests
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "lltut.h"
#include "llsdtraits.h"
#include "llstring.h"
namespace tut
{
class SDCleanupCheck
{
private:
U32 mOutstandingAtStart;
public:
SDCleanupCheck() : mOutstandingAtStart(LLSD::outstandingCount()) { }
~SDCleanupCheck()
{
ensure_equals("SDCleanupCheck",
LLSD::outstandingCount(), mOutstandingAtStart);
}
};
class SDAllocationCheck : public SDCleanupCheck
{
private:
std::string mMessage;
U32 mExpectedAllocations;
U32 mAllocationAtStart;
public:
SDAllocationCheck(const std::string& message, int expectedAllocations)
: mMessage(message),
mExpectedAllocations(expectedAllocations),
mAllocationAtStart(LLSD::allocationCount())
{ }
~SDAllocationCheck()
{
ensure_equals(mMessage + " SDAllocationCheck",
LLSD::allocationCount() - mAllocationAtStart,
mExpectedAllocations);
}
};
struct SDTestData {
template<class T>
static void ensureTypeAndValue(const char* msg, const LLSD& actual,
T expectedValue)
{
LLSDTraits<T> traits;
std::string s(msg);
ensure( s + " type", traits.checkType(actual));
ensure_equals( s + " value", traits.get(actual), expectedValue);
}
};
typedef test_group<SDTestData> SDTestGroup;
typedef SDTestGroup::object SDTestObject;
SDTestGroup sdTestGroup("LLSD(new)");
template<> template<>
void SDTestObject::test<1>()
// construction and test of undefined
{
SDCleanupCheck check;
LLSD u;
ensure("is undefined", u.isUndefined());
}
template<> template<>
void SDTestObject::test<2>()
// setting and fetching scalar types
{
SDCleanupCheck check;
LLSD v;
v = true; ensureTypeAndValue("set true", v, true);
v = false; ensureTypeAndValue("set false", v, false);
v = true; ensureTypeAndValue("set true again", v, true);
v = 42; ensureTypeAndValue("set to 42", v, 42);
v = 0; ensureTypeAndValue("set to zero", v, 0);
v = -12345; ensureTypeAndValue("set to neg", v, -12345);
v = 2000000000; ensureTypeAndValue("set to big", v, 2000000000);
v = 3.14159265359;
ensureTypeAndValue("set to pi", v, 3.14159265359);
ensure_not_equals("isn't float", v.asReal(),
(float)3.14159265359);
v = 6.7e256; ensureTypeAndValue("set to big", v, 6.7e256);
LLUUID nullUUID;
LLUUID newUUID;
newUUID.generate();
v = nullUUID; ensureTypeAndValue("set to null UUID", v, nullUUID);
v = newUUID; ensureTypeAndValue("set to new UUID", v, newUUID);
v = nullUUID; ensureTypeAndValue("set to null again", v, nullUUID);
// strings must be tested with two types of string objects
std::string s = "now is the time";
const char* cs = "for all good zorks";
v = s; ensureTypeAndValue("set to std::string", v, s);
v = cs; ensureTypeAndValue("set to const char*", v, cs);
LLDate epoch;
LLDate aDay("2001-10-22T10:11:12.00Z");
v = epoch; ensureTypeAndValue("set to epoch", v, epoch);
v = aDay; ensureTypeAndValue("set to a day", v, aDay);
LLURI path("http://slurl.com/secondlife/Ambleside/57/104/26/");
v = path; ensureTypeAndValue("set to a uri", v, path);
const char source[] = "once in a blue moon";
std::vector<U8> data;
copy(&source[0], &source[sizeof(source)], back_inserter(data));
v = data; ensureTypeAndValue("set to data", v, data);
v.clear();
ensure("reset to undefined", v.type() == LLSD::TypeUndefined);
}
template<> template<>
void SDTestObject::test<3>()
// construction via scalar values
// tests both constructor and initialize forms
{
SDCleanupCheck check;
LLSD b1(true); ensureTypeAndValue("construct boolean", b1, true);
LLSD b2 = true; ensureTypeAndValue("initialize boolean", b2, true);
LLSD i1(42); ensureTypeAndValue("construct int", i1, 42);
LLSD i2 =42; ensureTypeAndValue("initialize int", i2, 42);
LLSD d1(1.2); ensureTypeAndValue("construct double", d1, 1.2);
LLSD d2 = 1.2; ensureTypeAndValue("initialize double", d2, 1.2);
LLUUID newUUID;
newUUID.generate();
LLSD u1(newUUID);
ensureTypeAndValue("construct UUID", u1, newUUID);
LLSD u2 = newUUID;
ensureTypeAndValue("initialize UUID", u2, newUUID);
LLSD ss1(std::string("abc"));
ensureTypeAndValue("construct std::string", ss1, "abc");
LLSD ss2 = std::string("abc");
ensureTypeAndValue("initialize std::string",ss2, "abc");
LLSD sl1(std::string("def"));
ensureTypeAndValue("construct std::string", sl1, "def");
LLSD sl2 = std::string("def");
ensureTypeAndValue("initialize std::string", sl2, "def");
LLSD sc1("ghi");
ensureTypeAndValue("construct const char*", sc1, "ghi");
LLSD sc2 = "ghi";
ensureTypeAndValue("initialize const char*",sc2, "ghi");
LLDate aDay("2001-10-22T10:11:12.00Z");
LLSD t1(aDay); ensureTypeAndValue("construct LLDate", t1, aDay);
LLSD t2 = aDay; ensureTypeAndValue("initialize LLDate", t2, aDay);
LLURI path("http://slurl.com/secondlife/Ambleside/57/104/26/");
LLSD p1(path); ensureTypeAndValue("construct LLURI", p1, path);
LLSD p2 = path; ensureTypeAndValue("initialize LLURI", p2, path);
const char source[] = "once in a blue moon";
std::vector<U8> data;
copy(&source[0], &source[sizeof(source)], back_inserter(data));
LLSD x1(data); ensureTypeAndValue("construct vector<U8>", x1, data);
LLSD x2 = data; ensureTypeAndValue("initialize vector<U8>", x2, data);
}
void checkConversions(const char* msg, const LLSD& v,
LLSD::Boolean eBoolean, LLSD::Integer eInteger,
LLSD::Real eReal, const LLSD::String& eString)
{
std::string s(msg);
ensure_equals(s+" to bool", v.asBoolean(), eBoolean);
ensure_equals(s+" to int", v.asInteger(), eInteger);
if (eReal == eReal)
{
ensure_equals(s+" to real", v.asReal(), eReal);
ensure_equals(s+" to string", v.asString(), eString);
}
else
{
// TODO: Fix on windows....
#ifndef LL_WINDOWS
# if !defined(fpclassify) && __GNUC__ >= 3
# define FPCLASSIFY_NAMESPACE std::
# else
# define FPCLASSIFY_NAMESPACE
# endif
int left = FPCLASSIFY_NAMESPACE fpclassify(v.asReal());
int right = FPCLASSIFY_NAMESPACE fpclassify(eReal);
ensure_equals(s+" to real", left, right);
ensure_equals(s+" to string", v.asString(), eString);
#endif
}
}
template<> template<>
void SDTestObject::test<4>()
// conversion between undefined and basic scalar types:
// boolean, integer, real and string
{
SDCleanupCheck check;
LLSD v; checkConversions("untitled", v, false, 0, 0.0, "");
v = false; checkConversions("false", v, false, 0, 0.0, "");
v = true; checkConversions("true", v, true, 1, 1.0, "true");
v = 0; checkConversions("zero", v, false, 0, 0.0, "0");
v = 1; checkConversions("one", v, true, 1, 1.0, "1");
v = -33; checkConversions("neg33", v, true, -33, -33.0, "-33");
v = 0.0; checkConversions("0.0", v, false, 0, 0.0, "0");
v = 0.5; checkConversions("point5", v, true, 0, 0.5, "0.5");
v = 0.9; checkConversions("point9", v, true, 0, 0.9, "0.9");
v = -3.9; checkConversions("neg3dot9", v, true, -3, -3.9, "-3.9");
v = sqrt(-1.0); checkConversions("NaN", v, false, 0, sqrt(-1.0), "nan");
v = ""; checkConversions("empty", v, false, 0, 0.0, "");
v = "0"; checkConversions("digit0", v, true, 0, 0.0, "0");
v = "10"; checkConversions("digit10", v, true, 10, 10.0, "10");
v = "-2.345"; checkConversions("decdigits", v,
true, -2, -2.345, "-2.345");
v = "apple"; checkConversions("apple", v, true, 0, 0.0, "apple");
v = "33bob"; checkConversions("digialpha", v, true, 0, 0.0, "33bob");
v = " "; checkConversions("space", v, true, 0, 0.0, " ");
v = "\n"; checkConversions("newline", v, true, 0, 0.0, "\n");
}
template<class T>
void checkRoundTrip(const std::string& msg, const LLSD& actual,
const char* sExpected, T vExpected)
{
std::string str = actual.asString();
if (sExpected) {
ensure_equals(msg + " string", str, sExpected);
}
LLSD u(str);
LLSDTraits<T> traits;
ensure_equals(msg + " value", traits.get(u), vExpected);
}
template<> template<>
void SDTestObject::test<5>()
// conversion of String to and from UUID, Date and URI.
{
SDCleanupCheck check;
LLSD v;
LLUUID nullUUID;
LLUUID someUUID;
someUUID.generate();
v = nullUUID; checkRoundTrip("null uuid", v,
"00000000-0000-0000-0000-000000000000", nullUUID);
v = someUUID; checkRoundTrip("random uuid", v, 0, someUUID);
LLDate epoch;
LLDate beta("2003-04-30T04:00:00Z");
LLDate oneOh("2003-06-23T04:00:00Z");
v = epoch; checkRoundTrip("epoch date", v, 0, epoch);
v = beta; checkRoundTrip("beta date", v,
"2003-04-30T04:00:00Z", beta);
v = oneOh; checkRoundTrip("1.0 date", v,
"2003-06-23T04:00:00Z", oneOh);
LLURI empty;
LLURI path("http://slurl.com/secondlife/Ambleside/57/104/26/");
LLURI mail("mailto:zero.linden@secondlife.com");
v = empty; checkRoundTrip("empty URI", v, 0, empty);
v = path; checkRoundTrip("path URI", v,
"http://slurl.com/secondlife/Ambleside/57/104/26/",
path);
v = mail; checkRoundTrip("mail URI", v,
"mailto:zero.linden@secondlife.com", mail);
}
template<> template<>
void SDTestObject::test<6>()
// copy construction and assignment
// checking for shared values after constr. or assignment
// checking in both the same type and change of type case
{
SDCleanupCheck check;
{
LLSD v = 42;
LLSD w0(v);
ensureTypeAndValue("int constr.", w0, 42);
LLSD w1(v);
w1 = 13;
ensureTypeAndValue("int constr. change case 1", w1, 13);
ensureTypeAndValue("int constr. change case 2", v, 42);
LLSD w2(v);
v = 7;
ensureTypeAndValue("int constr. change case 3", w2, 42);
ensureTypeAndValue("int constr. change case 4", v, 7);
}
{
LLSD v = 42;
LLSD w1(v);
w1 = "bob";
ensureTypeAndValue("string constr. change case 1", w1, "bob");
ensureTypeAndValue("string constr. change case 2", v, 42);
LLSD w2(v);
v = "amy";
ensureTypeAndValue("string constr. change case 3", w2, 42);
ensureTypeAndValue("string constr. change case 4", v, "amy");
}
{
LLSD v = 42;
LLSD w0;
w0 = v;
ensureTypeAndValue("int assign", w0, 42);
LLSD w1;
w1 = v;
w1 = 13;
ensureTypeAndValue("int assign change case 1", w1, 13);
ensureTypeAndValue("int assign change case 2", v, 42);
LLSD w2;
w2 = v;
v = 7;
ensureTypeAndValue("int assign change case 3", w2, 42);
ensureTypeAndValue("int assign change case 4", v, 7);
}
{
LLSD v = 42;
LLSD w1;
w1 = v;
w1 = "bob";
ensureTypeAndValue("string assign change case 1", w1, "bob");
ensureTypeAndValue("string assign change case 2", v, 42);
LLSD w2;
w2 = v;
v = "amy";
ensureTypeAndValue("string assign change case 3", w2, 42);
ensureTypeAndValue("string assign change case 4", v, "amy");
}
}
template<> template<>
void SDTestObject::test<7>()
// Test assignment and casting to various scalar types. These
// assignments should invoke the right conversion without it being
// mentioned explicitly. The few exceptions are marked SAD.
{
SDCleanupCheck check;
LLSD v(" 42.375");
bool b = false;
b = v; ensure_equals("assign to bool", b, true);
b = (bool)v; ensure_equals("cast to bool", b, true);
int i = 99;
i = v; ensure_equals("assign to int", i, 42);
i = (int)v; ensure_equals("cast to int", i, 42);
double d = 3.14159;
d = v; ensure_equals("assign to double", d, 42.375);
d = (double)v; ensure_equals("cast to double", d, 42.375);
std::string s = "yo";
// SAD s = v; ensure_equals("assign to string", s, " 42.375");
s = (std::string)v; ensure_equals("cast to string", s, " 42.375");
std::string uuidStr = "b1e50c2b-b627-4d23-8a86-a65d97b6319b";
v = uuidStr;
LLUUID u;
u = v;
ensure_equals("assign to LLUUID", u, LLUUID(uuidStr));
// SAD u = (LLUUID)v;
// ensure_equals("cast to LLUUID", u, LLUUID(uuidStr));
std::string dateStr = "2005-10-24T15:00:00Z";
v = dateStr;
LLDate date;
date = v;
ensure_equals("assign to LLDate", date.asString(), dateStr);
// SAD date = (LLDate)v;
// ensure_equals("cast to LLDate", date.asString(), dateStr);
std::string uriStr = "http://secondlife.com";
v = uriStr;
LLURI uri;
uri = v;
ensure_equals("assign to LLURI", uri.asString(), uriStr);
// SAD uri = (LLURI)v;
// ensure_equals("cast to LLURI", uri.asString(), uriStr);
}
template<> template<>
void SDTestObject::test<8>()
// Test construction of various scalar types from LLSD.
// Test both construction and initialization forms.
// These should invoke the right conversion without it being
// mentioned explicitly. The few exceptions are marked SAD.
{
SDCleanupCheck check;
LLSD v(" 42.375");
bool b1(v); ensure_equals("contruct bool", b1, true);
bool b2 = v; ensure_equals("initialize bool", b2, true);
int i1(v); ensure_equals("contruct int", i1, 42);
int i2 = v; ensure_equals("initialize int", i2, 42);
double d1(v); ensure_equals("contruct double", d1, 42.375);
double d2 = v; ensure_equals("initialize double", d2, 42.375);
std::string s1(v);
std::string s2 = v;
ensure_equals("contruct string", s1, " 42.375");
ensure_equals("initialize string", s2, " 42.375");
std::string t1(v);
std::string t2 = v.asString(); // SAD
ensure_equals("contruct std::string", t1, " 42.375");
ensure_equals("initialize std::string", t2, " 42.375");
std::string uuidStr = "b1e50c2b-b627-4d23-8a86-a65d97b6319b";
v = uuidStr;
LLUUID uuid1(v.asUUID()); // SAD
LLUUID uuid2 = v;
ensure_equals("contruct LLUUID", uuid1, LLUUID(uuidStr));
ensure_equals("initialize LLUUID", uuid2, LLUUID(uuidStr));
std::string dateStr = "2005-10-24T15:00:00Z";
v = dateStr;
LLDate date1(v.asDate()); // SAD
LLDate date2 = v;
ensure_equals("contruct LLDate", date1.asString(), dateStr);
ensure_equals("initialize LLDate", date2.asString(), dateStr);
std::string uriStr = "http://secondlife.com";
v = uriStr;
LLURI uri1(v.asURI()); // SAD
LLURI uri2 = v;
ensure_equals("contruct LLURI", uri1.asString(), uriStr);
ensure_equals("initialize LLURI", uri2.asString(), uriStr);
}
template<> template<>
void SDTestObject::test<9>()
// test to make sure v is interpreted as a bool in a various
// scenarios.
{
SDCleanupCheck check;
LLSD v = "0";
// magic value that is interpreted as boolean true, but integer false!
ensure_equals("trinary operator bool", (v ? true : false), true);
ensure_equals("convert to int, then bool",
((int)v ? true : false), false);
if(v)
{
ensure("if converted to bool", true);
}
else
{
fail("bool did not convert to a bool in if statement.");
}
if(!v)
{
fail("bool did not convert to a bool in negated if statement.");
}
}
template<> template<>
void SDTestObject::test<10>()
// map operations
{
SDCleanupCheck check;
LLSD v;
ensure("undefined has no members", !v.has("amy"));
ensure("undefined get() is undefined", v.get("bob").isUndefined());
v = LLSD::emptyMap();
ensure("empty map is a map", v.isMap());
ensure("empty map has no members", !v.has("cam"));
ensure("empty map get() is undefined", v.get("don").isUndefined());
v.clear();
v.insert("eli", 43);
ensure("insert converts to map", v.isMap());
ensure("inserted key is present", v.has("eli"));
ensureTypeAndValue("inserted value", v.get("eli"), 43);
v.insert("fra", false);
ensure("first key still present", v.has("eli"));
ensure("second key is present", v.has("fra"));
ensureTypeAndValue("first value", v.get("eli"), 43);
ensureTypeAndValue("second value", v.get("fra"), false);
v.erase("eli");
ensure("first key now gone", !v.has("eli"));
ensure("second key still present", v.has("fra"));
ensure("first value gone", v.get("eli").isUndefined());
ensureTypeAndValue("second value sill there", v.get("fra"), false);
v.erase("fra");
ensure("second key now gone", !v.has("fra"));
ensure("second value gone", v.get("fra").isUndefined());
v["gil"] = (std::string)"good morning";
ensure("third key present", v.has("gil"));
ensureTypeAndValue("third key value", v.get("gil"), "good morning");
const LLSD& cv = v; // FIX ME IF POSSIBLE
ensure("missing key", cv["ham"].isUndefined());
ensure("key not present", !v.has("ham"));
LLSD w = 43;
const LLSD& cw = w; // FIX ME IF POSSIBLE
int i = cw["ian"];
ensureTypeAndValue("other missing value", i, 0);
ensure("other missing key", !w.has("ian"));
ensure("no conversion", w.isInteger());
LLSD x;
x = v;
ensure("copy map type", x.isMap());
ensureTypeAndValue("copy map value gil", x.get("gil"), "good morning");
}
template<> template<>
void SDTestObject::test<11>()
// array operations
{
SDCleanupCheck check;
LLSD v;
ensure_equals("undefined has no size", v.size(), 0);
ensure("undefined get() is undefined", v.get(0).isUndefined());
v = LLSD::emptyArray();
ensure("empty array is an array", v.isArray());
ensure_equals("empty array has no size", v.size(), 0);
ensure("empty map get() is undefined", v.get(0).isUndefined());
v.clear();
v.append(88);
v.append("noodle");
v.append(true);
ensure_equals("appened array size", v.size(), 3);
ensure("append array is an array", v.isArray());
ensureTypeAndValue("append 0", v[0], 88);
ensureTypeAndValue("append 1", v[1], "noodle");
ensureTypeAndValue("append 2", v[2], true);
v.insert(0, 77);
v.insert(2, "soba");
v.insert(4, false);
ensure_equals("inserted array size", v.size(), 6);
ensureTypeAndValue("post insert 0", v[0], 77);
ensureTypeAndValue("post insert 1", v[1], 88);
ensureTypeAndValue("post insert 2", v[2], "soba");
ensureTypeAndValue("post insert 3", v[3], "noodle");
ensureTypeAndValue("post insert 4", v[4], false);
ensureTypeAndValue("post insert 5", v[5], true);
ensureTypeAndValue("get 1", v.get(1), 88);
v.set(1, "hot");
ensureTypeAndValue("set 1", v.get(1), "hot");
v.erase(3);
ensure_equals("post erase array size", v.size(), 5);
ensureTypeAndValue("post erase 0", v[0], 77);
ensureTypeAndValue("post erase 1", v[1], "hot");
ensureTypeAndValue("post erase 2", v[2], "soba");
ensureTypeAndValue("post erase 3", v[3], false);
ensureTypeAndValue("post erase 4", v[4], true);
v.append(34);
ensure_equals("size after append", v.size(), 6);
ensureTypeAndValue("post append 5", v[5], 34);
LLSD w;
w = v;
ensure("copy array type", w.isArray());
ensure_equals("copy array size", w.size(), 6);
ensureTypeAndValue("copy array 0", w[0], 77);
ensureTypeAndValue("copy array 1", w[1], "hot");
ensureTypeAndValue("copy array 2", w[2], "soba");
ensureTypeAndValue("copy array 3", w[3], false);
ensureTypeAndValue("copy array 4", w[4], true);
ensureTypeAndValue("copy array 5", w[5], 34);
}
template<> template<>
void SDTestObject::test<12>()
// no sharing
{
SDCleanupCheck check;
LLSD a = 99;
LLSD b = a;
a = 34;
ensureTypeAndValue("top level original changed", a, 34);
ensureTypeAndValue("top level copy unaltered", b, 99);
b = a;
b = 66;
ensureTypeAndValue("top level original unaltered", a, 34);
ensureTypeAndValue("top level copy changed", b, 66);
a[0] = "uno";
a[1] = 99;
a[2] = 1.414;
b = a;
a[1] = 34;
ensureTypeAndValue("array member original changed", a[1], 34);
ensureTypeAndValue("array member copy unaltered", b[1], 99);
b = a;
b[1] = 66;
ensureTypeAndValue("array member original unaltered", a[1], 34);
ensureTypeAndValue("array member copy changed", b[1], 66);
a["alpha"] = "uno";
a["beta"] = 99;
a["gamma"] = 1.414;
b = a;
a["beta"] = 34;
ensureTypeAndValue("map member original changed", a["beta"], 34);
ensureTypeAndValue("map member copy unaltered", b["beta"], 99);
b = a;
b["beta"] = 66;
ensureTypeAndValue("map member original unaltered", a["beta"], 34);
ensureTypeAndValue("map member copy changed", b["beta"], 66);
}
template<> template<>
void SDTestObject::test<13>()
// sharing implementation
{
SDCleanupCheck check;
{
SDAllocationCheck check("copy construct undefinded", 0);
LLSD v;
LLSD w = v;
}
{
SDAllocationCheck check("assign undefined", 0);
LLSD v;
LLSD w;
w = v;
}
{
SDAllocationCheck check("assign integer value", 1);
LLSD v = 45;
v = 33;
v = 0;
}
{
SDAllocationCheck check("copy construct integer", 1);
LLSD v = 45;
LLSD w = v;
}
{
SDAllocationCheck check("assign integer", 1);
LLSD v = 45;
LLSD w;
w = v;
}
{
SDAllocationCheck check("avoids extra clone", 2);
LLSD v = 45;
LLSD w = v;
w = "nice day";
}
}
template<> template<>
void SDTestObject::test<14>()
// make sure that assignment of char* NULL in a string does not crash.
{
LLSD v;
v = (const char*)NULL;
ensure("type is a string", v.isString());
}
/* TO DO:
conversion of undefined to UUID, Date, URI and Binary
conversion of undefined to map and array
test map operations
test array operations
test array extension
test copying and assign maps and arrays (clone)
test iteration over map
test iteration over array
test iteration over scalar
test empty map and empty array are indeed shared
test serializations
*/
}

View File

@@ -0,0 +1,840 @@
/**
* @file llsdmessagebuilder_tut.cpp
* @date February 2006
* @brief LLSDMessageBuilder unit tests
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "lltut.h"
#include "llmessagetemplate.h"
#include "llsdmessagebuilder.h"
#include "llsdmessagereader.h"
#include "llsdtraits.h"
#include "llquaternion.h"
#include "u64.h"
#include "v3dmath.h"
#include "v3math.h"
#include "v4math.h"
#include "llsdutil_math.cpp"
#include "lltemplatemessagebuilder.h"
namespace tut
{
static LLTemplateMessageBuilder::message_template_name_map_t templateNameMap;
LLMsgData* messageData = NULL;
LLMsgBlkData* messageBlockData = NULL;
struct LLSDMessageBuilderTestData {
LLSDMessageBuilderTestData()
{
messageData = new LLMsgData("testMessage");
messageBlockData = new LLMsgBlkData("testBlock", 0);
}
static LLSDMessageBuilder defaultBuilder()
{
LLSDMessageBuilder builder;
builder.newMessage("name");
builder.nextBlock("block");
return builder;
}
static LLSDMessageReader setReader(const LLSDMessageBuilder& builder)
{
LLSDMessageReader reader;
reader.setMessage("name", builder.getMessage());
return reader;
}
static void addValue(LLMsgBlkData* mbd, char* name, void* v, EMsgVariableType type, int size, int data_size = -1)
{
LLMsgVarData tmp(name, type);
tmp.addData(v, size, type, data_size);
mbd->mMemberVarData[name] = tmp;
}
static LLMessageBlock* defaultTemplateBlock(const EMsgVariableType type = MVT_NULL, const S32 size = 0, EMsgBlockType block = MBT_VARIABLE)
{
return createTemplateBlock(_PREHASH_Test0, type, size, block);
}
static LLMessageBlock* createTemplateBlock(char* name, const EMsgVariableType type = MVT_NULL, const S32 size = 0, EMsgBlockType block = MBT_VARIABLE)
{
LLMessageBlock* result = new LLMessageBlock(name, block);
if(type != MVT_NULL)
{
result->addVariable(_PREHASH_Test0, type, size);
}
return result;
}
static LLTemplateMessageBuilder* defaultTemplateBuilder(LLMessageTemplate& messageTemplate, char* name = _PREHASH_Test0)
{
templateNameMap[_PREHASH_TestMessage] = &messageTemplate;
LLTemplateMessageBuilder* builder = new LLTemplateMessageBuilder(templateNameMap);
builder->newMessage(_PREHASH_TestMessage);
builder->nextBlock(name);
return builder;
}
static LLMessageTemplate defaultTemplate()
{
return LLMessageTemplate(_PREHASH_TestMessage, 1, MFT_HIGH);
}
};
typedef test_group<LLSDMessageBuilderTestData> LLSDMessageBuilderTestGroup;
typedef LLSDMessageBuilderTestGroup::object LLSDMessageBuilderTestObject;
LLSDMessageBuilderTestGroup llsdMessageBuilderTestGroup("LLSDMessageBuilder");
template<> template<>
void LLSDMessageBuilderTestObject::test<1>()
// construction and test of undefined
{
LLSDMessageBuilder builder = defaultBuilder();
LLSDMessageReader reader = setReader(builder);
}
template<> template<>
void LLSDMessageBuilderTestObject::test<2>()
// BOOL
{
BOOL outValue, inValue = TRUE;
LLSDMessageBuilder builder = defaultBuilder();
builder.addBOOL("var", inValue);
LLSDMessageReader reader = setReader(builder);
reader.getBOOL("block", "var", outValue);
ensure_equals("Ensure BOOL", inValue, outValue);
}
template<> template<>
void LLSDMessageBuilderTestObject::test<3>()
// U8
{
U8 outValue, inValue = 2;
LLSDMessageBuilder builder = defaultBuilder();
builder.addU8("var", inValue);
LLSDMessageReader reader = setReader(builder);
reader.getU8("block", "var", outValue);
ensure_equals("Ensure U8", inValue, outValue);
}
template<> template<>
void LLSDMessageBuilderTestObject::test<4>()
// S16
{
S16 outValue, inValue = 90;
LLSDMessageBuilder builder = defaultBuilder();
builder.addS16("var", inValue);
LLSDMessageReader reader = setReader(builder);
reader.getS16("block", "var", outValue);
ensure_equals("Ensure S16", inValue, outValue);
}
template<> template<>
void LLSDMessageBuilderTestObject::test<5>()
// U16
{
U16 outValue, inValue = 3;
LLSDMessageBuilder builder = defaultBuilder();
builder.addU16("var", inValue);
LLSDMessageReader reader = setReader(builder);
reader.getU16("block", "var", outValue);
ensure_equals("Ensure U16", inValue, outValue);
}
template<> template<>
void LLSDMessageBuilderTestObject::test<6>()
// S32
{
S32 outValue, inValue = 44;
LLSDMessageBuilder builder = defaultBuilder();
builder.addS32("var", inValue);
LLSDMessageReader reader = setReader(builder);
reader.getS32("block", "var", outValue);
ensure_equals("Ensure S32", inValue, outValue);
}
template<> template<>
void LLSDMessageBuilderTestObject::test<7>()
// F32
{
F32 outValue, inValue = 121.44f;
LLSDMessageBuilder builder = defaultBuilder();
builder.addF32("var", inValue);
LLSDMessageReader reader = setReader(builder);
reader.getF32("block", "var", outValue);
ensure_equals("Ensure F32", inValue, outValue);
}
template<> template<>
void LLSDMessageBuilderTestObject::test<8>()
// U32
{
U32 outValue, inValue = 88;
LLSDMessageBuilder builder = defaultBuilder();
builder.addU32("var", inValue);
LLSDMessageReader reader = setReader(builder);
reader.getU32("block", "var", outValue);
ensure_equals("Ensure U32", inValue, outValue);
}
template<> template<>
void LLSDMessageBuilderTestObject::test<9>()
// U64
{
U64 outValue, inValue = 121;
LLSDMessageBuilder builder = defaultBuilder();
builder.addU64("var", inValue);
LLSDMessageReader reader = setReader(builder);
reader.getU64("block", "var", outValue);
ensure_equals("Ensure U64", inValue, outValue);
}
template<> template<>
void LLSDMessageBuilderTestObject::test<10>()
// F64
{
F64 outValue, inValue = 3232143.33;
LLSDMessageBuilder builder = defaultBuilder();
builder.addF64("var", inValue);
LLSDMessageReader reader = setReader(builder);
reader.getF64("block", "var", outValue);
ensure_equals("Ensure F64", inValue, outValue);
}
template<> template<>
void LLSDMessageBuilderTestObject::test<11>()
// Vector3
{
LLVector3 outValue, inValue = LLVector3(1,2,3);
LLSDMessageBuilder builder = defaultBuilder();
builder.addVector3("var", inValue);
LLSDMessageReader reader = setReader(builder);
reader.getVector3("block", "var", outValue);
ensure_equals("Ensure Vector3", inValue, outValue);
}
template<> template<>
void LLSDMessageBuilderTestObject::test<12>()
// Vector4
{
LLVector4 outValue, inValue = LLVector4(1,2,3,4);
LLSDMessageBuilder builder = defaultBuilder();
builder.addVector4("var", inValue);
LLSDMessageReader reader = setReader(builder);
reader.getVector4("block", "var", outValue);
ensure_equals("Ensure Vector4", inValue, outValue);
}
template<> template<>
void LLSDMessageBuilderTestObject::test<13>()
// Vector3d
{
LLVector3d outValue, inValue = LLVector3d(1,2,3);
LLSDMessageBuilder builder = defaultBuilder();
builder.addVector3d("var", inValue);
LLSDMessageReader reader = setReader(builder);
reader.getVector3d("block", "var", outValue);
ensure_equals("Ensure Vector3d", inValue, outValue);
}
template<> template<>
void LLSDMessageBuilderTestObject::test<14>()
// Quaternion
{
LLQuaternion outValue, inValue = LLQuaternion(1,2,3,4);
LLSDMessageBuilder builder = defaultBuilder();
builder.addQuat("var", inValue);
LLSDMessageReader reader = setReader(builder);
reader.getQuat("block", "var", outValue);
ensure_equals("Ensure Quaternion", inValue, outValue);
}
template<> template<>
void LLSDMessageBuilderTestObject::test<15>()
// UUID
{
LLUUID outValue, inValue;
inValue.generate();
LLSDMessageBuilder builder = defaultBuilder();
builder.addUUID("var", inValue);
LLSDMessageReader reader = setReader(builder);
reader.getUUID("block", "var", outValue);
ensure_equals("Ensure UUID", inValue, outValue);
}
template<> template<>
void LLSDMessageBuilderTestObject::test<16>()
// IPAddr
{
U32 outValue, inValue = 12344556;
LLSDMessageBuilder builder = defaultBuilder();
builder.addIPAddr("var", inValue);
LLSDMessageReader reader = setReader(builder);
reader.getIPAddr("block", "var", outValue);
ensure_equals("Ensure IPAddr", inValue, outValue);
}
template<> template<>
void LLSDMessageBuilderTestObject::test<17>()
// IPPort
{
U16 outValue, inValue = 80;
LLSDMessageBuilder builder = defaultBuilder();
builder.addIPPort("var", inValue);
LLSDMessageReader reader = setReader(builder);
reader.getIPPort("block", "var", outValue);
ensure_equals("Ensure IPPort", inValue, outValue);
}
template<> template<>
void LLSDMessageBuilderTestObject::test<18>()
{
std::string outValue, inValue = "testing";
LLSDMessageBuilder builder = defaultBuilder();
builder.addString("var", inValue.c_str());
LLSDMessageReader reader = setReader(builder);
char buffer[MAX_STRING];
reader.getString("block", "var", MAX_STRING, buffer);
outValue = buffer;
ensure_equals("Ensure String", inValue, outValue);
}
template<> template<>
void LLSDMessageBuilderTestObject::test<19>()
{
LLMsgBlkData* mbd = new LLMsgBlkData("testBlock", 0);
LLMsgData* md = new LLMsgData("testMessage");
md->addBlock(mbd);
LLSDMessageBuilder builder = defaultBuilder();
builder.copyFromMessageData(*md);
LLSD output = builder.getMessage();
ensure("Ensure message block created when copied from legacy message to llsd", output["testBlock"].isDefined());
}
// MVT_FIXED
template<> template<>
void LLSDMessageBuilderTestObject::test<20>()
{
char binData[] = "abcdefghijklmnop";
addValue(messageBlockData, "testBinData", &binData, MVT_FIXED, sizeof(binData));
messageData->addBlock(messageBlockData);
LLSDMessageBuilder builder = defaultBuilder();
builder.copyFromMessageData(*messageData);
LLSD output = builder.getMessage();
std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary();
ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0);
ensure_memory_matches("Ensure fixed binary data works in a message copied from legacy to llsd",
&v[0], sizeof(binData), binData, sizeof(binData));
}
// MVT_VARIABLE data_size 1 (U8's)
template<> template<>
void LLSDMessageBuilderTestObject::test<21>()
{
/* U8 binData[] = "abcdefghijklmnop";
addValue(messageBlockData, "testBinData", &binData, MVT_VARIABLE, sizeof(binData), 1);
messageData->addBlock(messageBlockData);
LLSDMessageBuilder builder = defaultBuilder();
builder.copyFromMessageData(*messageData);
LLSD output = builder.getMessage();
std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary();
ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0);
ensure_memory_matches("Ensure MVT_VARIABLE U8 binary data works in a message copied from legacy to llsd",
&v[0], sizeof(binData), binData, sizeof(binData));*/
}
// MVT_VARIABLE data_size 2 (U16's)
template<> template<>
void LLSDMessageBuilderTestObject::test<22>()
{
U16 binData[] = {1,2,3,4,5,6,7,8,9}; //9 shorts
addValue(messageBlockData, "testBinData", &binData, MVT_VARIABLE, sizeof(binData) >> 1, 2);
messageData->addBlock(messageBlockData);
LLSDMessageBuilder builder = defaultBuilder();
builder.copyFromMessageData(*messageData);
LLSD output = builder.getMessage();
std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary();
ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0);
ensure_memory_matches("Ensure MVT_VARIABLE U16 binary data works in a message copied from legacy to llsd",
&v[0], sizeof(binData) >> 1, binData, sizeof(binData) >> 1);
}
// MVT_VARIABLE data_size 4 (S32's)
template<> template<>
void LLSDMessageBuilderTestObject::test<23>()
{
U32 binData[] = {9,8,7,6,5,4,3,2,1};
addValue(messageBlockData, "testBinData", &binData, MVT_VARIABLE, sizeof(binData) >> 2, 4);
messageData->addBlock(messageBlockData);
LLSDMessageBuilder builder = defaultBuilder();
builder.copyFromMessageData(*messageData);
LLSD output = builder.getMessage();
std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary();
ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0);
ensure_memory_matches("Ensure MVT_VARIABLE S32 binary data works in a message copied from legacy to llsd",
&v[0], sizeof(binData) >> 2, binData, sizeof(binData) >> 2);
}
// MVT_U8
template<> template<>
void LLSDMessageBuilderTestObject::test<24>()
{
U8 data = 0xa5;
addValue(messageBlockData, "testBinData", &data, MVT_U8, sizeof(data));
messageData->addBlock(messageBlockData);
LLSDMessageBuilder builder = defaultBuilder();
builder.copyFromMessageData(*messageData);
LLSD output = builder.getMessage();
ensure_equals("Ensure MVT_U8 data works in a message copied from legacy to llsd",
output["testBlock"][0]["testBinData"].asInteger(), data);
}
// MVT_U16
template<> template<>
void LLSDMessageBuilderTestObject::test<25>()
{
U16 data = 0xa55a;
addValue(messageBlockData, "testBinData", &data, MVT_U16, sizeof(data));
messageData->addBlock(messageBlockData);
LLSDMessageBuilder builder = defaultBuilder();
builder.copyFromMessageData(*messageData);
LLSD output = builder.getMessage();
ensure_equals("Ensure MVT_U16 data works in a message copied from legacy to llsd",
output["testBlock"][0]["testBinData"].asInteger(), data);
}
// MVT_U32
template<> template<>
void LLSDMessageBuilderTestObject::test<26>()
{
U32 data = 0xa55a7117;
addValue(messageBlockData, "testBinData", &data, MVT_U32, sizeof(data));
messageData->addBlock(messageBlockData);
LLSDMessageBuilder builder = defaultBuilder();
builder.copyFromMessageData(*messageData);
LLSD output = builder.getMessage();
ensure_equals("Ensure MVT_U32 data works in a message copied from legacy to llsd",
ll_U32_from_sd(output["testBlock"][0]["testBinData"]), data);
}
// MVT_U64 - crush into an s32: LLSD does not support 64 bit values
template<> template<>
void LLSDMessageBuilderTestObject::test<27>()
{
U64 data = U64L(0xa55a711711223344);
addValue(messageBlockData, "testBinData", &data, MVT_U64, sizeof(data));
messageData->addBlock(messageBlockData);
LLSDMessageBuilder builder = defaultBuilder();
builder.copyFromMessageData(*messageData);
LLSD output = builder.getMessage();
ensure_equals("Ensure MVT_U64 data works in a message copied from legacy to llsd",
ll_U64_from_sd(output["testBlock"][0]["testBinData"]), data);
}
// MVT_S8
template<> template<>
void LLSDMessageBuilderTestObject::test<28>()
{
S8 data = -31;
addValue(messageBlockData, "testBinData", &data, MVT_S8, sizeof(data));
messageData->addBlock(messageBlockData);
LLSDMessageBuilder builder = defaultBuilder();
builder.copyFromMessageData(*messageData);
LLSD output = builder.getMessage();
ensure_equals("Ensure MVT_S8 data works in a message copied from legacy to llsd",
output["testBlock"][0]["testBinData"].asInteger(), data);
}
// MVT_S16
template<> template<>
void LLSDMessageBuilderTestObject::test<29>()
{
S16 data = -31;
addValue(messageBlockData, "testBinData", &data, MVT_S16, sizeof(data));
messageData->addBlock(messageBlockData);
LLSDMessageBuilder builder = defaultBuilder();
builder.copyFromMessageData(*messageData);
LLSD output = builder.getMessage();
ensure_equals("Ensure MVT_S16 data works in a message copied from legacy to llsd",
output["testBlock"][0]["testBinData"].asInteger(), data);
}
// MVT_S32
template<> template<>
void LLSDMessageBuilderTestObject::test<30>()
{
S32 data = -3100;
addValue(messageBlockData, "testBinData", &data, MVT_S32, sizeof(data));
messageData->addBlock(messageBlockData);
LLSDMessageBuilder builder = defaultBuilder();
builder.copyFromMessageData(*messageData);
LLSD output = builder.getMessage();
ensure_equals("Ensure MVT_S32 data works in a message copied from legacy to llsd",
output["testBlock"][0]["testBinData"].asInteger(), data);
}
// MVT_S64 - crush into an s32: LLSD does not support 64 bit values
template<> template<>
void LLSDMessageBuilderTestObject::test<31>()
{
S64 data = -31003100;
addValue(messageBlockData, "testBinData", &data, MVT_S64, sizeof(data));
messageData->addBlock(messageBlockData);
LLSDMessageBuilder builder = defaultBuilder();
builder.copyFromMessageData(*messageData);
LLSD output = builder.getMessage();
ensure_equals("Ensure MVT_S64 data works in a message copied from legacy to llsd",
output["testBlock"][0]["testBinData"].asInteger(), (S32)data);
}
// MVT_F32
template<> template<>
void LLSDMessageBuilderTestObject::test<32>()
{
F32 data = 1234.1234f;
addValue(messageBlockData, "testBinData", &data, MVT_F32, sizeof(data));
messageData->addBlock(messageBlockData);
LLSDMessageBuilder builder = defaultBuilder();
builder.copyFromMessageData(*messageData);
LLSD output = builder.getMessage();
ensure_equals("Ensure MVT_F32 data works in a message copied from legacy to llsd",
output["testBlock"][0]["testBinData"].asReal(), data);
}
// MVT_F64
template<> template<>
void LLSDMessageBuilderTestObject::test<33>()
{
F64 data = 1234.1234;
addValue(messageBlockData, "testBinData", &data, MVT_F64, sizeof(data));
messageData->addBlock(messageBlockData);
LLSDMessageBuilder builder = defaultBuilder();
builder.copyFromMessageData(*messageData);
LLSD output = builder.getMessage();
ensure_equals("Ensure MVT_F64 data works in a message copied from legacy to llsd",
output["testBlock"][0]["testBinData"].asReal(), data);
}
// MVT_LLVector3
template<> template<>
void LLSDMessageBuilderTestObject::test<34>()
{
LLVector3 data(1,2,3);
addValue(messageBlockData, "testBinData", &data, MVT_LLVector3, sizeof(data));
messageData->addBlock(messageBlockData);
LLSDMessageBuilder builder = defaultBuilder();
builder.copyFromMessageData(*messageData);
LLSD output = builder.getMessage();
ensure_equals("Ensure MVT_LLVector3 data works in a message copied from legacy to llsd",
ll_vector3_from_sd(output["testBlock"][0]["testBinData"]), data);
}
// MVT_LLVector3d
template<> template<>
void LLSDMessageBuilderTestObject::test<35>()
{
LLVector3d data(1,2,3);
addValue(messageBlockData, "testBinData", &data, MVT_LLVector3d, sizeof(data));
messageData->addBlock(messageBlockData);
LLSDMessageBuilder builder = defaultBuilder();
builder.copyFromMessageData(*messageData);
LLSD output = builder.getMessage();
ensure_equals("Ensure MVT_LLVector3 data works in a message copied from legacy to llsd",
ll_vector3d_from_sd(output["testBlock"][0]["testBinData"]), data);
}
// MVT_LLVector4
template<> template<>
void LLSDMessageBuilderTestObject::test<36>()
{
LLVector4 data(1,2,3,4);
LLSD v = ll_sd_from_vector4(data);
addValue(messageBlockData, "testBinData", &data, MVT_LLVector4, sizeof(data));
messageData->addBlock(messageBlockData);
LLSDMessageBuilder builder = defaultBuilder();
builder.copyFromMessageData(*messageData);
LLSD output = builder.getMessage();
ensure_equals("Ensure MVT_LLVector4 data works in a message copied from legacy to llsd",
output["testBlock"][0]["testBinData"], v);
}
// MVT_LLQuaternion
template<> template<>
void LLSDMessageBuilderTestObject::test<37>()
{
LLQuaternion data(1,2,3,0);
//we send a quaternion packed into a vec3 (w is infered) - so sizeof(vec) == 12 bytes not 16.
LLVector3 vec = data.packToVector3();
addValue(messageBlockData, "testBinData", &vec, MVT_LLQuaternion, sizeof(vec));
messageData->addBlock(messageBlockData);
LLSDMessageBuilder builder = defaultBuilder();
builder.copyFromMessageData(*messageData);
LLSD output = builder.getMessage();
ensure_equals("Ensure MVT_LLQuaternion data works in a message copied from legacy to llsd",
ll_quaternion_from_sd(output["testBlock"][0]["testBinData"]), data);
}
// MVT_LLUUID
template<> template<>
void LLSDMessageBuilderTestObject::test<38>()
{
LLUUID data("01234567-0123-0123-0123-234567abcdef");
addValue(messageBlockData, "testBinData", &data, MVT_LLUUID, sizeof(data));
messageData->addBlock(messageBlockData);
LLSDMessageBuilder builder = defaultBuilder();
builder.copyFromMessageData(*messageData);
LLSD output = builder.getMessage();
std::string v = output["testBlock"][0]["testBinData"].asUUID().asString();
ensure_equals("Ensure MVT_LLUUID data works in a message copied from legacy to llsd",
output["testBlock"][0]["testBinData"].asUUID(), data);
}
// MVT_BOOL
template<> template<>
void LLSDMessageBuilderTestObject::test<39>()
{
BOOL valueTrue = true;
BOOL valueFalse = false;
LLMsgData* md = new LLMsgData("testMessage");
LLMsgBlkData* mbd = new LLMsgBlkData("testBlock", 0);
addValue(mbd, "testBoolFalse", &valueFalse, MVT_BOOL, sizeof(BOOL));
addValue(mbd, "testBoolTrue", &valueTrue, MVT_BOOL, sizeof(BOOL));
md->addBlock(mbd);
LLSDMessageBuilder builder = defaultBuilder();
builder.copyFromMessageData(*md);
LLSD output = builder.getMessage();
ensure("Ensure bools work in a message copied from legacy to llsd",
output["testBlock"][0]["testBoolTrue"].asBoolean() && !output["testBlock"][0]["testBoolFalse"].asBoolean());
}
// MVT_IP_ADDR
template<> template<>
void LLSDMessageBuilderTestObject::test<40>()
{
U32 data(0xff887766);
LLSD v = ll_sd_from_ipaddr(data);
addValue(messageBlockData, "testBinData", &data, MVT_IP_ADDR, sizeof(data));
messageData->addBlock(messageBlockData);
LLSDMessageBuilder builder = defaultBuilder();
builder.copyFromMessageData(*messageData);
LLSD output = builder.getMessage();
ensure_equals("Ensure MVT_IP_ADDR data works in a message copied from legacy to llsd",
output["testBlock"][0]["testBinData"], v);
}
// MVT_IP_PORT
template<> template<>
void LLSDMessageBuilderTestObject::test<41>()
{
U16 data = 0xff88;
addValue(messageBlockData, "testBinData", &data, MVT_IP_PORT, sizeof(data));
messageData->addBlock(messageBlockData);
LLSDMessageBuilder builder = defaultBuilder();
builder.copyFromMessageData(*messageData);
LLSD output = builder.getMessage();
ensure_equals("Ensure MVT_IP_PORT data works in a message copied from legacy to llsd",
output["testBlock"][0]["testBinData"].asInteger(), data);
}
// MVT_U16Vec3
template<> template<>
void LLSDMessageBuilderTestObject::test<42>()
{
U16 data[3] = {0,1,2};
addValue(messageBlockData, "testBinData", &data, MVT_U16Vec3, sizeof(data));
messageData->addBlock(messageBlockData);
LLSDMessageBuilder builder = defaultBuilder();
builder.copyFromMessageData(*messageData);
LLSD output = builder.getMessage();
std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary();
ensure("Ensure MVT_U16Vec3 data copied from legacy to llsd give a valid vector", v.size() > 0);
ensure_memory_matches("Ensure MVT_U16Vec3 data works in a message copied from legacy to llsd",
(U16*)&v[0], 6, data, 6);
}
// MVT_U16Quat
template<> template<>
void LLSDMessageBuilderTestObject::test<43>()
{
U16 data[4] = {0,1,2,4};
addValue(messageBlockData, "testBinData", &data, MVT_U16Quat, sizeof(data));
messageData->addBlock(messageBlockData);
LLSDMessageBuilder builder = defaultBuilder();
builder.copyFromMessageData(*messageData);
LLSD output = builder.getMessage();
std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary();
ensure("Ensure MVT_U16Quat data copied from legacy to llsd give a valid vector", v.size() > 0);
ensure_memory_matches("Ensure MVT_U16Quat data works in a message copied from legacy to llsd",
(U16*)&v[0], 8, data, 8);
}
// MVT_S16Array
template<> template<>
void LLSDMessageBuilderTestObject::test<44>()
{
S16 data[19] = {0,-1,2,-4,5,-6,7,-8,9,-10,11,-12,13,-14,15,16,17,18};
addValue(messageBlockData, "testBinData", &data, MVT_S16Array, sizeof(data));
messageData->addBlock(messageBlockData);
LLSDMessageBuilder builder = defaultBuilder();
builder.copyFromMessageData(*messageData);
LLSD output = builder.getMessage();
std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary();
ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0);
ensure_memory_matches("Ensure MVT_S16Array data works in a message copied from legacy to llsd",
(U16*)&v[0], 19, data, 19);
}
template<> template<>
void LLSDMessageBuilderTestObject::test<45>()
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultTemplateBlock(MVT_U8, 1));
U8 inValue = 2;
LLTemplateMessageBuilder* template_builder = defaultTemplateBuilder(messageTemplate);
template_builder->addU8(_PREHASH_Test0, inValue);
LLSDMessageBuilder builder;
builder.copyFromMessageData(*template_builder->getCurrentMessage());
LLSD output = builder.getMessage();
ensure_equals(output["Test0"][0]["Test0"].asInteger(), 2);
}
template<> template<>
void LLSDMessageBuilderTestObject::test<46>()
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultTemplateBlock(MVT_VARIABLE, 1));
std::string inValue = "testing";
LLTemplateMessageBuilder* builder = defaultTemplateBuilder(messageTemplate);
builder->addString(_PREHASH_Test0, inValue.c_str());
LLSDMessageBuilder sd_builder;
sd_builder.copyFromMessageData(*builder->getCurrentMessage());
LLSD output = sd_builder.getMessage();
ensure_equals(output["Test0"][0]["Test0"].asString(), std::string("testing"));
}
}

View File

@@ -0,0 +1,329 @@
/**
* @file llsdmessagereader_tut.cpp
* @date February 2006
* @brief LLSDMessageReader unit tests
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "lltut.h"
#include "v3dmath.h"
#include "v3math.h"
#include "v4math.h"
#include "llquaternion.h"
#include "message.h"
#include "llsdmessagereader.h"
#include "llsdutil.h"
namespace tut
{
struct LLSDMessageReaderTestData {
static void ensureMessageName(const std::string& msg_name,
const LLSD& msg_data,
const std::string& expected_name)
{
LLSDMessageReader msg;
msg.setMessage(LLMessageStringTable::getInstance()->getString(msg_name.c_str()), msg_data);
ensure_equals("Ensure name", std::string(msg.getMessageName()),
expected_name);
}
static void ensureNumberOfBlocks(const LLSD& msg_data,
const std::string& block,
S32 expected_number)
{
LLSDMessageReader msg;
msg.setMessage("fakename", msg_data);
ensure_equals("Ensure number of blocks", msg.getNumberOfBlocks(block.c_str()),
expected_number);
}
static void ensureMessageSize(const LLSD& msg_data,
S32 expected_size)
{
LLSDMessageReader msg;
msg.setMessage("fakename", msg_data);
ensure_equals( "Ensure size", msg.getMessageSize(), expected_size);
}
static void ensureBool(const LLSD& msg_data,
const std::string& block,
const std::string& var,
S32 blocknum,
BOOL expected)
{
LLSDMessageReader msg;
msg.setMessage("fakename", msg_data);
BOOL test_data;
msg.getBOOL(block.c_str(), var.c_str(), test_data, blocknum);
ensure_equals( "Ensure bool field", test_data, expected);
}
};
typedef test_group<LLSDMessageReaderTestData> LLSDMessageReaderTestGroup;
typedef LLSDMessageReaderTestGroup::object LLSDMessageReaderTestObject;
LLSDMessageReaderTestGroup llsdMessageReaderTestGroup("LLSDMessageReader");
template<> template<>
void LLSDMessageReaderTestObject::test<1>()
// construction and test of empty LLSD
{
LLSD message = LLSD::emptyMap();
ensureMessageName("", message, "");
ensureNumberOfBlocks(message, "Fakeblock", 0);
ensureMessageSize(message, 0);
}
template<> template<>
void LLSDMessageReaderTestObject::test<2>()
// construction and test of simple message with one block
{
LLSD message = LLSD::emptyMap();
message["block1"] = LLSD::emptyArray();
message["block1"][0] = LLSD::emptyMap();
message["block1"][0]["Field1"] = 0;
ensureMessageName("name2", message, "name2");
ensureNumberOfBlocks(message, "block1", 1);
ensureMessageSize(message, 0);
}
template<> template<>
void LLSDMessageReaderTestObject::test<3>()
// multiple blocks
{
LLSD message = LLSD::emptyMap();
message["block1"] = LLSD::emptyArray();
BOOL bool_true = TRUE;
BOOL bool_false = FALSE;
message["block1"][0] = LLSD::emptyMap();
message["block1"][0]["BoolField1"] = bool_true;
message["block1"][1] = LLSD::emptyMap();
message["block1"][1]["BoolField1"] = bool_false;
message["block1"][1]["BoolField2"] = bool_true;
ensureMessageName("name3", message, "name3");
ensureBool(message, "block1", "BoolField1", 0, TRUE);
ensureBool(message, "block1", "BoolField1", 1, FALSE);
ensureBool(message, "block1", "BoolField2", 1, TRUE);
ensureNumberOfBlocks(message, "block1", 2);
ensureMessageSize(message, 0);
}
template<typename T>
LLSDMessageReader testType(const T& value)
{
LLSD message = LLSD::emptyMap();
message["block"][0]["var"] = value;
LLSDMessageReader msg;
msg.setMessage("fakename", message);
return msg;
}
template<> template<>
void LLSDMessageReaderTestObject::test<4>()
// S8
{
S8 outValue, inValue = -3;
LLSDMessageReader msg = testType(inValue);
msg.getS8("block", "var", outValue);
ensure_equals("Ensure S8", outValue, inValue);
}
template<> template<>
void
LLSDMessageReaderTestObject::test<5>()
// U8
{
U8 outValue, inValue = 2;
LLSDMessageReader msg = testType(inValue);
msg.getU8("block", "var", outValue);
ensure_equals("Ensure U8", outValue, inValue);
}
template<> template<>
void LLSDMessageReaderTestObject::test<6>()
// S16
{
S16 outValue, inValue = 90;
LLSDMessageReader msg = testType(inValue);
msg.getS16("block", "var", outValue);
ensure_equals("Ensure S16", outValue, inValue);
}
template<> template<>
void LLSDMessageReaderTestObject::test<7>()
// U16
{
U16 outValue, inValue = 3;
LLSDMessageReader msg = testType(inValue);
msg.getU16("block", "var", outValue);
ensure_equals("Ensure S16", outValue, inValue);
}
template<> template<>
void LLSDMessageReaderTestObject::test<8>()
// S32
{
S32 outValue, inValue = 44;
LLSDMessageReader msg = testType(inValue);
msg.getS32("block", "var", outValue);
ensure_equals("Ensure S32", outValue, inValue);
}
template<> template<>
void LLSDMessageReaderTestObject::test<9>()
// F32
{
F32 outValue, inValue = 121.44f;
LLSDMessageReader msg = testType(inValue);
msg.getF32("block", "var", outValue);
ensure_equals("Ensure F32", outValue, inValue);
}
template<> template<>
void LLSDMessageReaderTestObject::test<10>()
// U32
{
U32 outValue, inValue = 88;
LLSD sdValue = ll_sd_from_U32(inValue);
LLSDMessageReader msg = testType(sdValue);
msg.getU32("block", "var", outValue);
ensure_equals("Ensure U32", outValue, inValue);
}
template<> template<>
void LLSDMessageReaderTestObject::test<11>()
// U64
{
U64 outValue, inValue = 121;
LLSD sdValue = ll_sd_from_U64(inValue);
LLSDMessageReader msg = testType(sdValue);
msg.getU64("block", "var", outValue);
ensure_equals("Ensure U64", outValue, inValue);
}
template<> template<>
void LLSDMessageReaderTestObject::test<12>()
// F64
{
F64 outValue, inValue = 3232143.33;
LLSDMessageReader msg = testType(inValue);
msg.getF64("block", "var", outValue);
ensure_equals("Ensure F64", outValue, inValue);
}
template<> template<>
void LLSDMessageReaderTestObject::test<13>()
// String
{
std::string outValue, inValue = "testing";
LLSDMessageReader msg = testType<std::string>(inValue.c_str());
char buffer[MAX_STRING];
msg.getString("block", "var", MAX_STRING, buffer);
outValue = buffer;
ensure_equals("Ensure String", outValue, inValue);
}
template<> template<>
void LLSDMessageReaderTestObject::test<14>()
// Vector3
{
LLVector3 outValue, inValue = LLVector3(1,2,3);
LLSD sdValue = ll_sd_from_vector3(inValue);
LLSDMessageReader msg = testType(sdValue);
msg.getVector3("block", "var", outValue);
ensure_equals("Ensure Vector3", outValue, inValue);
}
template<> template<>
void LLSDMessageReaderTestObject::test<15>()
// Vector4
{
LLVector4 outValue, inValue = LLVector4(1,2,3,4);
LLSD sdValue = ll_sd_from_vector4(inValue);
LLSDMessageReader msg = testType(sdValue);
msg.getVector4("block", "var", outValue);
ensure_equals("Ensure Vector4", outValue, inValue);
}
template<> template<>
void LLSDMessageReaderTestObject::test<16>()
// Vector3d
{
LLVector3d outValue, inValue = LLVector3d(1,2,3);
LLSD sdValue = ll_sd_from_vector3d(inValue);
LLSDMessageReader msg = testType(sdValue);
msg.getVector3d("block", "var", outValue);
ensure_equals("Ensure Vector3d", outValue, inValue);
}
template<> template<>
void LLSDMessageReaderTestObject::test<17>()
// Quaternion
{
LLQuaternion outValue, inValue = LLQuaternion(1,2,3,4);
LLSD sdValue = ll_sd_from_quaternion(inValue);
LLSDMessageReader msg = testType(sdValue);
msg.getQuat("block", "var", outValue);
ensure_equals("Ensure Quaternion", outValue, inValue);
}
template<> template<>
void LLSDMessageReaderTestObject::test<18>()
// UUID
{
LLUUID outValue, inValue;
inValue.generate();
LLSDMessageReader msg = testType(inValue);
msg.getUUID("block", "var", outValue);
ensure_equals("Ensure UUID", outValue, inValue);
}
template<> template<>
void LLSDMessageReaderTestObject::test<19>()
// IPAddr
{
U32 outValue, inValue = 12344556;
LLSD sdValue = ll_sd_from_ipaddr(inValue);
LLSDMessageReader msg = testType(sdValue);
msg.getIPAddr("block", "var", outValue);
ensure_equals("Ensure IPAddr", outValue, inValue);
}
template<> template<>
void LLSDMessageReaderTestObject::test<20>()
// IPPort
{
U16 outValue, inValue = 80;
LLSDMessageReader msg = testType(inValue);
msg.getIPPort("block", "var", outValue);
ensure_equals("Ensure IPPort", outValue, inValue);
}
template<> template<>
void LLSDMessageReaderTestObject::test<21>()
// Binary
{
std::vector<U8> outValue(2), inValue(2);
inValue[0] = 0;
inValue[1] = 1;
LLSDMessageReader msg = testType(inValue);
msg.getBinaryData("block", "var", &(outValue[0]), inValue.size());
ensure_equals("Ensure Binary", outValue, inValue);
}
}

File diff suppressed because it is too large Load Diff

106
indra/test/llsdtraits.h Normal file
View File

@@ -0,0 +1,106 @@
/**
* @file llsdtraits.h
* @brief Unit test helpers
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LLSDTRAITS_H
#define LLSDTRAITS_H
#include "llsd.h"
#include "llstring.h"
template<class T>
class LLSDTraits
{
protected:
typedef T (LLSD::*Getter)() const;
LLSD::Type type;
Getter getter;
public:
LLSDTraits();
T get(const LLSD& actual)
{
return (actual.*getter)();
}
bool checkType(const LLSD& actual)
{
return actual.type() == type;
}
};
template<> inline
LLSDTraits<LLSD::Boolean>::LLSDTraits()
: type(LLSD::TypeBoolean), getter(&LLSD::asBoolean)
{ }
template<> inline
LLSDTraits<LLSD::Integer>::LLSDTraits()
: type(LLSD::TypeInteger), getter(&LLSD::asInteger)
{ }
template<> inline
LLSDTraits<LLSD::Real>::LLSDTraits()
: type(LLSD::TypeReal), getter(&LLSD::asReal)
{ }
template<> inline
LLSDTraits<LLSD::UUID>::LLSDTraits()
: type(LLSD::TypeUUID), getter(&LLSD::asUUID)
{ }
template<> inline
LLSDTraits<LLSD::String>::LLSDTraits()
: type(LLSD::TypeString), getter(&LLSD::asString)
{ }
template<>
class LLSDTraits<const char*> : public LLSDTraits<LLSD::String>
{ };
template<> inline
LLSDTraits<LLSD::Date>::LLSDTraits()
: type(LLSD::TypeDate), getter(&LLSD::asDate)
{ }
template<> inline
LLSDTraits<LLSD::URI>::LLSDTraits()
: type(LLSD::TypeURI), getter(&LLSD::asURI)
{ }
template<> inline
LLSDTraits<LLSD::Binary>::LLSDTraits()
: type(LLSD::TypeBinary), getter(&LLSD::asBinary)
{ }
#endif // LLSDTRAITS_H

162
indra/test/llsdutil_tut.cpp Normal file
View File

@@ -0,0 +1,162 @@
/**
* @file llsdutil_tut.cpp
* @author Adroit
* @date 2007-02
* @brief LLSD conversion routines test cases.
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "lltut.h"
#include "m4math.h"
#include "v2math.h"
#include "v2math.h"
#include "v3color.h"
#include "v3math.h"
#include "v3dmath.h"
#include "v4coloru.h"
#include "v4math.h"
#include "llquaternion.h"
#include "llsdutil.h"
namespace tut
{
struct llsdutil_data
{
};
typedef test_group<llsdutil_data> llsdutil_test;;
typedef llsdutil_test::object llsdutil_object;
tut::llsdutil_test tutil("llsdutil");
template<> template<>
void llsdutil_object::test<1>()
{
LLSD sd;
U64 valueIn , valueOut;
valueIn = U64L(0xFEDCBA9876543210);
sd = ll_sd_from_U64(valueIn);
valueOut = ll_U64_from_sd(sd);
ensure_equals("U64 valueIn->sd->valueOut", valueIn, valueOut);
}
template<> template<>
void llsdutil_object::test<2>()
{
LLSD sd;
U32 valueIn, valueOut;
valueIn = 0x87654321;
sd = ll_sd_from_U32(valueIn);
valueOut = ll_U32_from_sd(sd);
ensure_equals("U32 valueIn->sd->valueOut", valueIn, valueOut);
}
template<> template<>
void llsdutil_object::test<3>()
{
U32 valueIn, valueOut;
valueIn = 0x87654321;
LLSD sd;
sd = ll_sd_from_ipaddr(valueIn);
valueOut = ll_ipaddr_from_sd(sd);
ensure_equals("valueIn->sd->valueOut", valueIn, valueOut);
}
template<> template<>
void llsdutil_object::test<4>()
{
LLSD sd;
LLVector3 vec1(-1.0, 2.0, -3.0);
sd = ll_sd_from_vector3(vec1);
LLVector3 vec2 = ll_vector3_from_sd(sd);
ensure_equals("vector3 -> sd -> vector3: 1", vec1, vec2);
LLVector3 vec3(sd);
ensure_equals("vector3 -> sd -> vector3: 2", vec1, vec3);
sd.clear();
vec1.setVec(0., 0., 0.);
sd = ll_sd_from_vector3(vec1);
vec2 = ll_vector3_from_sd(sd);
ensure_equals("vector3 -> sd -> vector3: 3", vec1, vec2);
sd.clear();
}
template<> template<>
void llsdutil_object::test<5>()
{
LLSD sd;
LLVector3d vec1((F64)(U64L(0xFEDCBA9876543210) << 2), -1., 0);
sd = ll_sd_from_vector3d(vec1);
LLVector3d vec2 = ll_vector3d_from_sd(sd);
ensure_equals("vector3d -> sd -> vector3d: 1", vec1, vec2);
LLVector3d vec3(sd);
ensure_equals("vector3d -> sd -> vector3d : 2", vec1, vec3);
}
template<> template<>
void llsdutil_object::test<6>()
{
LLSD sd;
LLVector2 vec((F32) -3., (F32) 4.2);
sd = ll_sd_from_vector2(vec);
LLVector2 vec1 = ll_vector2_from_sd(sd);
ensure_equals("vector2 -> sd -> vector2", vec, vec1);
LLSD sd2 = ll_sd_from_vector2(vec1);
ensure_equals("sd -> vector2 -> sd: 2", sd, sd2);
}
template<> template<>
void llsdutil_object::test<7>()
{
LLSD sd;
LLQuaternion quat((F32) 1., (F32) -0.98, (F32) 2.3, (F32) 0xffff);
sd = ll_sd_from_quaternion(quat);
LLQuaternion quat1 = ll_quaternion_from_sd(sd);
ensure_equals("LLQuaternion -> sd -> LLQuaternion", quat, quat1);
LLSD sd2 = ll_sd_from_quaternion(quat1);
ensure_equals("sd -> LLQuaternion -> sd ", sd, sd2);
}
template<> template<>
void llsdutil_object::test<8>()
{
LLSD sd;
LLColor4 c(1.0f, 2.2f, 4.0f, 7.f);
sd = ll_sd_from_color4(c);
LLColor4 c1 =ll_color4_from_sd(sd);
ensure_equals("LLColor4 -> sd -> LLColor4", c, c1);
LLSD sd1 = ll_sd_from_color4(c1);
ensure_equals("sd -> LLColor4 -> sd", sd, sd1);
}
}

View File

@@ -0,0 +1,179 @@
/**
* @file llservicebuilder_tut.cpp
* @brief LLServiceBuilder unit tests
* @date March 2007
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "lltut.h"
#include "llsd.h"
#include "llservicebuilder.h"
namespace tut
{
struct ServiceBuilderTestData {
LLServiceBuilder mServiceBuilder;
};
typedef test_group<ServiceBuilderTestData> ServiceBuilderTestGroup;
typedef ServiceBuilderTestGroup::object ServiceBuilderTestObject;
ServiceBuilderTestGroup serviceBuilderTestGroup("ServiceBuilder");
template<> template<>
void ServiceBuilderTestObject::test<1>()
{
//Simple service build and reply with no mapping
LLSD test_block;
test_block["service-builder"] = "/agent/name";
mServiceBuilder.createServiceDefinition("ServiceBuilderTest", test_block["service-builder"]);
std::string test_url = mServiceBuilder.buildServiceURI("ServiceBuilderTest");
ensure_equals("Basic URL Creation", test_url , "/agent/name");
}
template<> template<>
void ServiceBuilderTestObject::test<2>()
{
//Simple replace test
LLSD test_block;
test_block["service-builder"] = "/agent/{$agent-id}/name";
mServiceBuilder.createServiceDefinition("ServiceBuilderTest", test_block["service-builder"]);
LLSD data_map;
data_map["agent-id"] = "257c631f-a0c5-4f29-8a9f-9031feaae6c6";
std::string test_url = mServiceBuilder.buildServiceURI("ServiceBuilderTest", data_map);
ensure_equals("Replacement URL Creation", test_url , "/agent/257c631f-a0c5-4f29-8a9f-9031feaae6c6/name");
}
template<> template<>
void ServiceBuilderTestObject::test<3>()
{
//Incorrect service test
LLSD test_block;
test_block["service-builder"] = "/agent/{$agent-id}/name";
mServiceBuilder.createServiceDefinition("ServiceBuilderTest", test_block["service-builder"]);
std::string test_url = mServiceBuilder.buildServiceURI("ServiceBuilder");
ensure_equals("Replacement URL Creation for Non-existant Service", test_url , "");
}
template<> template<>
void ServiceBuilderTestObject::test<4>()
{
//Incorrect service test
LLSD test_block;
test_block["service-builder"] = "/agent/{$agent-id}/name";
mServiceBuilder.createServiceDefinition("ServiceBuilderTest", test_block["service-builder"]);
LLSD data_map;
data_map["agent_id"] = "257c631f-a0c5-4f29-8a9f-9031feaae6c6";
std::string test_url = mServiceBuilder.buildServiceURI("ServiceBuilderTest", data_map);
ensure_equals("Replacement URL Creation for Non-existant Service", test_url , "/agent/{$agent-id}/name");
}
template<> template<>
void ServiceBuilderTestObject::test<5>()
{
LLSD test_block;
test_block["service-builder"] = "/proc/{$proc}{%params}";
mServiceBuilder.createServiceDefinition("ServiceBuilderTest", test_block["service-builder"]);
LLSD data_map;
data_map["proc"] = "do/something/useful";
data_map["params"]["estate_id"] = 1;
data_map["params"]["query"] = "public";
std::string test_url = mServiceBuilder.buildServiceURI("ServiceBuilderTest", data_map);
ensure_equals(
"two part URL Creation",
test_url ,
"/proc/do/something/useful?estate_id=1&query=public");
}
template<> template<>
void ServiceBuilderTestObject::test<6>()
{
LLSD test_block;
test_block["service-builder"] = "Which way to the {${$baz}}?";
mServiceBuilder.createServiceDefinition(
"ServiceBuilderTest",
test_block["service-builder"]);
LLSD data_map;
data_map["foo"] = "bar";
data_map["baz"] = "foo";
std::string test_url = mServiceBuilder.buildServiceURI(
"ServiceBuilderTest",
data_map);
ensure_equals(
"recursive url creation",
test_url ,
"Which way to the bar?");
}
template<> template<>
void ServiceBuilderTestObject::test<7>()
{
LLSD test_block;
test_block["service-builder"] = "Which way to the {$foo}?";
mServiceBuilder.createServiceDefinition(
"ServiceBuilderTest",
test_block["service-builder"]);
LLSD data_map;
data_map["baz"] = "foo";
std::string test_url = mServiceBuilder.buildServiceURI(
"ServiceBuilderTest",
data_map);
ensure_equals(
"fails to do replacement",
test_url ,
"Which way to the {$foo}?");
}
template<> template<>
void ServiceBuilderTestObject::test<8>()
{
LLSD test_block;
test_block["service-builder"] = "/proc/{$proc}{%params}";
mServiceBuilder.createServiceDefinition(
"ServiceBuilderTest",
test_block["service-builder"]);
LLSD data_map;
data_map["proc"] = "do/something/useful";
data_map["params"] = LLSD();
std::string test_url = mServiceBuilder.buildServiceURI(
"ServiceBuilderTest",
data_map);
ensure_equals(
"strip params",
test_url ,
"/proc/do/something/useful");
}
}

View File

@@ -0,0 +1,897 @@
/**
* @file llstreamtools_tut.cpp
* @author Adroit
* @date February 2007
* @brief llstreamtools test cases.
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "llstreamtools.h"
#include "lltut.h"
namespace tut
{
struct streamtools_data
{
};
typedef test_group<streamtools_data> streamtools_test;
typedef streamtools_test::object streamtools_object;
tut::streamtools_test streamtools_testcase("streamtools");
//test cases for skip_whitespace()
template<> template<>
void streamtools_object::test<1>()
{
char arr[255];
std::string str;
std::string expected_result;
std::string actual_result;
std::istringstream is;
is.str(str = "");
ensure("skip_whitespace: empty string", (false == skip_whitespace(is)));
is.clear();
is.str(str = " SecondLife is a 3D World");
skip_whitespace(is);
is.get(arr, 255, '\0');
expected_result = "SecondLife is a 3D World";
ensure_equals("skip_whitespace: space", arr, expected_result);
is.clear();
is.str(str = "\t \tSecondLife is a 3D World");
skip_whitespace(is);
is.get(arr, 255, '\0');
expected_result = "SecondLife is a 3D World";
ensure_equals("skip_whitespace: space and tabs", arr, expected_result);
is.clear();
is.str(str = "\t \tSecondLife is a 3D World ");
skip_whitespace(is);
is.get(arr, 255, '\0');
expected_result = "SecondLife is a 3D World ";
ensure_equals("skip_whitespace: space at end", arr, expected_result);
is.clear();
is.str(str = "\t \r\nSecondLife is a 3D World");
skip_whitespace(is);
is.get(arr, 255, '\0');
expected_result = "\r\nSecondLife is a 3D World";
ensure_equals("skip_whitespace: space at end", arr, expected_result);
}
//testcases for skip_emptyspaces()
template<> template<>
void streamtools_object::test<2>()
{
char arr[255];
std::string str;
std::string expected_result;
std::string actual_result;
std::istringstream is;
bool ret;
is.clear();
is.str(str = " \tSecondLife is a 3D World.\n");
skip_emptyspace(is);
is.get(arr, 255, '\0');
expected_result = "SecondLife is a 3D World.\n";
ensure_equals("skip_emptyspace: space and tabs", arr, expected_result);
is.clear();
is.str(str = " \t\r\n \r SecondLife is a 3D World.\n");
skip_emptyspace(is);
is.get(arr, 255, '\0');
expected_result = "SecondLife is a 3D World.\n";
ensure_equals("skip_emptyspace: space, tabs, carriage return, newline", arr, expected_result);
is.clear();
is.str(str = "");
ret = skip_emptyspace(is);
is.get(arr, 255, '\0');
ensure("skip_emptyspace: empty string", ret == false);
is.clear();
is.str(str = " \r\n \t ");
ret = skip_emptyspace(is);
is.get(arr, 255, '\0');
ensure("skip_emptyspace: space newline empty", ret == false);
}
//testcases for skip_comments_and_emptyspace()
template<> template<>
void streamtools_object::test<3>()
{
char arr[255];
std::string str;
std::string expected_result;
std::string actual_result;
std::istringstream is;
bool ret;
is.clear();
is.str(str = " \t\r\n \r SecondLife is a 3D World.\n");
skip_comments_and_emptyspace(is);
is.get(arr, 255, '\0');
expected_result = "SecondLife is a 3D World.\n";
ensure_equals("skip_comments_and_emptyspace: space, tabs, carriage return, newline", arr, expected_result);
is.clear();
is.str(str = "# \r\n SecondLife is a 3D World.");
skip_comments_and_emptyspace(is);
is.get(arr, 255, '\0');
expected_result = "SecondLife is a 3D World.";
ensure_equals("skip_comments_and_emptyspace: skip comment - 1", arr, expected_result);
is.clear();
is.str(str = "# \r\n # SecondLife is a 3D World. ##");
skip_comments_and_emptyspace(is);
is.get(arr, 255, '\0');
expected_result = "";
ensure_equals("skip_comments_and_emptyspace: skip comment - 2", arr, expected_result);
is.clear();
is.str(str = " \r\n SecondLife is a 3D World. ##");
skip_comments_and_emptyspace(is);
is.get(arr, 255, '\0');
expected_result = "SecondLife is a 3D World. ##";
ensure_equals("skip_comments_and_emptyspace: skip comment - 3", arr, expected_result);
is.clear();
is.str(str = "");
ret = skip_comments_and_emptyspace(is);
is.get(arr, 255, '\0');
ensure("skip_comments_and_emptyspace: empty string", ret == false);
is.clear();
is.str(str = " \r\n \t # SecondLife is a 3D World");
ret = skip_comments_and_emptyspace(is);
is.get(arr, 255, '\0');
ensure("skip_comments_and_emptyspace: space newline comment empty", ret == false);
}
//testcases for skip_line()
template<> template<>
void streamtools_object::test<4>()
{
char arr[255];
std::string str;
std::string expected_result;
std::string actual_result;
std::istringstream is;
bool ret;
is.clear();
is.str(str = "SecondLife is a 3D World.\n\n It provides an opportunity to the site \nuser to perform real life activities in virtual world.");
skip_line(is);
is.get(arr, 255, '\0');
expected_result = "\n It provides an opportunity to the site \nuser to perform real life activities in virtual world.";
ensure_equals("skip_line: 1 newline", arr, expected_result);
is.clear();
is.str(expected_result);
skip_line(is);
is.get(arr, 255, '\0');
expected_result = " It provides an opportunity to the site \nuser to perform real life activities in virtual world.";
ensure_equals("skip_line: 2 newline", arr, expected_result);
is.clear();
is.str(expected_result);
skip_line(is);
is.get(arr, 255, '\0');
expected_result = "user to perform real life activities in virtual world.";
ensure_equals("skip_line: 3 newline", arr, expected_result);
is.clear();
is.str(str = "");
ret = skip_line(is);
ensure("skip_line: empty string", ret == false);
}
// testcases for skip_to_next_word()
template<> template<>
void streamtools_object::test<5>()
{
char arr[255];
std::string str;
std::string expected_result;
std::string actual_result;
std::istringstream is;
bool ret;
is.clear();
is.str(str = "SecondLife is a 3D_World.\n\n It-provides an opportunity to the site \nuser to perform real life activities in virtual world.");
skip_to_next_word(is); // get past SecondLife
is.get(arr, 255, '\0');
expected_result = "is a 3D_World.\n\n It-provides an opportunity to the site \nuser to perform real life activities in virtual world.";
ensure_equals("skip_to_next_word: 1", arr, expected_result);
is.clear();
is.str(expected_result);
skip_to_next_word(is); // get past is
skip_to_next_word(is); // get past a
skip_to_next_word(is); // get past 3D_World.\n\n
is.get(arr, 255, '\0');
expected_result = "It-provides an opportunity to the site \nuser to perform real life activities in virtual world.";
ensure_equals("skip_to_next_word: get past .\n\n 2", arr, expected_result);
is.clear();
is.str(expected_result);
skip_to_next_word(is); // get past It-
expected_result = "provides an opportunity to the site \nuser to perform real life activities in virtual world.";
is.get(arr, 255, '\0');
ensure_equals("skip_to_next_word: get past -", arr, expected_result);
is.clear();
is.str(str = "");
ret = skip_to_next_word(is);
ensure("skip_line: empty string", ret == false);
is.clear();
is.str(str = " \r\n\r\n");
ret = skip_to_next_word(is);
ensure("skip_line: space new lines", ret == false);
}
//testcases for skip_to_end_of_next_keyword()
template<> template<>
void streamtools_object::test<6>()
{
char arr[255];
std::string str;
std::string expected_result;
std::string actual_result;
std::istringstream is;
bool ret;
is.clear();
is.str(str = "FIRSTKEY followed by second delimiter\nSECONDKEY\t SecondValue followed by third delimiter \nSECONDKEY\nFOURTHKEY FOURTHVALUEis a 3DWorld.");
ret = skip_to_end_of_next_keyword("FIRSTKEY", is);
is.get(arr, 255, '\0');
expected_result = " followed by second delimiter\nSECONDKEY\t SecondValue followed by third delimiter \nSECONDKEY\nFOURTHKEY FOURTHVALUEis a 3DWorld.";
ensure_equals("skip_to_end_of_next_keyword: 1", arr, expected_result);
is.clear();
is.str(expected_result);
ret = skip_to_end_of_next_keyword("SECONDKEY", is);
is.get(arr, 255, '\0');
expected_result = "\t SecondValue followed by third delimiter \nSECONDKEY\nFOURTHKEY FOURTHVALUEis a 3DWorld.";
ensure_equals("skip_to_end_of_next_keyword: 2", arr, expected_result);
is.clear();
is.str(expected_result);
ret = skip_to_end_of_next_keyword("SECONDKEY", is);
is.get(arr, 255, '\0');
expected_result = "\nFOURTHKEY FOURTHVALUEis a 3DWorld.";
ensure_equals("skip_to_end_of_next_keyword: 3", arr, expected_result);
is.clear();
is.str(expected_result);
ret = skip_to_end_of_next_keyword("FOURTHKEY", is);
is.get(arr, 255, '\0');
expected_result = " FOURTHVALUEis a 3DWorld.";
ensure_equals("skip_to_end_of_next_keyword: 4", arr, expected_result);
is.clear();
is.str(str = "{should be skipped as newline/space/tab does not follow but this one should be picked\n { Does it?\n");
ret = skip_to_end_of_next_keyword("{", is);
is.get(arr, 255, '\0');
expected_result = " Does it?\n";
ensure_equals("skip_to_end_of_next_keyword: multiple delim matches on same line", arr, expected_result);
is.clear();
is.str(str = "Delim { could not be found at start");
ret = skip_to_end_of_next_keyword("{", is);
ensure("skip_to_end_of_next_keyword: delim should not be present", ret == false);
is.clear();
is.str(str = "Empty Delim");
ret = skip_to_end_of_next_keyword("", is);
ensure("skip_to_end_of_next_keyword: empty delim should not be valid", ret == false);
is.clear();
is.str(str = "");
ret = skip_to_end_of_next_keyword("}", is);
ensure("skip_to_end_of_next_keyword: empty string", ret == false);
}
//testcases for get_word(std::string& output_string, std::istream& input_stream)
template<> template<>
void streamtools_object::test<7>()
{
std::string str;
std::string expected_result;
std::string actual_result;
std::istringstream is;
bool ret;
is.clear();
is.str(str = " First Second \t \r \n Third Fourth-ShouldThisBePartOfFourth Fifth\n");
actual_result = "";
ret = get_word(actual_result, is);
expected_result = "First";
ensure_equals("get_word: 1", actual_result, expected_result);
actual_result = "";
ret = get_word(actual_result, is);
expected_result = "Second";
ensure_equals("get_word: 2", actual_result, expected_result);
actual_result = "";
ret = get_word(actual_result, is);
expected_result = "Third";
ensure_equals("get_word: 3", actual_result, expected_result);
// the current implementation of get_word seems inconsistent with
// skip_to_next_word. skip_to_next_word treats any character other
// than alhpa-numeric and '_' as a delimter, while get_word()
// treats only isspace() (i.e. space, form-feed('\f'), newline ('\n'),
// carriage return ('\r'), horizontal tab ('\t'), and vertical tab ('\v')
// as delimiters
actual_result = "";
ret = get_word(actual_result, is); // will copy Fourth-ShouldThisBePartOfFourth
expected_result = "Fourth-ShouldThisBePartOfFourth"; // as per current impl.
ensure_equals("get_word: 4", actual_result, expected_result);
actual_result = "";
ret = get_word(actual_result, is); // will copy Fifth
expected_result = "Fifth"; // as per current impl.
ensure_equals("get_word: 5", actual_result, expected_result);
is.clear();
is.str(str = " \t \r \n ");
actual_result = "";
ret = get_word(actual_result, is);
ensure("get_word: empty all spaces, newline tabs", ret == false);
is.clear();
is.str(str = "");
actual_result = "";
ret = get_word(actual_result, is);
ensure("get_word: empty string", ret == false);
}
// testcase for get_word and skip_to_next_word compatibility
template<> template<>
void streamtools_object::test<8>()
{
std::string str;
std::string expected_result;
std::string actual_result;
std::istringstream is;
bool ret;
is.clear();
is.str(str = " First Second \t \r \n Third Fourth-ShouldThisBePartOfFourth Fifth\n");
actual_result = "";
ret = get_word(actual_result, is); // First
actual_result = "";
ret = get_word(actual_result, is); // Second
actual_result = "";
ret = get_word(actual_result, is); // Third
// the current implementation of get_word seems inconsistent with
// skip_to_next_word. skip_to_next_word treats any character other
// than alhpa-numeric and '_' as a delimter, while get_word()
// treats only isspace() (i.e. space, form-feed('\f'), newline ('\n'),
// carriage return ('\r'), horizontal tab ('\t'), and vertical tab ('\v')
// as delimiters
actual_result = "";
ret = get_word(actual_result, is); // will copy Fourth-ShouldThisBePartOfFourth
actual_result = "";
ret = get_word(actual_result, is); // will copy Fifth
is.clear();
is.str(str = " First Second \t \r \n Third Fourth_ShouldThisBePartOfFourth Fifth\n");
ret = skip_to_next_word(is); // should now point to First
ret = skip_to_next_word(is); // should now point to Second
ret = skip_to_next_word(is); // should now point to Third
ret = skip_to_next_word(is); // should now point to Fourth
ret = skip_to_next_word(is); // should now point to ShouldThisBePartOfFourth
expected_result = "";
// will copy ShouldThisBePartOfFourth, the fifth word,
// while using get_word above five times result in getting "Fifth"
ret = get_word(expected_result, is);
ensure_equals("get_word: skip_to_next_word compatibility", actual_result, expected_result);
}
//testcases for get_word(std::string& output_string, std::istream& input_stream, int n)
template<> template<>
void streamtools_object::test<9>()
{
std::string str;
std::string expected_result;
std::string actual_result;
std::istringstream is;
bool ret;
is.clear();
is.str(str = " First Second \t \r \n Third Fourth-ShouldThisBePartOfFourth Fifth\n");
actual_result = "";
ret = get_word(actual_result, is, 255);
expected_result = "First";
ensure_equals("get_word: 1", actual_result, expected_result);
actual_result = "";
ret = get_word(actual_result, is, 4);
expected_result = "Seco"; // should be cut short
ensure_equals("get_word: 2", actual_result, expected_result);
actual_result = "";
ret = get_word(actual_result, is, 255);
expected_result = "nd"; // get remainder of Second
ensure_equals("get_word: 3", actual_result, expected_result);
actual_result = "";
ret = get_word(actual_result, is, 0); // 0 size string
expected_result = ""; // get remainder of Second
ensure_equals("get_word: 0 sized output", actual_result, expected_result);
actual_result = "";
ret = get_word(actual_result, is, 255);
expected_result = "Third";
ensure_equals("get_word: 4", actual_result, expected_result);
is.clear();
is.str(str = " \t \r \n ");
actual_result = "";
ret = get_word(actual_result, is, 255);
ensure("get_word: empty all spaces, newline tabs", ret == false);
is.clear();
is.str(str = "");
actual_result = "";
ret = get_word(actual_result, is, 255);
ensure("get_word: empty string", ret == false);
}
//test cases for get_line(std::string& output_string, std::istream& input_stream)
template<> template<>
void streamtools_object::test<10>()
{
std::string str;
std::string expected_result;
std::string actual_result;
std::istringstream is;
bool ret;
is.clear();
is.str(str = "First Second \t \r\n Third Fourth-ShouldThisBePartOfFourth IsThisFifth\n");
actual_result = "";
ret = get_line(actual_result, is);
expected_result = "First Second \t \r\n";
ensure_equals("get_line: 1", actual_result, expected_result);
actual_result = "";
ret = get_line(actual_result, is);
expected_result = " Third Fourth-ShouldThisBePartOfFourth IsThisFifth\n";
ensure_equals("get_line: 2", actual_result, expected_result);
is.clear();
is.str(str = "\nFirst Line.\n\nSecond Line.\n");
actual_result = "";
ret = get_line(actual_result, is);
expected_result = "\n";
ensure_equals("get_line: First char as newline", actual_result, expected_result);
actual_result = "";
ret = get_line(actual_result, is);
expected_result = "First Line.\n";
ensure_equals("get_line: 3", actual_result, expected_result);
actual_result = "";
ret = get_line(actual_result, is);
expected_result = "\n";
ensure_equals("get_line: 4", actual_result, expected_result);
actual_result = "";
ret = get_line(actual_result, is);
expected_result = "Second Line.\n";
ensure_equals("get_line: 5", actual_result, expected_result);
}
//test cases for get_line(std::string& output_string, std::istream& input_stream)
template<> template<>
void streamtools_object::test<11>()
{
std::string str;
std::string expected_result;
std::string actual_result;
std::istringstream is;
bool ret;
is.clear();
is.str(str = "One Line only with no newline");
actual_result = "";
ret = get_line(actual_result, is);
expected_result = "One Line only with no newline";
ensure_equals("get_line: No newline", actual_result, expected_result);
ensure_equals("return value is good state of stream", ret, is.good());
}
//test cases for get_line(std::string& output_string, std::istream& input_stream)
template<> template<>
void streamtools_object::test<12>()
{
std::string str;
std::string expected_result;
std::string actual_result;
std::istringstream is;
bool ret;
// need to be check if this test case is wrong or the implementation is wrong.
is.clear();
is.str(str = "Should not skip lone \r.\r\n");
actual_result = "";
ret = get_line(actual_result, is);
expected_result = "Should not skip lone \r.\r\n";
ensure_equals("get_line: carriage return skipped even though not followed by newline", actual_result, expected_result);
}
//test cases for get_line(std::string& output_string, std::istream& input_stream)
template<> template<>
void streamtools_object::test<13>()
{
std::string str;
std::string expected_result;
std::string actual_result;
std::istringstream is;
bool ret;
is.clear();
is.str(str = "\n");
actual_result = "";
ret = get_line(actual_result, is);
expected_result = "\n";
ensure_equals("get_line: Just newline", actual_result, expected_result);
}
//testcases for get_line(std::string& output_string, std::istream& input_stream, int n)
template<> template<>
void streamtools_object::test<14>()
{
std::string str;
std::string expected_result;
std::string actual_result;
std::istringstream is;
bool ret;
is.clear();
is.str(str = "First Line.\nSecond Line.\n");
actual_result = "";
ret = get_line(actual_result, is, 255);
expected_result = "First Line.\n";
ensure_equals("get_line: Basic Operation", actual_result, expected_result);
actual_result = "";
ret = get_line(actual_result, is, sizeof("Second")-1);
expected_result = "Second\n";
ensure_equals("get_line: Insufficient length 1", actual_result, expected_result);
actual_result = "";
ret = get_line(actual_result, is, 255);
expected_result = " Line.\n";
ensure_equals("get_line: Remainder after earlier insufficient length", actual_result, expected_result);
is.clear();
is.str(str = "One Line only with no newline with limited length");
actual_result = "";
ret = get_line(actual_result, is, sizeof("One Line only with no newline with limited length")-1);
expected_result = "One Line only with no newline with limited length\n";
ensure_equals("get_line: No newline with limited length", actual_result, expected_result);
is.clear();
is.str(str = "One Line only with no newline");
actual_result = "";
ret = get_line(actual_result, is, 255);
expected_result = "One Line only with no newline";
ensure_equals("get_line: No newline", actual_result, expected_result);
}
//testcases for get_line(std::string& output_string, std::istream& input_stream, int n)
template<> template<>
void streamtools_object::test<15>()
{
std::string str;
std::string expected_result;
std::string actual_result;
std::istringstream is;
bool ret;
is.clear();
is.str(str = "One Line only with no newline");
actual_result = "";
ret = get_line(actual_result, is, 255);
expected_result = "One Line only with no newline";
ensure_equals("get_line: No newline", actual_result, expected_result);
ensure_equals("return value is good state of stream", ret, is.good());
}
//testcases for remove_last_char()
template<> template<>
void streamtools_object::test<16>()
{
std::string str;
std::string expected_result;
bool ret;
str = "SecondLife is a 3D World";
ret = remove_last_char('d',str);
expected_result = "SecondLife is a 3D Worl";
ensure_equals("remove_last_char: should remove last char", str, expected_result);
str = "SecondLife is a 3D World";
ret = remove_last_char('W',str);
expected_result = "SecondLife is a 3D World";
ensure_equals("remove_last_char: should not remove as it is not last char", str, expected_result);
ensure("remove_last_char: should return false", ret == false);
str = "SecondLife is a 3D World\n";
ret = remove_last_char('\n',str);
expected_result = "SecondLife is a 3D World";
ensure_equals("remove_last_char: should remove last newline", str, expected_result);
ensure("remove_last_char: should remove newline and return true", ret == true);
}
//testcases for unescaped_string()
template<> template<>
void streamtools_object::test<17>()
{
std::string str;
std::string expected_result;
str = "SecondLife is a 3D world \\n";
unescape_string(str);
expected_result = "SecondLife is a 3D world \n";
ensure_equals("unescape_string: newline", str, expected_result);
str = "SecondLife is a 3D world \\\\t \\n";
unescape_string(str);
expected_result = "SecondLife is a 3D world \\t \n";
ensure_equals("unescape_string: backslash and newline", str, expected_result);
str = "SecondLife is a 3D world \\ ";
unescape_string(str);
expected_result = "SecondLife is a 3D world \\ ";
ensure_equals("unescape_string: insufficient to unescape", str, expected_result);
str = "SecondLife is a 3D world \\n \\n \\n \\\\\\n";
unescape_string(str);
expected_result = "SecondLife is a 3D world \n \n \n \\\n";
ensure_equals("unescape_string: multipel newline and backslash", str, expected_result);
str = "SecondLife is a 3D world \\t";
unescape_string(str);
expected_result = "SecondLife is a 3D world \\t";
ensure_equals("unescape_string: leaves tab as is", str, expected_result);
str = "\\n";
unescape_string(str);
expected_result = "\n";
ensure_equals("unescape_string: only a newline", str, expected_result);
}
//testcases for escape_string()
template<> template<>
void streamtools_object::test<18>()
{
std::string str;
std::string expected_result;
str = "SecondLife is a 3D world \n";
escape_string(str);
expected_result = "SecondLife is a 3D world \\n";
ensure_equals("escape_string: newline", str, expected_result);
str = "SecondLife is a 3D world \\t \n";
escape_string(str);
expected_result = "SecondLife is a 3D world \\\\t \\n";
ensure_equals("escape_string: backslash and newline", str, expected_result);
str = "SecondLife is a 3D world \n \n \n \\\n";
escape_string(str);
expected_result = "SecondLife is a 3D world \\n \\n \\n \\\\\\n";
ensure_equals("escape_string: multipel newline and backslash", str, expected_result);
str = "SecondLife is a 3D world \t";
escape_string(str);
expected_result = "SecondLife is a 3D world \t";
ensure_equals("unescape_string: leaves tab as is", str, expected_result);
str = "\n";
escape_string(str);
expected_result = "\\n";
ensure_equals("unescape_string: only a newline", str, expected_result);
// serialization/deserialization escape->unescape
str = "SecondLife is a 3D world \n \n \n \\\n";
escape_string(str);
unescape_string(str);
expected_result = "SecondLife is a 3D world \n \n \n \\\n";
ensure_equals("escape_string: should preserve with escape/unescape", str, expected_result);
// serialization/deserialization unescape->escape
str = "SecondLife is a 3D world \\n \\n \\n \\\\";
unescape_string(str);
escape_string(str);
expected_result = "SecondLife is a 3D world \\n \\n \\n \\\\";
ensure_equals("escape_string: should preserve with unescape/escape", str, expected_result);
}
// testcases for replace_newlines_with_whitespace()
template<> template<>
void streamtools_object::test<19>()
{
std::string str;
std::string expected_result;
str = "SecondLife is a 3D \n\nworld\n";
replace_newlines_with_whitespace(str);
expected_result = "SecondLife is a 3D world ";
ensure_equals("replace_newlines_with_whitespace: replace all newline", str, expected_result);
str = "\nSecondLife is a 3D world\n";
replace_newlines_with_whitespace(str);
expected_result = " SecondLife is a 3D world ";
ensure_equals("replace_newlines_with_whitespace: begin and newline", str, expected_result);
str = "SecondLife is a 3D world\r\t";
replace_newlines_with_whitespace(str);
expected_result = "SecondLife is a 3D world\r\t";
ensure_equals("replace_newlines_with_whitespace: should only replace newline", str, expected_result);
str = "";
replace_newlines_with_whitespace(str);
expected_result = "";
ensure_equals("replace_newlines_with_whitespace: empty string", str, expected_result);
}
//testcases for remove_double_quotes()
template<> template<>
void streamtools_object::test<20>()
{
std::string str;
std::string expected_result;
str = "SecondLife is a \"\"3D world";
remove_double_quotes(str);
expected_result = "SecondLife is a 3D world";
ensure_equals("remove_double_quotes: replace empty doube quotes", str, expected_result);
str = "SecondLife is a \"3D world";
remove_double_quotes(str);
expected_result = "SecondLife is a 3D world";
ensure_equals("remove_double_quotes: keep as is it matching quote not found", str, expected_result);
}
// testcases for get_brace_count()
template<> template<>
void streamtools_object::test<21>()
{
}
//testcases for get_keyword_and_value()
template<> template<>
void streamtools_object::test<22>()
{
std::string s = "SecondLife is a 3D World";
std::string keyword;
std::string value;
get_keyword_and_value(keyword, value, s);
ensure("get_keyword_and_value: Unable to get Keyword and Value", ((keyword == "SecondLife") && (value == "is a 3D World")));
s = "SecondLife";
get_keyword_and_value(keyword, value, s);
ensure("get_keyword_and_value: value should be empty", ((keyword == "SecondLife") && (value == "")));
s = "SecondLife \t is cool! \n";
get_keyword_and_value(keyword, value, s);
ensure("get_keyword_and_value: remove space before value but not after", ((keyword == "SecondLife") && (value == "is cool! ")));
}
//testcases for get_keyword_and_value()
template<> template<>
void streamtools_object::test<23>()
{
std::string s;
std::string keyword = "SOME PRIOR KEYWORD";
std::string value = "SOME PRIOR VALUE";
s = "SecondLife\n";
get_keyword_and_value(keyword, value, s);
ensure("get_keyword_and_value: terminated with newline. value should be empty", ((keyword == "SecondLife") && (value == "")));
}
//testcases for get_keyword_and_value()
template<> template<>
void streamtools_object::test<24>()
{
std::string s;
std::string keyword = "SOME PRIOR KEYWORD";
std::string value = "SOME PRIOR VALUE";
s = "";
get_keyword_and_value(keyword, value, s);
ensure("get_keyword_and_value: empty string. keyword value should empty", ((keyword == "") && (value == "")));
}
//testcase for fullread()
template<> template<>
void streamtools_object::test<25>()
{
std::string str = "First Line.\nSecond Line\n";
std::istringstream is(str);
char buf[255] = {0};
fullread(is, buf, 255);
ensure_memory_matches("fullread: read with newlines", (void*) buf, str.size()-1, (void*) str.c_str(), str.size()-1);
is.clear();
is.str(str = "First Line.\nSecond Line\n");
memset(buf, 0, 255);
char expected_string[] = "First Line.\nSecond";
int len = sizeof(expected_string)-1;
fullread(is, buf, len);
ensure_memory_matches("fullread: read with newlines", (void*) buf, len, (void*) &expected_string, len);
}
// testcases for operator >>
template<> template<>
void streamtools_object::test<26>()
{
char arr[255];
std::string str;
std::string toCheck = "SecondLife" ;
std::string expected_result;
std::istringstream stream("SecondLife is a 3D World");
stream >> toCheck.c_str();
stream.get(arr, 255, '\0');
expected_result = " is a 3D World";
ensure_equals("istream << operator", arr, expected_result);
stream.clear();
stream.str(str = "SecondLife is a 3D World");
toCheck = "is";
stream >> toCheck.c_str();
ensure("istream << operator should have failed", stream.good() == false);
}
}

671
indra/test/llstring_tut.cpp Normal file
View File

@@ -0,0 +1,671 @@
/**
* @file llstring_tut.cpp
* @author Adroit
* @date 2006-12-24
* @brief Test cases of llstring.cpp
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include <tut/tut.hpp>
#include "lltut.h"
#include "llstring.h"
namespace tut
{
struct string_index
{
};
typedef test_group<string_index> string_index_t;
typedef string_index_t::object string_index_object_t;
tut::string_index_t tut_string_index("string_test");
template<> template<>
void string_index_object_t::test<1>()
{
std::string llstr1;
ensure("Empty std::string", (llstr1.size() == 0) && llstr1.empty());
std::string llstr2("Hello");
ensure("std::string = Hello", (!strcmp(llstr2.c_str(), "Hello")) && (llstr2.size() == 5) && !llstr2.empty());
std::string llstr3(llstr2);
ensure("std::string = std::string(std::string)", (!strcmp(llstr3.c_str(), "Hello")) && (llstr3.size() == 5) && !llstr3.empty());
std::string str("Hello World");
std::string llstr4(str, 6);
ensure("std::string = std::string(s, size_type pos, size_type n = npos)", (!strcmp(llstr4.c_str(), "World")) && (llstr4.size() == 5) && !llstr4.empty());
std::string llstr5(str, str.size());
ensure("std::string = std::string(s, size_type pos, size_type n = npos)", (llstr5.size() == 0) && llstr5.empty());
std::string llstr6(5, 'A');
ensure("std::string = std::string(count, c)", (!strcmp(llstr6.c_str(), "AAAAA")) && (llstr6.size() == 5) && !llstr6.empty());
std::string llstr7("Hello World", 5);
ensure("std::string(s, n)", (!strcmp(llstr7.c_str(), "Hello")) && (llstr7.size() == 5) && !llstr7.empty());
std::string llstr8("Hello World", 6, 5);
ensure("std::string(s, n, count)", (!strcmp(llstr8.c_str(), "World")) && (llstr8.size() == 5) && !llstr8.empty());
std::string llstr9("Hello World", sizeof("Hello World")-1, 5); // go past end
ensure("std::string(s, n, count) goes past end", (llstr9.size() == 0) && llstr9.empty());
}
template<> template<>
void string_index_object_t::test<3>()
{
std::string str("Len=5");
ensure("isValidIndex failed", LLStringUtil::isValidIndex(str, 0) == TRUE &&
LLStringUtil::isValidIndex(str, 5) == TRUE &&
LLStringUtil::isValidIndex(str, 6) == FALSE);
std::string str1;
ensure("isValidIndex failed fo rempty string", LLStringUtil::isValidIndex(str1, 0) == FALSE);
}
template<> template<>
void string_index_object_t::test<4>()
{
std::string str_val(" Testing the extra whitespaces ");
LLStringUtil::trimHead(str_val);
ensure_equals("1: trimHead failed", str_val, "Testing the extra whitespaces ");
std::string str_val1("\n\t\r\n Testing the extra whitespaces ");
LLStringUtil::trimHead(str_val1);
ensure_equals("2: trimHead failed", str_val1, "Testing the extra whitespaces ");
}
template<> template<>
void string_index_object_t::test<5>()
{
std::string str_val(" Testing the extra whitespaces ");
LLStringUtil::trimTail(str_val);
ensure_equals("1: trimTail failed", str_val, " Testing the extra whitespaces");
std::string str_val1("\n Testing the extra whitespaces \n\t\r\n ");
LLStringUtil::trimTail(str_val1);
ensure_equals("2: trimTail failed", str_val1, "\n Testing the extra whitespaces");
}
template<> template<>
void string_index_object_t::test<6>()
{
std::string str_val(" \t \r Testing the extra \r\n whitespaces \n \t ");
LLStringUtil::trim(str_val);
ensure_equals("1: trim failed", str_val, "Testing the extra \r\n whitespaces");
}
template<> template<>
void string_index_object_t::test<7>()
{
std::string str("Second LindenLabs");
LLStringUtil::truncate(str, 6);
ensure_equals("1: truncate", str, "Second");
// further truncate more than the length
LLStringUtil::truncate(str, 0);
ensure_equals("2: truncate", str, "");
}
template<> template<>
void string_index_object_t::test<8>()
{
std::string str_val("SecondLife Source");
LLStringUtil::toUpper(str_val);
ensure_equals("toUpper failed", str_val, "SECONDLIFE SOURCE");
}
template<> template<>
void string_index_object_t::test<9>()
{
std::string str_val("SecondLife Source");
LLStringUtil::toLower(str_val);
ensure_equals("toLower failed", str_val, "secondlife source");
}
template<> template<>
void string_index_object_t::test<10>()
{
std::string str_val("Second");
ensure("1. isHead failed", LLStringUtil::isHead(str_val, "SecondLife Source") == TRUE);
ensure("2. isHead failed", LLStringUtil::isHead(str_val, " SecondLife Source") == FALSE);
std::string str_val2("");
ensure("3. isHead failed", LLStringUtil::isHead(str_val2, "") == FALSE);
}
template<> template<>
void string_index_object_t::test<11>()
{
std::string str_val("Hello.\n\n Lindenlabs. \n This is \na simple test.\n");
std::string orig_str_val(str_val);
LLStringUtil::addCRLF(str_val);
ensure_equals("addCRLF failed", str_val, "Hello.\r\n\r\n Lindenlabs. \r\n This is \r\na simple test.\r\n");
LLStringUtil::removeCRLF(str_val);
ensure_equals("removeCRLF failed", str_val, orig_str_val);
}
template<> template<>
void string_index_object_t::test<12>()
{
std::string str_val("Hello.\n\n\t \t Lindenlabs. \t\t");
std::string orig_str_val(str_val);
LLStringUtil::replaceTabsWithSpaces(str_val, 1);
ensure_equals("replaceTabsWithSpaces failed", str_val, "Hello.\n\n Lindenlabs. ");
LLStringUtil::replaceTabsWithSpaces(orig_str_val, 0);
ensure_equals("replaceTabsWithSpaces failed for 0", orig_str_val, "Hello.\n\n Lindenlabs. ");
str_val = "\t\t\t\t";
LLStringUtil::replaceTabsWithSpaces(str_val, 0);
ensure_equals("replaceTabsWithSpaces failed for all tabs", str_val, "");
}
template<> template<>
void string_index_object_t::test<13>()
{
std::string str_val("Hello.\n\n\t\t\r\nLindenlabsX.");
LLStringUtil::replaceNonstandardASCII(str_val, 'X');
ensure_equals("replaceNonstandardASCII failed", str_val, "Hello.\n\nXXX\nLindenlabsX.");
}
template<> template<>
void string_index_object_t::test<14>()
{
std::string str_val("Hello.\n\t\r\nABCDEFGHIABABAB");
LLStringUtil::replaceChar(str_val, 'A', 'X');
ensure_equals("1: replaceChar failed", str_val, "Hello.\n\t\r\nXBCDEFGHIXBXBXB");
std::string str_val1("Hello.\n\t\r\nABCDEFGHIABABAB");
}
template<> template<>
void string_index_object_t::test<15>()
{
std::string str_val("Hello.\n\r\t");
ensure("containsNonprintable failed", LLStringUtil::containsNonprintable(str_val) == TRUE);
str_val = "ABC ";
ensure("containsNonprintable failed", LLStringUtil::containsNonprintable(str_val) == FALSE);
}
template<> template<>
void string_index_object_t::test<16>()
{
std::string str_val("Hello.\n\r\t Again!");
LLStringUtil::stripNonprintable(str_val);
ensure_equals("stripNonprintable failed", str_val, "Hello. Again!");
str_val = "\r\n\t\t";
LLStringUtil::stripNonprintable(str_val);
ensure_equals("stripNonprintable resulting in empty string failed", str_val, "");
}
template<> template<>
void string_index_object_t::test<17>()
{
BOOL value;
std::string str_val("1");
ensure("convertToBOOL 1 failed", LLStringUtil::convertToBOOL(str_val, value) && value);
str_val = "T";
ensure("convertToBOOL T failed", LLStringUtil::convertToBOOL(str_val, value) && value);
str_val = "t";
ensure("convertToBOOL t failed", LLStringUtil::convertToBOOL(str_val, value) && value);
str_val = "TRUE";
ensure("convertToBOOL TRUE failed", LLStringUtil::convertToBOOL(str_val, value) && value);
str_val = "True";
ensure("convertToBOOL True failed", LLStringUtil::convertToBOOL(str_val, value) && value);
str_val = "true";
ensure("convertToBOOL true failed", LLStringUtil::convertToBOOL(str_val, value) && value);
str_val = "0";
ensure("convertToBOOL 0 failed", LLStringUtil::convertToBOOL(str_val, value) && !value);
str_val = "F";
ensure("convertToBOOL F failed", LLStringUtil::convertToBOOL(str_val, value) && !value);
str_val = "f";
ensure("convertToBOOL f failed", LLStringUtil::convertToBOOL(str_val, value) && !value);
str_val = "FALSE";
ensure("convertToBOOL FASLE failed", LLStringUtil::convertToBOOL(str_val, value) && !value);
str_val = "False";
ensure("convertToBOOL False failed", LLStringUtil::convertToBOOL(str_val, value) && !value);
str_val = "false";
ensure("convertToBOOL false failed", LLStringUtil::convertToBOOL(str_val, value) && !value);
str_val = "Tblah";
ensure("convertToBOOL false failed", !LLStringUtil::convertToBOOL(str_val, value));
}
template<> template<>
void string_index_object_t::test<18>()
{
U8 value;
std::string str_val("255");
ensure("1: convertToU8 failed", LLStringUtil::convertToU8(str_val, value) && value == 255);
str_val = "0";
ensure("2: convertToU8 failed", LLStringUtil::convertToU8(str_val, value) && value == 0);
str_val = "-1";
ensure("3: convertToU8 failed", !LLStringUtil::convertToU8(str_val, value));
str_val = "256"; // bigger than MAX_U8
ensure("4: convertToU8 failed", !LLStringUtil::convertToU8(str_val, value));
}
template<> template<>
void string_index_object_t::test<19>()
{
S8 value;
std::string str_val("127");
ensure("1: convertToS8 failed", LLStringUtil::convertToS8(str_val, value) && value == 127);
str_val = "0";
ensure("2: convertToS8 failed", LLStringUtil::convertToS8(str_val, value) && value == 0);
str_val = "-128";
ensure("3: convertToS8 failed", LLStringUtil::convertToS8(str_val, value) && value == -128);
str_val = "128"; // bigger than MAX_S8
ensure("4: convertToS8 failed", !LLStringUtil::convertToS8(str_val, value));
str_val = "-129";
ensure("5: convertToS8 failed", !LLStringUtil::convertToS8(str_val, value));
}
template<> template<>
void string_index_object_t::test<20>()
{
S16 value;
std::string str_val("32767");
ensure("1: convertToS16 failed", LLStringUtil::convertToS16(str_val, value) && value == 32767);
str_val = "0";
ensure("2: convertToS16 failed", LLStringUtil::convertToS16(str_val, value) && value == 0);
str_val = "-32768";
ensure("3: convertToS16 failed", LLStringUtil::convertToS16(str_val, value) && value == -32768);
str_val = "32768";
ensure("4: convertToS16 failed", !LLStringUtil::convertToS16(str_val, value));
str_val = "-32769";
ensure("5: convertToS16 failed", !LLStringUtil::convertToS16(str_val, value));
}
template<> template<>
void string_index_object_t::test<21>()
{
U16 value;
std::string str_val("65535"); //0xFFFF
ensure("1: convertToU16 failed", LLStringUtil::convertToU16(str_val, value) && value == 65535);
str_val = "0";
ensure("2: convertToU16 failed", LLStringUtil::convertToU16(str_val, value) && value == 0);
str_val = "-1";
ensure("3: convertToU16 failed", !LLStringUtil::convertToU16(str_val, value));
str_val = "65536";
ensure("4: convertToU16 failed", !LLStringUtil::convertToU16(str_val, value));
}
template<> template<>
void string_index_object_t::test<22>()
{
U32 value;
std::string str_val("4294967295"); //0xFFFFFFFF
ensure("1: convertToU32 failed", LLStringUtil::convertToU32(str_val, value) && value == 4294967295UL);
str_val = "0";
ensure("2: convertToU32 failed", LLStringUtil::convertToU32(str_val, value) && value == 0);
str_val = "4294967296";
ensure("3: convertToU32 failed", !LLStringUtil::convertToU32(str_val, value));
}
template<> template<>
void string_index_object_t::test<23>()
{
S32 value;
std::string str_val("2147483647"); //0x7FFFFFFF
ensure("1: convertToS32 failed", LLStringUtil::convertToS32(str_val, value) && value == 2147483647);
str_val = "0";
ensure("2: convertToS32 failed", LLStringUtil::convertToS32(str_val, value) && value == 0);
// Avoid "unary minus operator applied to unsigned type" warning on VC++. JC
S32 min_val = -2147483647 - 1;
str_val = "-2147483648";
ensure("3: convertToS32 failed", LLStringUtil::convertToS32(str_val, value) && value == min_val);
str_val = "2147483648";
ensure("4: convertToS32 failed", !LLStringUtil::convertToS32(str_val, value));
str_val = "-2147483649";
ensure("5: convertToS32 failed", !LLStringUtil::convertToS32(str_val, value));
}
template<> template<>
void string_index_object_t::test<24>()
{
F32 value;
std::string str_val("2147483647"); //0x7FFFFFFF
ensure("1: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == 2147483647);
str_val = "0";
ensure("2: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == 0);
/* Need to find max/min F32 values
str_val = "-2147483648";
ensure("3: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == -2147483648);
str_val = "2147483648";
ensure("4: convertToF32 failed", !LLStringUtil::convertToF32(str_val, value));
str_val = "-2147483649";
ensure("5: convertToF32 failed", !LLStringUtil::convertToF32(str_val, value));
*/
}
template<> template<>
void string_index_object_t::test<25>()
{
F64 value;
std::string str_val("9223372036854775807"); //0x7FFFFFFFFFFFFFFF
ensure("1: convertToF64 failed", LLStringUtil::convertToF64(str_val, value) && value == 9223372036854775807LL);
str_val = "0";
ensure("2: convertToF64 failed", LLStringUtil::convertToF64(str_val, value) && value == 0.0F);
/* Need to find max/min F64 values
str_val = "-2147483648";
ensure("3: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == -2147483648);
str_val = "2147483648";
ensure("4: convertToF32 failed", !LLStringUtil::convertToF32(str_val, value));
str_val = "-2147483649";
ensure("5: convertToF32 failed", !LLStringUtil::convertToF32(str_val, value));
*/
}
template<> template<>
void string_index_object_t::test<26>()
{
const char* str1 = NULL;
const char* str2 = NULL;
ensure("1: compareStrings failed", LLStringUtil::compareStrings(str1, str2) == 0);
str2 = "A";
ensure("2: compareStrings failed", LLStringUtil::compareStrings(str1, str2) > 0);
ensure("3: compareStrings failed", LLStringUtil::compareStrings(str2, str1) < 0);
str1 = "A is smaller than B";
str2 = "B is greater than A";
ensure("4: compareStrings failed", LLStringUtil::compareStrings(str1, str2) < 0);
str2 = "A is smaller than B";
ensure("5: compareStrings failed", LLStringUtil::compareStrings(str1, str2) == 0);
}
template<> template<>
void string_index_object_t::test<27>()
{
const char* str1 = NULL;
const char* str2 = NULL;
ensure("1: compareInsensitive failed", LLStringUtil::compareInsensitive(str1, str2) == 0);
str2 = "A";
ensure("2: compareInsensitive failed", LLStringUtil::compareInsensitive(str1, str2) > 0);
ensure("3: compareInsensitive failed", LLStringUtil::compareInsensitive(str2, str1) < 0);
str1 = "A is equal to a";
str2 = "a is EQUAL to A";
ensure("4: compareInsensitive failed", LLStringUtil::compareInsensitive(str1, str2) == 0);
}
template<> template<>
void string_index_object_t::test<28>()
{
std::string lhs_str("PROgraM12files");
std::string rhs_str("PROgram12Files");
ensure("compareDict 1 failed", LLStringUtil::compareDict(lhs_str, rhs_str) < 0);
ensure("precedesDict 1 failed", LLStringUtil::precedesDict(lhs_str, rhs_str) == TRUE);
lhs_str = "PROgram12Files";
rhs_str = "PROgram12Files";
ensure("compareDict 2 failed", LLStringUtil::compareDict(lhs_str, rhs_str) == 0);
ensure("precedesDict 2 failed", LLStringUtil::precedesDict(lhs_str, rhs_str) == FALSE);
lhs_str = "PROgram12Files";
rhs_str = "PROgRAM12FILES";
ensure("compareDict 3 failed", LLStringUtil::compareDict(lhs_str, rhs_str) > 0);
ensure("precedesDict 3 failed", LLStringUtil::precedesDict(lhs_str, rhs_str) == FALSE);
}
template<> template<>
void string_index_object_t::test<29>()
{
char str1[] = "First String...";
char str2[100];
LLStringUtil::copy(str2, str1, 100);
ensure("LLStringUtil::copy with enough dest length failed", strcmp(str2, str1) == 0);
LLStringUtil::copy(str2, str1, sizeof("First"));
ensure("LLStringUtil::copy with less dest length failed", strcmp(str2, "First") == 0);
}
template<> template<>
void string_index_object_t::test<30>()
{
std::string str1 = "This is the sentence...";
std::string str2 = "This is the ";
std::string str3 = "first ";
std::string str4 = "This is the first sentence...";
std::string str5 = "This is the sentence...first ";
std::string dest;
dest = str1;
LLStringUtil::copyInto(dest, str3, str2.length());
ensure("LLStringUtil::copyInto insert failed", dest == str4);
dest = str1;
LLStringUtil::copyInto(dest, str3, dest.length());
ensure("LLStringUtil::copyInto append failed", dest == str5);
}
template<> template<>
void string_index_object_t::test<31>()
{
std::string stripped;
// Plain US ASCII text, including spaces and punctuation,
// should not be altered.
std::string simple_text = "Hello, world!";
stripped = LLStringFn::strip_invalid_xml(simple_text);
ensure("Simple text passed unchanged", stripped == simple_text);
// Control characters should be removed
// except for 0x09, 0x0a, 0x0d
std::string control_chars;
for (char c = 0x01; c < 0x20; c++)
{
control_chars.push_back(c);
}
std::string allowed_control_chars;
allowed_control_chars.push_back( (char)0x09 );
allowed_control_chars.push_back( (char)0x0a );
allowed_control_chars.push_back( (char)0x0d );
stripped = LLStringFn::strip_invalid_xml(control_chars);
ensure("Only tab, LF, CR control characters allowed",
stripped == allowed_control_chars);
// UTF-8 should be passed intact, including high byte
// characters. Try Francais (with C squiggle cedilla)
std::string french = "Fran";
french.push_back( (char)0xC3 );
french.push_back( (char)0xA7 );
french += "ais";
stripped = LLStringFn::strip_invalid_xml( french );
ensure("UTF-8 high byte text is allowed", french == stripped );
}
template<> template<>
void string_index_object_t::test<32>()
{
// Test LLStringUtil::format() string interpolation
LLStringUtil::format_map_t fmt_map;
std::string s;
int subcount;
fmt_map["[TRICK1]"] = "[A]";
fmt_map["[A]"] = "a";
fmt_map["[B]"] = "b";
fmt_map["[AAA]"] = "aaa";
fmt_map["[BBB]"] = "bbb";
fmt_map["[TRICK2]"] = "[A]";
fmt_map["[EXPLOIT]"] = "!!!!!!!!!!!![EXPLOIT]!!!!!!!!!!!!";
fmt_map["[KEYLONGER]"] = "short";
fmt_map["[KEYSHORTER]"] = "Am I not a long string?";
fmt_map["?"] = "!";
fmt_map["[DELETE]"] = "";
for (LLStringUtil::format_map_t::const_iterator iter = fmt_map.begin(); iter != fmt_map.end(); ++iter)
{
// Test when source string is entirely one key
std::string s1 = (std::string)iter->first;
std::string s2 = (std::string)iter->second;
subcount = LLStringUtil::format(s1, fmt_map);
ensure_equals("LLStringUtil::format: Raw interpolation result", s1, s2);
ensure_equals("LLStringUtil::format: Raw interpolation result count", 1, subcount);
}
for (LLStringUtil::format_map_t::const_iterator iter = fmt_map.begin(); iter != fmt_map.end(); ++iter)
{
// Test when source string is one key, duplicated
std::string s1 = (std::string)iter->first;
std::string s2 = (std::string)iter->second;
s = s1 + s1 + s1 + s1;
subcount = LLStringUtil::format(s, fmt_map);
ensure_equals("LLStringUtil::format: Rawx4 interpolation result", s, s2 + s2 + s2 + s2);
ensure_equals("LLStringUtil::format: Rawx4 interpolation result count", 4, subcount);
}
// Test when source string has no keys
std::string srcs = "!!!!!!!!!!!!!!!!";
s = srcs;
subcount = LLStringUtil::format(s, fmt_map);
ensure_equals("LLStringUtil::format: No key test result", s, srcs);
ensure_equals("LLStringUtil::format: No key test result count", 0, subcount);
// Test when source string has no keys and is empty
std::string srcs3;
s = srcs3;
subcount = LLStringUtil::format(s, fmt_map);
ensure("LLStringUtil::format: No key test3 result", s.empty());
ensure_equals("LLStringUtil::format: No key test3 result count", 0, subcount);
// Test a substitution where a key is substituted with blankness
std::string srcs2 = "[DELETE]";
s = srcs2;
subcount = LLStringUtil::format(s, fmt_map);
ensure("LLStringUtil::format: Delete key test2 result", s.empty());
ensure_equals("LLStringUtil::format: Delete key test2 result count", 1, subcount);
// Test an assorted substitution
std::string srcs4 = "[TRICK1][A][B][AAA][BBB][TRICK2][KEYLONGER][KEYSHORTER]?[DELETE]";
s = srcs4;
subcount = LLStringUtil::format(s, fmt_map);
ensure_equals("LLStringUtil::format: Assorted Test1 result", s, "[A]abaaabbb[A]shortAm I not a long string?!");
ensure_equals("LLStringUtil::format: Assorted Test1 result count", 10, subcount);
// Test an assorted substitution
std::string srcs5 = "[DELETE]?[KEYSHORTER][KEYLONGER][TRICK2][BBB][AAA][B][A][TRICK1]";
s = srcs5;
subcount = LLStringUtil::format(s, fmt_map);
ensure_equals("LLStringUtil::format: Assorted Test2 result", s, "!Am I not a long string?short[A]bbbaaaba[A]");
ensure_equals("LLStringUtil::format: Assorted Test2 result count", 10, subcount);
// Test an assorted substitution
std::string srcs8 = "foo[DELETE]bar?";
s = srcs8;
subcount = LLStringUtil::format(s, fmt_map);
ensure_equals("LLStringUtil::format: Assorted Test3 result", s, "foobar!");
ensure_equals("LLStringUtil::format: Assorted Test3 result count", 2, subcount);
}
template<> template<>
void string_index_object_t::test<33>()
{
// Test LLStringUtil::format() string interpolation
LLStringUtil::format_map_t blank_fmt_map;
std::string s;
int subcount;
// Test substituting out of a blank format_map
std::string srcs6 = "12345";
s = srcs6;
subcount = LLStringUtil::format(s, blank_fmt_map);
ensure_equals("LLStringUtil::format: Blankfmt Test1 result", s, "12345");
ensure_equals("LLStringUtil::format: Blankfmt Test1 result count", 0, subcount);
// Test substituting a blank string out of a blank format_map
std::string srcs7;
s = srcs7;
subcount = LLStringUtil::format(s, blank_fmt_map);
ensure("LLStringUtil::format: Blankfmt Test2 result", s.empty());
ensure_equals("LLStringUtil::format: Blankfmt Test2 result count", 0, subcount);
}
template<> template<>
void string_index_object_t::test<34>()
{
// Test that incorrect LLStringUtil::format() use does not explode.
LLStringUtil::format_map_t nasty_fmt_map;
std::string s;
int subcount;
nasty_fmt_map[""] = "never used"; // see, this is nasty.
// Test substituting out of a nasty format_map
std::string srcs6 = "12345";
s = srcs6;
subcount = LLStringUtil::format(s, nasty_fmt_map);
ensure_equals("LLStringUtil::format: Nastyfmt Test1 result", s, "12345");
ensure_equals("LLStringUtil::format: Nastyfmt Test1 result count", 0, subcount);
// Test substituting a blank string out of a nasty format_map
std::string srcs7;
s = srcs7;
subcount = LLStringUtil::format(s, nasty_fmt_map);
ensure("LLStringUtil::format: Nastyfmt Test2 result", s.empty());
ensure_equals("LLStringUtil::format: Nastyfmt Test2 result count", 0, subcount);
}
}

View File

@@ -0,0 +1,976 @@
/**
* @file lltemplatemessagebuilder_tut.cpp
* @date 2007-04
* @brief Tests for building messages.
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "lltut.h"
#include "llapr.h"
#include "llmessagetemplate.h"
#include "llquaternion.h"
#include "lltemplatemessagebuilder.h"
#include "lltemplatemessagereader.h"
#include "llversionserver.h"
#include "message_prehash.h"
#include "u64.h"
#include "v3dmath.h"
#include "v3math.h"
#include "v4math.h"
namespace tut
{
static LLTemplateMessageBuilder::message_template_name_map_t nameMap;
static LLTemplateMessageReader::message_template_number_map_t numberMap;
struct LLTemplateMessageBuilderTestData
{
static LLMessageTemplate defaultTemplate()
{
static bool init = false;
if(! init)
{
ll_init_apr();
const F32 circuit_heartbeat_interval=5;
const F32 circuit_timeout=100;
start_messaging_system("notafile", 13035,
LL_VERSION_MAJOR,
LL_VERSION_MINOR,
LL_VERSION_PATCH,
FALSE,
"notasharedsecret",
NULL,
false,
circuit_heartbeat_interval,
circuit_timeout);
//init_prehash_data();
init = true;
}
return LLMessageTemplate(_PREHASH_TestMessage, 1, MFT_HIGH);
}
static LLMessageBlock* defaultBlock(const EMsgVariableType type = MVT_NULL, const S32 size = 0, EMsgBlockType block = MBT_VARIABLE)
{
return createBlock(_PREHASH_Test0, type, size, block);
}
static LLMessageBlock* createBlock(char* name, const EMsgVariableType type = MVT_NULL, const S32 size = 0, EMsgBlockType block = MBT_VARIABLE)
{
LLMessageBlock* result = new LLMessageBlock(name, block);
if(type != MVT_NULL)
{
result->addVariable(_PREHASH_Test0, type, size);
}
return result;
}
static LLTemplateMessageBuilder* defaultBuilder(LLMessageTemplate& messageTemplate, char* name = _PREHASH_Test0)
{
nameMap[_PREHASH_TestMessage] = &messageTemplate;
LLTemplateMessageBuilder* builder = new LLTemplateMessageBuilder(nameMap);
builder->newMessage(_PREHASH_TestMessage);
builder->nextBlock(name);
return builder;
}
/** Takes ownership of builder */
static LLTemplateMessageReader* setReader(
LLMessageTemplate& messageTemplate,
LLTemplateMessageBuilder* builder,
U8 offset = 0)
{
numberMap[1] = &messageTemplate;
const U32 bufferSize = 1024;
U8 buffer[bufferSize];
// zero out the packet ID field
memset(buffer, 0, LL_PACKET_ID_SIZE);
U32 builtSize = builder->buildMessage(buffer, bufferSize, offset);
delete builder;
LLTemplateMessageReader* reader = new LLTemplateMessageReader(numberMap);
reader->validateMessage(buffer, builtSize, LLHost());
reader->readMessage(buffer, LLHost());
return reader;
}
};
typedef test_group<LLTemplateMessageBuilderTestData> LLTemplateMessageBuilderTestGroup;
typedef LLTemplateMessageBuilderTestGroup::object LLTemplateMessageBuilderTestObject;
LLTemplateMessageBuilderTestGroup templateMessageBuilderTestGroup("LLTemplateMessageBuilder");
template<> template<>
void LLTemplateMessageBuilderTestObject::test<1>()
// construction and test of undefined
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock());
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<2>()
// BOOL
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_BOOL, 1));
BOOL outValue, inValue = TRUE;
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addBOOL(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
reader->getBOOL(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure BOOL", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<3>()
// U8
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_U8, 1));
U8 outValue, inValue = 2;
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addU8(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
reader->getU8(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure U8", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<4>()
// S16
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_S16, 2));
S16 outValue, inValue = 90;
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addS16(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
reader->getS16(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure S16", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<5>()
// U16
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_U16, 2));
U16 outValue, inValue = 3;
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addU16(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
reader->getU16(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure U16", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<6>()
// S32
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_S32, 4));
S32 outValue, inValue = 44;
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addS32(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
reader->getS32(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure S32", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<7>()
// F32
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_F32, 4));
F32 outValue, inValue = 121.44f;
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addF32(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
reader->getF32(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure F32", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<8>()
// U32
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_U32, 4));
U32 outValue, inValue = 88;
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addU32(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure U32", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<9>()
// U64
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_U64, 8));
U64 outValue, inValue = 121;
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addU64(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
reader->getU64(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure U64", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<10>()
// F64
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_F64, 8));
F64 outValue, inValue = 3232143.33;
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addF64(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
reader->getF64(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure F64", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<11>()
// Vector3
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_LLVector3, 12));
LLVector3 outValue, inValue = LLVector3(1,2,3);
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addVector3(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
reader->getVector3(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure LLVector3", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<12>()
// Vector4
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_LLVector4, 16));
LLVector4 outValue, inValue = LLVector4(1,2,3,4);
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addVector4(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
reader->getVector4(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure LLVector4", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<13>()
// Vector3d
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_LLVector3d, 24));
LLVector3d outValue, inValue = LLVector3d(1,2,3);
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addVector3d(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
reader->getVector3d(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure LLVector3d", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<14>()
// Quaternion
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_LLQuaternion, 12));
LLQuaternion outValue, inValue = LLQuaternion(1,2,3,0);
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addQuat(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
reader->getQuat(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure LLQuaternion", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<15>()
// UUID
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_LLUUID, 16));
LLUUID outValue, inValue;
inValue.generate();
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addUUID(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
reader->getUUID(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure UUID", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<16>()
// IPAddr
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_IP_ADDR, 4));
U32 outValue, inValue = 12344556;
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addIPAddr(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
reader->getIPAddr(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure IPAddr", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<17>()
// IPPort
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_IP_PORT, 2));
U16 outValue, inValue = 80;
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addIPPort(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
reader->getIPPort(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure IPPort", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<18>()
// String
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_VARIABLE, 1));
std::string outValue, inValue = "testing";
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addString(_PREHASH_Test0, inValue.c_str());
LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
char buffer[MAX_STRING];
reader->getString(_PREHASH_Test0, _PREHASH_Test0, MAX_STRING, buffer);
outValue = buffer;
ensure_equals("Ensure String", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<19>()
// block name !-> binary order
{
U8 buffer1[MAX_BUFFER_SIZE];
memset(buffer1, 0, MAX_BUFFER_SIZE);
U8 buffer2[MAX_BUFFER_SIZE];
memset(buffer2, 0, MAX_BUFFER_SIZE);
U32 bufferSize1, bufferSize2;
// build template: Test0 before Test1
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(createBlock(_PREHASH_Test0, MVT_U32, 4, MBT_SINGLE));
messageTemplate.addBlock(createBlock(_PREHASH_Test1, MVT_U32, 4, MBT_SINGLE));
// build message: 1st declared block var == 0xaaaa, 2nd declared block var == 0xbbbb
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate, _PREHASH_Test0);
builder->addU32(_PREHASH_Test0, 0xaaaa);
builder->nextBlock(_PREHASH_Test1);
builder->addU32(_PREHASH_Test0, 0xbbbb);
bufferSize1 = builder->buildMessage(buffer1, MAX_BUFFER_SIZE, 0);
delete builder;
// build template: Test1 before Test0
messageTemplate = defaultTemplate();
messageTemplate.addBlock(createBlock(_PREHASH_Test1, MVT_U32, 4, MBT_SINGLE));
messageTemplate.addBlock(createBlock(_PREHASH_Test0, MVT_U32, 4, MBT_SINGLE));
// build message: 1st declared block var == 0xaaaa, 2nd declared block var == 0xbbbb
builder = defaultBuilder(messageTemplate, _PREHASH_Test1);
builder->addU32(_PREHASH_Test0, 0xaaaa);
builder->nextBlock(_PREHASH_Test0);
builder->addU32(_PREHASH_Test0, 0xbbbb);
bufferSize2 = builder->buildMessage(buffer2, MAX_BUFFER_SIZE, 0);
delete builder;
ensure_equals("Ensure Buffer Sizes Equal", bufferSize1, bufferSize2);
ensure_equals("Ensure Buffer Contents Equal", memcmp(buffer1, buffer2, bufferSize1), 0);
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<20>()
// block build order !-> binary order
{
U8 buffer1[MAX_BUFFER_SIZE];
memset(buffer1, 0, MAX_BUFFER_SIZE);
U8 buffer2[MAX_BUFFER_SIZE];
memset(buffer2, 0, MAX_BUFFER_SIZE);
U32 bufferSize1, bufferSize2;
// build template: Test0 before Test1
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(createBlock(_PREHASH_Test0, MVT_U32, 4, MBT_SINGLE));
messageTemplate.addBlock(createBlock(_PREHASH_Test1, MVT_U32, 4, MBT_SINGLE));
// build message: 1st declared block var == 0xaaaa, 2nd declared block var == 0xbbbb
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate, _PREHASH_Test0);
builder->addU32(_PREHASH_Test0, 0xaaaa);
builder->nextBlock(_PREHASH_Test1);
builder->addU32(_PREHASH_Test0, 0xbbbb);
bufferSize1 = builder->buildMessage(buffer1, MAX_BUFFER_SIZE, 0);
delete builder;
// build message: 1st declared block var == 0xaaaa, 2nd declared block var == 0xbbbb
builder = defaultBuilder(messageTemplate, _PREHASH_Test1);
builder->addU32(_PREHASH_Test0, 0xbbbb);
builder->nextBlock(_PREHASH_Test0);
builder->addU32(_PREHASH_Test0, 0xaaaa);
bufferSize2 = builder->buildMessage(buffer2, MAX_BUFFER_SIZE, 0);
delete builder;
ensure_equals("Ensure Buffer Sizes Equal", bufferSize1, bufferSize2);
ensure_equals("Ensure Buffer Contents Equal", memcmp(buffer1, buffer2, bufferSize1), 0);
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<21>()
// block appended in declaration -> data appended in binary
{
U8 buffer1[MAX_BUFFER_SIZE];
memset(buffer1, 0, MAX_BUFFER_SIZE);
U8 buffer2[MAX_BUFFER_SIZE];
memset(buffer2, 0, MAX_BUFFER_SIZE);
U32 bufferSize1, bufferSize2;
// Build template: Test0 only
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(createBlock(_PREHASH_Test0, MVT_U32, 4, MBT_SINGLE));
// Build message
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate, _PREHASH_Test0);
builder->addU32(_PREHASH_Test0, 0xaaaa);
bufferSize1 = builder->buildMessage(buffer1, MAX_BUFFER_SIZE, 0);
delete builder;
// Build template: Test0 before Test1
messageTemplate = defaultTemplate();
messageTemplate.addBlock(createBlock(_PREHASH_Test0, MVT_U32, 4, MBT_SINGLE));
messageTemplate.addBlock(createBlock(_PREHASH_Test1, MVT_U32, 4, MBT_SINGLE));
// Build message
builder = defaultBuilder(messageTemplate, _PREHASH_Test0);
builder->addU32(_PREHASH_Test0, 0xaaaa);
builder->nextBlock(_PREHASH_Test1);
builder->addU32(_PREHASH_Test0, 0xbbbb);
bufferSize2 = builder->buildMessage(buffer2, MAX_BUFFER_SIZE, 0);
delete builder;
ensure_not_equals("Ensure Buffer Sizes Not Equal", bufferSize1, bufferSize2);
ensure_equals("Ensure Buffer Prefix Equal", memcmp(buffer1, buffer2, bufferSize1), 0);
ensure_not_equals("Ensure Buffer Contents Not Equal", memcmp(buffer1, buffer2, bufferSize2), 0);
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<22>()
// repeated penultimate block (crashes when data in LLDynamicArrayIndexed)
{
U32 inTest00 = 0, inTest01 = 1, inTest1 = 2;
U32 outTest00, outTest01, outTest1;
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(createBlock(_PREHASH_Test0, MVT_U32, 4));
messageTemplate.addBlock(createBlock(_PREHASH_Test1, MVT_U32, 4));
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addU32(_PREHASH_Test0, inTest00);
builder->nextBlock(_PREHASH_Test0);
builder->addU32(_PREHASH_Test0, inTest01);
builder->nextBlock(_PREHASH_Test1);
builder->addU32(_PREHASH_Test0, inTest1);
LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outTest00, 0);
reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outTest01, 1);
reader->getU32(_PREHASH_Test1, _PREHASH_Test0, outTest1);
ensure_equals("Ensure Test0[0]", inTest00, outTest00);
ensure_equals("Ensure Test0[1]", inTest01, outTest01);
ensure_equals("Ensure Test1", inTest1, outTest1);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<23>()
// variable repeated block name never accessed
{
U32 inTest = 1, outTest;
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(
createBlock(_PREHASH_Test0, MVT_U32, 4, MBT_SINGLE));
messageTemplate.addBlock(createBlock(_PREHASH_Test1, MVT_U32, 4));
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addU32(_PREHASH_Test0, inTest);
LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outTest);
S32 blockCount = reader->getNumberOfBlocks(_PREHASH_Test1);
ensure_equals("Ensure block count", blockCount, 0);
ensure_equals("Ensure Test0", inTest, outTest);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<24>()
// forwarding message
{
// build template
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(createBlock(_PREHASH_Test0, MVT_U32, 4));
// build message
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addU32(_PREHASH_Test0, 42);
// read message
LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
// forward message
builder = defaultBuilder(messageTemplate);
builder->newMessage(_PREHASH_TestMessage);
reader->copyToBuilder(*builder);
U8 buffer[MAX_BUFFER_SIZE];
builder->buildMessage(buffer, MAX_BUFFER_SIZE, 0);
delete builder;
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<25>()
// non-zero offset with undefined
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock());
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
LLTemplateMessageReader* reader = setReader(
messageTemplate, builder, 10);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<26>()
// non-zero offset with BOOL
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_BOOL, 1));
BOOL outValue, inValue = TRUE;
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addBOOL(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(
messageTemplate, builder, 1);
reader->getBOOL(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure BOOL", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<27>()
// non-zero offset with U8
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_U8, 1));
U8 outValue, inValue = 2;
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addU8(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(
messageTemplate, builder, 255);
reader->getU8(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure U8", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<28>()
// non-zero offset with S16
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_S16, 2));
S16 outValue, inValue = 90;
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addS16(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(
messageTemplate, builder, 2);
reader->getS16(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure S16", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<29>()
// non-zero offset with U16
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_U16, 2));
U16 outValue, inValue = 3;
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addU16(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(
messageTemplate, builder, 4);
reader->getU16(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure U16", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<30>()
// non-zero offset with S32
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_S32, 4));
S32 outValue, inValue = 44;
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addS32(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(
messageTemplate, builder, 4);
reader->getS32(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure S32", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<31>()
// non-zero offset with F32
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_F32, 4));
F32 outValue, inValue = 121.44f;
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addF32(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(
messageTemplate, builder, 16);
reader->getF32(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure F32", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<32>()
// non-zero offset with U32
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_U32, 4));
U32 outValue, inValue = 88;
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addU32(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(
messageTemplate, builder, 127);
reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure U32", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<33>()
// non-zero offset with U64
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_U64, 8));
U64 outValue, inValue = 121;
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addU64(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(
messageTemplate, builder, 32);
reader->getU64(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure U64", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<34>()
// non-zero offset with F64
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_F64, 8));
F64 outValue, inValue = 3232143.33;
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addF64(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(
messageTemplate, builder, 128);
reader->getF64(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure F64", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<35>()
// non-zero offset with Vector3
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_LLVector3, 12));
LLVector3 outValue, inValue = LLVector3(1,2,3);
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addVector3(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(
messageTemplate, builder, 63);
reader->getVector3(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure LLVector3", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<36>()
// non-zero offset with Vector4
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_LLVector4, 16));
LLVector4 outValue, inValue = LLVector4(1,2,3,4);
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addVector4(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(
messageTemplate, builder, 64);
reader->getVector4(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure LLVector4", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<37>()
// non-zero offset with Vector3d
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_LLVector3d, 24));
LLVector3d outValue, inValue = LLVector3d(1,2,3);
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addVector3d(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(
messageTemplate, builder, 64);
reader->getVector3d(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure LLVector3d", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<38>()
// non-zero offset with Quaternion
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_LLQuaternion, 12));
LLQuaternion outValue, inValue = LLQuaternion(1,2,3,0);
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addQuat(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(
messageTemplate, builder, 12);
reader->getQuat(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure LLQuaternion", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<39>()
// non-zero offset with UUID
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_LLUUID, 16));
LLUUID outValue, inValue;
inValue.generate();
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addUUID(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(
messageTemplate, builder, 31);
reader->getUUID(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure UUID", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<40>()
// non-zero offset with IPAddr
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_IP_ADDR, 4));
U32 outValue, inValue = 12344556;
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addIPAddr(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(
messageTemplate, builder, 32);
reader->getIPAddr(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure IPAddr", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<41>()
// non-zero offset with IPPort
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_IP_PORT, 2));
U16 outValue, inValue = 80;
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addIPPort(_PREHASH_Test0, inValue);
LLTemplateMessageReader* reader = setReader(
messageTemplate, builder, 6);
reader->getIPPort(_PREHASH_Test0, _PREHASH_Test0, outValue);
ensure_equals("Ensure IPPort", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<42>()
// non-zero offset with String
{
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_VARIABLE, 1));
std::string outValue, inValue = "testing";
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addString(_PREHASH_Test0, inValue.c_str());
LLTemplateMessageReader* reader = setReader(
messageTemplate, builder, 255);
char buffer[MAX_STRING];
reader->getString(_PREHASH_Test0, _PREHASH_Test0, MAX_STRING, buffer);
outValue = buffer;
ensure_equals("Ensure String", inValue, outValue);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<43>()
// read past end of message -> default values (forward compatibility)
{
// build message with single block
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_U32, 4, MBT_SINGLE));
U32 outValue, outValue2, inValue = 0xbbbbbbbb;
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addU32(_PREHASH_Test0, inValue);
const U32 bufferSize = 1024;
U8 buffer[bufferSize];
memset(buffer, 0xaa, bufferSize);
memset(buffer, 0, LL_PACKET_ID_SIZE);
U32 builtSize = builder->buildMessage(buffer, bufferSize, 0);
delete builder;
// add block to reader template
messageTemplate.addBlock(createBlock(_PREHASH_Test1, MVT_U32, 4, MBT_SINGLE));
// read message value and default value
numberMap[1] = &messageTemplate;
LLTemplateMessageReader* reader =
new LLTemplateMessageReader(numberMap);
reader->validateMessage(buffer, builtSize, LLHost());
reader->readMessage(buffer, LLHost());
reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outValue);
reader->getU32(_PREHASH_Test1, _PREHASH_Test0, outValue2);
ensure_equals("Ensure present value ", outValue, inValue);
ensure_equals("Ensure default value ", outValue2, 0);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<44>()
// read variable block past end of message -> 0 repeats
{
// build message with single block
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_U32, 4, MBT_SINGLE));
U32 outValue, outValue2, inValue = 0xbbbbbbbb;
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addU32(_PREHASH_Test0, inValue);
const U32 bufferSize = 1024;
U8 buffer[bufferSize];
memset(buffer, 0xaa, bufferSize);
memset(buffer, 0, LL_PACKET_ID_SIZE);
U32 builtSize = builder->buildMessage(buffer, bufferSize, 0);
delete builder;
// add variable block to reader template
messageTemplate.addBlock(createBlock(_PREHASH_Test1, MVT_U32, 4));
// read message value and check block repeat count
numberMap[1] = &messageTemplate;
LLTemplateMessageReader* reader =
new LLTemplateMessageReader(numberMap);
reader->validateMessage(buffer, builtSize, LLHost());
reader->readMessage(buffer, LLHost());
reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outValue);
outValue2 = reader->getNumberOfBlocks(_PREHASH_Test1);
ensure_equals("Ensure present value ", outValue, inValue);
ensure_equals("Ensure 0 repeats ", outValue2, 0);
delete reader;
}
template<> template<>
void LLTemplateMessageBuilderTestObject::test<45>()
// read variable length data past end of message -> 0 length
{
// build message with single block
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_U32, 4, MBT_SINGLE));
U32 outValue, outValue2, inValue = 0xbbbbbbbb;
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addU32(_PREHASH_Test0, inValue);
const U32 bufferSize = 1024;
U8 buffer[bufferSize];
memset(buffer, 0xaa, bufferSize);
memset(buffer, 0, LL_PACKET_ID_SIZE);
U32 builtSize = builder->buildMessage(buffer, bufferSize, 0);
delete builder;
// add variable block to reader template
messageTemplate.addBlock(createBlock(_PREHASH_Test1, MVT_VARIABLE, 4,
MBT_SINGLE));
// read message value and default string
numberMap[1] = &messageTemplate;
LLTemplateMessageReader* reader =
new LLTemplateMessageReader(numberMap);
reader->validateMessage(buffer, builtSize, LLHost());
reader->readMessage(buffer, LLHost());
reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outValue);
char outBuffer[bufferSize];
memset(buffer, 0xcc, bufferSize);
reader->getString(_PREHASH_Test1, _PREHASH_Test0, bufferSize,
outBuffer);
outValue2 = reader->getNumberOfBlocks(_PREHASH_Test1);
ensure_equals("Ensure present value ", outValue, inValue);
ensure_equals("Ensure unchanged buffer ", strlen(outBuffer), 0);
delete reader;
}
}

View File

@@ -0,0 +1,130 @@
/**
* @file lltimestampcache_tut.cpp
* @author James Tess
* @date 2008-12-03
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
* Copyright (c) 2008-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "../mapserver/lltimestampcache.h"
#include "lltut.h"
namespace tut
{
struct LLTimestampCacheTestData
{
};
typedef test_group<LLTimestampCacheTestData> LLTimestampCacheTestGroup;
typedef LLTimestampCacheTestGroup::object LLTimestampCacheTestObject;
LLTimestampCacheTestGroup timestampCacheTestGroup("LLTimestampCache");
// Most common usage
template<> template<>
void LLTimestampCacheTestObject::test<1>()
{
LLTimestampCache<std::string, std::string> cache;
// put in some data
cache.insert("key1", "val1", 1);
cache.insert("key2", "val2", 2);
cache.insert("key3", "val3", 3);
ensure_equals("size is 3", cache.size(), 3);
// check some items
ensure("has key1", cache.has("key1"));
ensure("no invalid key", !cache.has("invalid key"));
// get some items
ensure_equals("get key1", cache.get("key1", 4), "val1");
ensure_equals("get invalid key",
cache.get("invalid key", 4), std::string() );
// timestamps
ensure_equals("key1 timestamp updated", cache.getTimestamp("key1"), 4);
ensure_equals("invalid key timestamp",
cache.getTimestamp("invalid key"), 0);
}
// New empty cache shouldn't have any entries
template<> template<>
void LLTimestampCacheTestObject::test<2>()
{
LLTimestampCache<std::string, std::string> cache;
ensure_equals("starts empty", cache.size(), 0);
ensure_equals("has nothing", cache.has("foo"), false);
ensure_equals("gets nothing", cache.get("foo", 0), std::string() );
U32 max_time = 0xFFFFFFFF;
ensure_equals("erases nothing", cache.eraseBefore(max_time), 0);
}
// Non empty cache
template<> template<>
void LLTimestampCacheTestObject::test<3>()
{
LLTimestampCache<std::string, std::string> cache;
cache.insert("foo", "bar", 123);
ensure_equals("size one", cache.size(), 1);
ensure_equals("has it", cache.has("foo"), true);
ensure_equals("timestamp correct", cache.getTimestamp("foo"), 123);
std::string value = cache.get("foo", 456);
ensure_equals("get value", value, "bar");
ensure_equals("timestamp updated", cache.getTimestamp("foo"), 456);
ensure_equals("erase nothing", cache.eraseBefore(0), 0);
ensure_equals("erase one", cache.eraseBefore(789), 1);
ensure_equals("empty after erase", cache.size(), 0);
}
// Recache of item should update timestamp
template<> template<>
void LLTimestampCacheTestObject::test<4>()
{
LLTimestampCache<std::string, std::string> cache;
cache.insert("foo", "bar", 123);
cache.insert("foo", "bar", 456);
ensure_equals("duplicate suppressed", cache.size(), 1);
ensure_equals("timestamp replaced", cache.getTimestamp("foo"), 456);
}
// Erasing some items
template<> template<>
void LLTimestampCacheTestObject::test<5>()
{
LLTimestampCache<std::string, std::string> cache;
cache.insert("key1", "val1", 1);
cache.insert("key2", "val2", 2);
cache.insert("key3", "val3", 3);
cache.insert("key4", "val4", 4);
size_t erased = cache.eraseBefore(3);
ensure_equals("erase range", erased, 2);
ensure_equals("cache post erase", cache.size(), 2);
ensure_equals("has key3", cache.has("key3"), true);
ensure_equals("not has key2", cache.has("key2"), false);
}
}

117
indra/test/lltiming_tut.cpp Normal file
View File

@@ -0,0 +1,117 @@
/**
* @file lltiming_tut.cpp
* @date 2006-07-23
* @brief Tests the timers.
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "lltut.h"
#include "llframetimer.h"
#include "llsd.h"
namespace tut
{
struct frametimer_test
{
frametimer_test()
{
LLFrameTimer::updateFrameTime();
}
};
typedef test_group<frametimer_test> frametimer_group_t;
typedef frametimer_group_t::object frametimer_object_t;
tut::frametimer_group_t frametimer_instance("frametimer");
template<> template<>
void frametimer_object_t::test<1>()
{
F64 seconds_since_epoch = LLFrameTimer::getTotalSeconds();
LLFrameTimer timer;
timer.setExpiryAt(seconds_since_epoch);
F64 expires_at = timer.expiresAt();
ensure_distance(
"set expiry matches get expiry",
expires_at,
seconds_since_epoch,
0.001);
}
template<> template<>
void frametimer_object_t::test<2>()
{
F64 seconds_since_epoch = LLFrameTimer::getTotalSeconds();
seconds_since_epoch += 10.0;
LLFrameTimer timer;
timer.setExpiryAt(seconds_since_epoch);
F64 expires_at = timer.expiresAt();
ensure_distance(
"set expiry matches get expiry 1",
expires_at,
seconds_since_epoch,
0.001);
seconds_since_epoch += 10.0;
timer.setExpiryAt(seconds_since_epoch);
expires_at = timer.expiresAt();
ensure_distance(
"set expiry matches get expiry 2",
expires_at,
seconds_since_epoch,
0.001);
}
template<> template<>
void frametimer_object_t::test<3>()
{
F64 seconds_since_epoch = LLFrameTimer::getTotalSeconds();
seconds_since_epoch += 2.0;
LLFrameTimer timer;
timer.setExpiryAt(seconds_since_epoch);
ensure("timer not expired on create", !timer.hasExpired());
int ii;
for(ii = 0; ii < 10; ++ii)
{
ms_sleep(150);
LLFrameTimer::updateFrameTime();
}
ensure("timer not expired after a bit", !timer.hasExpired());
for(ii = 0; ii < 10; ++ii)
{
ms_sleep(100);
LLFrameTimer::updateFrameTime();
}
ensure("timer expired", timer.hasExpired());
}
/*
template<> template<>
void frametimer_object_t::test<4>()
{
}
*/
}

View File

@@ -0,0 +1,95 @@
/**
* @file llscriptresource_tut.cpp
* @brief Test LLScriptResource
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
* Copyright (c) 2008-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
//#include <tut/tut.h>
#include "linden_common.h"
#include "lltut.h"
#include "../newsim/lltranscode.cpp" // include TU to pull in newsim implementation.
static const char test_utf8[] = "Edelwei\xc3\x9f";
static const char test_utf7[] = "Edelwei+AN8-";
static const char test_latin1[] = "Edelwei\xdf";
static const char test_latin2[] = "Edelwei\xdf";
namespace tut
{
class LLTranscodeTestData
{
};
typedef test_group<LLTranscodeTestData> LLTranscodeTestGroup;
typedef LLTranscodeTestGroup::object LLTranscodeTestObject;
LLTranscodeTestGroup transcodeTestGroup("transcode");
template<> template<>
void LLTranscodeTestObject::test<1>()
{
#if LL_WINDOWS
skip("Windows APR libs can't transcode.");
#endif
// Test utf8
std::stringstream input;
std::stringstream output;
input.str(test_utf7);
output.clear();
LLTranscode::transcode("charset=UTF-7", input, output);
ensure_equals("UTF-7 to UTF-8 transcoding", output.str(),
std::string(test_utf8));
input.str(test_latin1);
output.clear();
LLTranscode::transcode("", input, output);
ensure_equals("Default (latin_1) to UTF8 transcoding", output.str(),
std::string(test_utf8));
input.str(test_latin1);
output.clear();
LLTranscode::transcode("charset=iso-8859-1", input, output);
ensure_equals("latin_1 (ISO-8859-1) to UTF8 transcoding", output.str(),
std::string(test_utf8));
input.str(test_latin2);
output.clear();
LLTranscode::transcode("charset=iso-8859-2", input, output);
ensure_equals("latin_2 (ISO-8859-2) to UTF8 transcoding", output.str(),
std::string(test_utf8));
input.str(test_utf8);
output.clear();
LLTranscode::transcode("charset=utf-8", input, output);
ensure_equals("UTF8 to UTF8 transcoding", output.str(),
std::string(test_utf8));
}
}

202
indra/test/lltut.cpp Normal file
View File

@@ -0,0 +1,202 @@
/**
* @file lltut.cpp
* @author Mark Lentczner
* @date 5/16/06
* @brief MacTester
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "lltut.h"
#include "lldate.h"
#include "llformat.h"
#include "llsd.h"
#include "lluri.h"
namespace tut
{
void ensure_equals(const char* msg, const LLDate& actual,
const LLDate& expected)
{
ensure_equals(msg,
actual.secondsSinceEpoch(), expected.secondsSinceEpoch());
}
void ensure_equals(const char* msg, const LLURI& actual,
const LLURI& expected)
{
ensure_equals(msg,
actual.asString(), expected.asString());
}
void ensure_equals(const char* msg,
const std::vector<U8>& actual, const std::vector<U8>& expected)
{
std::string s(msg);
ensure_equals(s + " size", actual.size(), expected.size());
std::vector<U8>::const_iterator i, j;
int k;
for (i = actual.begin(), j = expected.begin(), k = 0;
i != actual.end();
++i, ++j, ++k)
{
ensure_equals(s + " field", *i, *j);
}
}
void ensure_equals(const char* m, const LLSD& actual,
const LLSD& expected)
{
const std::string& msg = m ? m : "";
ensure_equals(msg + " type", actual.type(), expected.type());
switch (actual.type())
{
case LLSD::TypeUndefined:
return;
case LLSD::TypeBoolean:
ensure_equals(msg + " boolean", actual.asBoolean(), expected.asBoolean());
return;
case LLSD::TypeInteger:
ensure_equals(msg + " integer", actual.asInteger(), expected.asInteger());
return;
case LLSD::TypeReal:
ensure_equals(msg + " real", actual.asReal(), expected.asReal());
return;
case LLSD::TypeString:
ensure_equals(msg + " string", actual.asString(), expected.asString());
return;
case LLSD::TypeUUID:
ensure_equals(msg + " uuid", actual.asUUID(), expected.asUUID());
return;
case LLSD::TypeDate:
ensure_equals(msg + " date", actual.asDate(), expected.asDate());
return;
case LLSD::TypeURI:
ensure_equals(msg + " uri", actual.asURI(), expected.asURI());
return;
case LLSD::TypeBinary:
ensure_equals(msg + " binary", actual.asBinary(), expected.asBinary());
return;
case LLSD::TypeMap:
{
ensure_equals(msg + " map size", actual.size(), expected.size());
LLSD::map_const_iterator actual_iter = actual.beginMap();
LLSD::map_const_iterator expected_iter = expected.beginMap();
while(actual_iter != actual.endMap())
{
ensure_equals(msg + " map keys",
actual_iter->first, expected_iter->first);
ensure_equals((msg + "[" + actual_iter->first + "]").c_str(),
actual_iter->second, expected_iter->second);
++actual_iter;
++expected_iter;
}
return;
}
case LLSD::TypeArray:
{
ensure_equals(msg + " array size", actual.size(), expected.size());
for(int i = 0; i < actual.size(); ++i)
{
ensure_equals((msg + llformat("[%d]", i)).c_str(),
actual[i], expected[i]);
}
return;
}
}
}
void ensure_starts_with(const std::string& msg,
const std::string& actual, const std::string& expectedStart)
{
if( actual.find(expectedStart, 0) != 0 )
{
std::stringstream ss;
ss << msg << ": " << "expected to find " << expectedStart
<< " at start of actual " << actual;
throw failure(ss.str().c_str());
}
}
void ensure_ends_with(const std::string& msg,
const std::string& actual, const std::string& expectedEnd)
{
if( actual.size() < expectedEnd.size()
|| actual.rfind(expectedEnd)
!= (actual.size() - expectedEnd.size()) )
{
std::stringstream ss;
ss << msg << ": " << "expected to find " << expectedEnd
<< " at end of actual " << actual;
throw failure(ss.str().c_str());
}
}
void ensure_contains(const std::string& msg,
const std::string& actual, const std::string& expectedSubString)
{
if( actual.find(expectedSubString, 0) == std::string::npos )
{
std::stringstream ss;
ss << msg << ": " << "expected to find " << expectedSubString
<< " in actual " << actual;
throw failure(ss.str().c_str());
}
}
void ensure_does_not_contain(const std::string& msg,
const std::string& actual, const std::string& expectedSubString)
{
if( actual.find(expectedSubString, 0) != std::string::npos )
{
std::stringstream ss;
ss << msg << ": " << "expected not to find " << expectedSubString
<< " in actual " << actual;
throw failure(ss.str().c_str());
}
}
}

139
indra/test/lltut.h Normal file
View File

@@ -0,0 +1,139 @@
/**
* @file lltut.h
* @author Phoenix
* @date 2005-09-26
* @brief helper tut methods
*
* $LicenseInfo:firstyear=2005&license=viewergpl$
*
* Copyright (c) 2005-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLTUT_H
#define LL_LLTUT_H
#include "is_approx_equal_fraction.h" // instead of llmath.h
#include <tut/tut.hpp>
#include <cstring>
class LLDate;
class LLSD;
class LLURI;
namespace tut
{
inline void ensure_approximately_equals(const char* msg, F64 actual, F64 expected, U32 frac_bits)
{
if(!is_approx_equal_fraction(actual, expected, frac_bits))
{
std::stringstream ss;
ss << (msg?msg:"") << (msg?": ":"") << "not equal actual: " << actual << " expected: " << expected;
throw tut::failure(ss.str().c_str());
}
}
inline void ensure_approximately_equals(const char* msg, F32 actual, F32 expected, U32 frac_bits)
{
if(!is_approx_equal_fraction(actual, expected, frac_bits))
{
std::stringstream ss;
ss << (msg?msg:"") << (msg?": ":"") << "not equal actual: " << actual << " expected: " << expected;
throw tut::failure(ss.str().c_str());
}
}
inline void ensure_approximately_equals(F32 actual, F32 expected, U32 frac_bits)
{
ensure_approximately_equals(NULL, actual, expected, frac_bits);
}
inline void ensure_memory_matches(const char* msg,const void* actual, U32 actual_len, const void* expected,U32 expected_len)
{
if((expected_len != actual_len) ||
(memcmp(actual, expected, actual_len) != 0))
{
std::stringstream ss;
ss << (msg?msg:"") << (msg?": ":"") << "not equal";
throw tut::failure(ss.str().c_str());
}
}
inline void ensure_memory_matches(const void* actual, U32 actual_len, const void* expected,U32 expected_len)
{
ensure_memory_matches(NULL, actual, actual_len, expected, expected_len);
}
template <class T,class Q>
void ensure_not_equals(const char* msg,const Q& actual,const T& expected)
{
if( expected == actual )
{
std::stringstream ss;
ss << (msg?msg:"") << (msg?": ":"") << "both equal " << expected;
throw tut::failure(ss.str().c_str());
}
}
template <class T,class Q>
void ensure_not_equals(const Q& actual,const T& expected)
{
ensure_not_equals(NULL, actual, expected);
}
template <class T,class Q>
void ensure_equals(const std::string& msg,
const Q& actual,const T& expected)
{ ensure_equals(msg.c_str(), actual, expected); }
void ensure_equals(const char* msg,
const LLDate& actual, const LLDate& expected);
void ensure_equals(const char* msg,
const LLURI& actual, const LLURI& expected);
void ensure_equals(const char* msg,
const std::vector<U8>& actual, const std::vector<U8>& expected);
void ensure_equals(const char* msg,
const LLSD& actual, const LLSD& expected);
void ensure_starts_with(const std::string& msg,
const std::string& actual, const std::string& expectedStart);
void ensure_ends_with(const std::string& msg,
const std::string& actual, const std::string& expectedEnd);
void ensure_contains(const std::string& msg,
const std::string& actual, const std::string& expectedSubString);
void ensure_does_not_contain(const std::string& msg,
const std::string& actual, const std::string& expectedSubString);
}
#endif // LL_LLTUT_H

367
indra/test/lluri_tut.cpp Normal file
View File

@@ -0,0 +1,367 @@
/**
* @file lluri_tut.cpp
* @brief LLURI unit tests
* @date September 2006
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "lltut.h"
#include "llsd.h"
#include "lluri.h"
#include "llhost.h"
namespace tut
{
struct URITestData {
void checkParts(const LLURI& u,
const char* expectedScheme,
const char* expectedOpaque,
const char* expectedAuthority,
const char* expectedPath,
const char* expectedQuery = "")
{
ensure_equals("scheme", u.scheme(), expectedScheme);
ensure_equals("opaque", u.opaque(), expectedOpaque);
ensure_equals("authority", u.authority(), expectedAuthority);
ensure_equals("path", u.path(), expectedPath);
ensure_equals("query", u.query(), expectedQuery);
}
void escapeRoundTrip(const std::string& uri_raw_1)
{
std::string uri_esc_1(LLURI::escape(uri_raw_1));
std::string uri_raw_2(LLURI::unescape(uri_esc_1));
ensure_equals("escape/unescape raw", uri_raw_2, uri_raw_1);
std::string uri_esc_2(LLURI::escape(uri_raw_2));
ensure_equals("escape/unescape escaped", uri_esc_2, uri_esc_1);
}
};
typedef test_group<URITestData> URITestGroup;
typedef URITestGroup::object URITestObject;
URITestGroup uriTestGroup("LLURI");
template<> template<>
void URITestObject::test<1>()
{
LLURI u("http://abc.com/def/ghi?x=37&y=hello");
ensure_equals("scheme", u.scheme(), "http");
ensure_equals("authority", u.authority(), "abc.com");
ensure_equals("path", u.path(), "/def/ghi");
ensure_equals("query", u.query(), "x=37&y=hello");
ensure_equals("host name", u.hostName(), "abc.com");
ensure_equals("host port", u.hostPort(), 80);
LLSD query = u.queryMap();
ensure_equals("query x", query["x"].asInteger(), 37);
ensure_equals("query y", query["y"].asString(), "hello");
query = LLURI::queryMap("x=22.23&y=https://lindenlab.com/");
ensure_equals("query x", query["x"].asReal(), 22.23);
ensure_equals("query y", query["y"].asURI().asString(), "https://lindenlab.com/");
}
template<> template<>
void URITestObject::test<2>()
{
// empty string
checkParts(LLURI(""), "", "", "", "");
}
template<> template<>
void URITestObject::test<3>()
{
// no scheme
checkParts(LLURI("foo"), "", "foo", "", "");
checkParts(LLURI("foo%3A"), "", "foo:", "", "");
}
template<> template<>
void URITestObject::test<4>()
{
// scheme w/o paths
checkParts(LLURI("mailto:zero@ll.com"),
"mailto", "zero@ll.com", "", "");
checkParts(LLURI("silly://abc/def?foo"),
"silly", "//abc/def?foo", "", "");
}
template<> template<>
void URITestObject::test<5>()
{
// authority section
checkParts(LLURI("http:///"),
"http", "///", "", "/");
checkParts(LLURI("http://abc"),
"http", "//abc", "abc", "");
checkParts(LLURI("http://a%2Fb/cd"),
"http", "//a/b/cd", "a/b", "/cd");
checkParts(LLURI("http://host?"),
"http", "//host?", "host", "");
}
template<> template<>
void URITestObject::test<6>()
{
// path section
checkParts(LLURI("http://host/a/b/"),
"http", "//host/a/b/", "host", "/a/b/");
checkParts(LLURI("http://host/a%3Fb/"),
"http", "//host/a?b/", "host", "/a?b/");
checkParts(LLURI("http://host/a:b/"),
"http", "//host/a:b/", "host", "/a:b/");
}
template<> template<>
void URITestObject::test<7>()
{
// query string
checkParts(LLURI("http://host/?"),
"http", "//host/?", "host", "/", "");
checkParts(LLURI("http://host/?x"),
"http", "//host/?x", "host", "/", "x");
checkParts(LLURI("http://host/??"),
"http", "//host/??", "host", "/", "?");
checkParts(LLURI("http://host/?%3F"),
"http", "//host/??", "host", "/", "?");
}
template<> template<>
void URITestObject::test<8>()
{
LLSD path;
path.append("x");
path.append("123");
checkParts(LLURI::buildHTTP("host", path),
"http", "//host/x/123", "host", "/x/123");
LLSD query;
query["123"] = "12";
query["abcd"] = "abc";
checkParts(LLURI::buildHTTP("host", path, query),
"http", "//host/x/123?123=12&abcd=abc",
"host", "/x/123", "123=12&abcd=abc");
}
template<> template<>
void URITestObject::test<9>()
{
// test unescaped path components
LLSD path;
path.append("x@*//*$&^");
path.append("123");
checkParts(LLURI::buildHTTP("host", path),
"http", "//host/x@*//*$&^/123", "host", "/x@*//*$&^/123");
}
template<> template<>
void URITestObject::test<10>()
{
// test unescaped query components
LLSD path;
path.append("x");
path.append("123");
LLSD query;
query["123"] = "?&*#//";
query["**@&?//"] = "abc";
checkParts(LLURI::buildHTTP("host", path, query),
"http", "//host/x/123?**@&?//=abc&123=?&*#//",
"host", "/x/123", "**@&?//=abc&123=?&*#//");
}
template<> template<>
void URITestObject::test<11>()
{
// test unescaped host components
LLSD path;
path.append("x");
path.append("123");
LLSD query;
query["123"] = "12";
query["abcd"] = "abc";
checkParts(LLURI::buildHTTP("hi123*33--}{:portstuffs", path, query),
"http", "//hi123*33--}{:portstuffs/x/123?123=12&abcd=abc",
"hi123*33--}{:portstuffs", "/x/123", "123=12&abcd=abc");
}
template<> template<>
void URITestObject::test<12>()
{
// test funky host_port values that are actually prefixes
checkParts(LLURI::buildHTTP("http://example.com:8080", LLSD()),
"http", "//example.com:8080",
"example.com:8080", "");
checkParts(LLURI::buildHTTP("http://example.com:8080/", LLSD()),
"http", "//example.com:8080/",
"example.com:8080", "/");
checkParts(LLURI::buildHTTP("http://example.com:8080/a/b", LLSD()),
"http", "//example.com:8080/a/b",
"example.com:8080", "/a/b");
}
template<> template<>
void URITestObject::test<13>()
{
const std::string unreserved =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
"0123456789"
"-._~";
// test escape
ensure_equals("escaping", LLURI::escape("abcdefg", "abcdef"), "abcdef%67");
ensure_equals("escaping", LLURI::escape("|/&\\+-_!@", ""), "%7C%2F%26%5C%2B%2D%5F%21%40");
ensure_equals("escaping as query variable",
LLURI::escape("http://10.0.1.4:12032/agent/god/agent-id/map/layer/?resume=http://station3.ll.com:12032/agent/203ad6df-b522-491d-ba48-4e24eb57aeff/send-postcard", unreserved + ":@!$'()*+,="),
"http:%2F%2F10.0.1.4:12032%2Fagent%2Fgod%2Fagent-id%2Fmap%2Flayer%2F%3Fresume=http:%2F%2Fstation3.ll.com:12032%2Fagent%2F203ad6df-b522-491d-ba48-4e24eb57aeff%2Fsend-postcard");
// French cedilla (C with squiggle, like in the word Francais) is UTF-8 C3 A7
#if LL_WINDOWS
#pragma warning(disable: 4309)
#endif
std::string cedilla;
cedilla.push_back( (char)0xC3 );
cedilla.push_back( (char)0xA7 );
ensure_equals("escape UTF8", LLURI::escape( cedilla, unreserved), "%C3%A7");
}
template<> template<>
void URITestObject::test<14>()
{
// make sure escape and unescape of empty strings return empty
// strings.
std::string uri_esc(LLURI::escape(""));
ensure("escape string empty", uri_esc.empty());
std::string uri_raw(LLURI::unescape(""));
ensure("unescape string empty", uri_raw.empty());
}
template<> template<>
void URITestObject::test<15>()
{
// do some round-trip tests
escapeRoundTrip("http://secondlife.com");
escapeRoundTrip("http://secondlife.com/url with spaces");
escapeRoundTrip("http://bad[domain]name.com/");
escapeRoundTrip("ftp://bill.gates@ms/micro$oft.com/c:\\autoexec.bat");
escapeRoundTrip("");
}
template<> template<>
void URITestObject::test<16>()
{
// Test the default escaping
std::string simple("http://secondlife.com");
ensure_equals("simple http", LLURI::escape(simple), simple);
std::string longer("http://secondlife.com:8888/simple.php?foo=bar&q=1");
ensure_equals("more http", LLURI::escape(longer), longer);
ensure_equals(
"needs escape",
LLURI::escape("http://get.secondlife.com/windows viewer"),
"http://get.secondlife.com/windows%20viewer");
}
template<> template<>
void URITestObject::test<17>()
{
// do some round-trip tests with very long strings.
escapeRoundTrip("Welcome to Second Life.We hope you'll have a richly rewarding experience, filled with creativity, self expression and fun.The goals of the Community Standards are simple: treat each other with respect and without harassment, adhere to local standards as indicated by simulator ratings, and refrain from any hate activity which slurs a real-world individual or real-world community. Behavioral Guidelines - The Big Six");
escapeRoundTrip(
"'asset_data':b(12100){'task_id':ucc706f2d-0b68-68f8-11a4-f1043ff35ca0}\n{\n\tname\tObject|\n\tpermissions 0\n\t{\n\t\tbase_mask\t7fffffff\n\t\towner_mask\t7fffffff\n\t\tgroup_mask\t00000000\n\t\teveryone_mask\t00000000\n\t\tnext_owner_mask\t7fffffff\n\t\tcreator_id\t13fd9595-a47b-4d64-a5fb-6da645f038e0\n\t\towner_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\tlast_owner_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\tgroup_id\t00000000-0000-0000-0000-000000000000\n\t}\n\tlocal_id\t217444921\n\ttotal_crc\t323\n\ttype\t2\n\ttask_valid\t2\n\ttravel_access\t13\n\tdisplayopts\t2\n\tdisplaytype\tv\n\tpos\t-0.368634403\t0.00781063363\t-0.569040775\n\toldpos\t150.117996\t25.8658009\t8.19664001\n\trotation\t-0.06293071806430816650390625\t-0.6995697021484375\t-0.7002241611480712890625\t0.1277817934751510620117188\n\tchildpos\t-0.00499999989\t-0.0359999985\t0.307999998\n\tchildrot\t-0.515492737293243408203125\t-0.46601200103759765625\t0.529055416584014892578125\t0.4870323240756988525390625\n\tscale"
"\t0.074629\t0.289956\t0.01\n\tsit_offset\t0\t0\t0\n\tcamera_eye_offset\t0\t0\t0\n\tcamera_at_offset\t0\t0\t0\n\tsit_quat\t0\t0\t0\t1\n\tsit_hint\t0\n\tstate\t160\n\tmaterial\t3\n\tsoundid\t00000000-0000-0000-0000-000000000000\n\tsoundgain\t0\n\tsoundradius\t0\n\tsoundflags\t0\n\ttextcolor\t0 0 0 1\n\tselected\t0\n\tselector\t00000000-0000-0000-0000-000000000000\n\tusephysics\t0\n\trotate_x\t1\n\trotate_y\t1\n\trotate_z\t1\n\tphantom\t0\n\tremote_script_access_pin\t0\n\tvolume_detect\t0\n\tblock_grabs\t0\n\tdie_at_edge\t0\n\treturn_at_edge\t0\n\ttemporary\t0\n\tsandbox\t0\n\tsandboxhome\t0\t0\t0\n\tshape 0\n\t{\n\t\tpath 0\n\t\t{\n\t\t\tcurve\t16\n\t\t\tbegin\t0\n\t\t\tend\t1\n\t\t\tscale_x\t1\n\t\t\tscale_y\t1\n\t\t\tshear_x\t0\n\t\t\tshear_y\t0\n\t\t\ttwist\t0\n\t\t\ttwist_begin\t0\n\t\t\tradius_offset\t0\n\t\t\ttaper_x\t0\n\t\t\ttaper_y\t0\n\t\t\trevolutions\t1\n\t\t\tskew\t0\n\t\t}\n\t\tprofile 0\n\t\t{\n\t\t\tcurve\t1\n\t\t\tbegin\t0\n\t\t\tend\t1\n\t\t\thollow\t0\n\t\t}\n\t}\n\tf"
"aces\t6\n\t{\n\t\timageid\tddde1ffc-678b-3cda-1748-513086bdf01b\n\t\tcolors\t0.937255 0.796078 0.494118 1\n\t\tscales\t1\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\tf54a0c32-3cd1-d49a-5b4f-7b792bebc204\n\t\tcolors\t0.937255 0.796078 0.494118 1\n\t\tscales\t1\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\tf54a0c32-3cd1-d49a-5b4f-7b792bebc204\n\t\tcolors\t0.937255 0.796078 0.494118 1\n\t\tscales\t1\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\tf54a0c32-3cd1-d49a-5b4f-7b792bebc204\n\t\tcolors\t0.937255 0.796078 0.494118 1\n\t\tscales\t1\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\tf54a0c32-3cd1-d49a-5b4f-7b792bebc204"
"\n\t\tcolors\t0.937255 0.796078 0.494118 1\n\t\tscales\t1\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\tddde1ffc-678b-3cda-1748-513086bdf01b\n\t\tcolors\t0.937255 0.796078 0.494118 1\n\t\tscales\t1\n\t\tscalet\t-1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\tps_next_crc\t1\n\tgpw_bias\t1\n\tip\t0\n\tcomplete\tTRUE\n\tdelay\t50000\n\tnextstart\t0\n\tbirthtime\t1061088050622956\n\treztime\t1094866329019785\n\tparceltime\t1133568981980596\n\ttax_rate\t1.00084\n\tscratchpad\t0\n\t{\n\t\n\t}\n\tsale_info\t0\n\t{\n\t\tsale_type\tnot\n\t\tsale_price\t10\n\t}\n\tcorrect_family_id\t00000000-0000-0000-0000-000000000000\n\thas_rezzed\t0\n\tpre_link_base_mask\t7fffffff\n\tlinked \tchild\n\tdefault_pay_price\t-2\t1\t5\t10\t20\n}\n{'task_id':u61fa7364-e151-0597-774c-523312dae31b}\n{\n\tname\tObject|\n\tpermissions 0\n\t{\n\t\tbase_mask\t7fffff"
"ff\n\t\towner_mask\t7fffffff\n\t\tgroup_mask\t00000000\n\t\teveryone_mask\t00000000\n\t\tnext_owner_mask\t7fffffff\n\t\tcreator_id\t13fd9595-a47b-4d64-a5fb-6da645f038e0\n\t\towner_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\tlast_owner_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\tgroup_id\t00000000-0000-0000-0000-000000000000\n\t}\n\tlocal_id\t217444922\n\ttotal_crc\t324\n\ttype\t2\n\ttask_valid\t2\n\ttravel_access\t13\n\tdisplayopts\t2\n\tdisplaytype\tv\n\tpos\t-0.367110789\t0.00780026987\t-0.566269755\n\toldpos\t150.115005\t25.8479004\t8.18669987\n\trotation\t0.47332942485809326171875\t-0.380102097988128662109375\t-0.5734078884124755859375\t0.550168216228485107421875\n\tchildpos\t-0.00499999989\t-0.0370000005\t0.305000007\n\tchildrot\t-0.736649334430694580078125\t-0.03042060509324073791503906\t-0.02784589119255542755126953\t0.67501628398895263671875\n\tscale\t0.074629\t0.289956\t0.01\n\tsit_offset\t0\t0\t0\n\tcamera_eye_offset\t0\t0\t0\n\tcamera_at_offset\t0\t0\t0\n\tsit_quat\t0\t"
"0\t0\t1\n\tsit_hint\t0\n\tstate\t160\n\tmaterial\t3\n\tsoundid\t00000000-0000-0000-0000-000000000000\n\tsoundgain\t0\n\tsoundradius\t0\n\tsoundflags\t0\n\ttextcolor\t0 0 0 1\n\tselected\t0\n\tselector\t00000000-0000-0000-0000-000000000000\n\tusephysics\t0\n\trotate_x\t1\n\trotate_y\t1\n\trotate_z\t1\n\tphantom\t0\n\tremote_script_access_pin\t0\n\tvolume_detect\t0\n\tblock_grabs\t0\n\tdie_at_edge\t0\n\treturn_at_edge\t0\n\ttemporary\t0\n\tsandbox\t0\n\tsandboxhome\t0\t0\t0\n\tshape 0\n\t{\n\t\tpath 0\n\t\t{\n\t\t\tcurve\t16\n\t\t\tbegin\t0\n\t\t\tend\t1\n\t\t\tscale_x\t1\n\t\t\tscale_y\t1\n\t\t\tshear_x\t0\n\t\t\tshear_y\t0\n\t\t\ttwist\t0\n\t\t\ttwist_begin\t0\n\t\t\tradius_offset\t0\n\t\t\ttaper_x\t0\n\t\t\ttaper_y\t0\n\t\t\trevolutions\t1\n\t\t\tskew\t0\n\t\t}\n\t\tprofile 0\n\t\t{\n\t\t\tcurve\t1\n\t\t\tbegin\t0\n\t\t\tend\t1\n\t\t\thollow\t0\n\t\t}\n\t}\n\tfaces\t6\n\t{\n\t\timageid\tddde1ffc-678b-3cda-1748-513086bdf01b\n\t\tcolors\t0.937255 0.796078 0.494118 1\n\t\tscales\t1\n\t"
"\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\tf54a0c32-3cd1-d49a-5b4f-7b792bebc204\n\t\tcolors\t0.937255 0.796078 0.494118 1\n\t\tscales\t1\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\tf54a0c32-3cd1-d49a-5b4f-7b792bebc204\n\t\tcolors\t0.937255 0.796078 0.494118 1\n\t\tscales\t1\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\tf54a0c32-3cd1-d49a-5b4f-7b792bebc204\n\t\tcolors\t0.937255 0.796078 0.494118 1\n\t\tscales\t1\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\tf54a0c32-3cd1-d49a-5b4f-7b792bebc204\n\t\tcolors\t0.937255 0.796078 0.494118 1\n\t\tscales\t1\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t"
"\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\tddde1ffc-678b-3cda-1748-513086bdf01b\n\t\tcolors\t0.937255 0.796078 0.494118 1\n\t\tscales\t1\n\t\tscalet\t-1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\tps_next_crc\t1\n\tgpw_bias\t1\n\tip\t0\n\tcomplete\tTRUE\n\tdelay\t50000\n\tnextstart\t0\n\tbirthtime\t1061087839248891\n\treztime\t1094866329020800\n\tparceltime\t1133568981981983\n\ttax_rate\t1.00084\n\tscratchpad\t0\n\t{\n\t\n\t}\n\tsale_info\t0\n\t{\n\t\tsale_type\tnot\n\t\tsale_price\t10\n\t}\n\tcorrect_family_id\t00000000-0000-0000-0000-000000000000\n\thas_rezzed\t0\n\tpre_link_base_mask\t7fffffff\n\tlinked \tchild\n\tdefault_pay_price\t-2\t1\t5\t10\t20\n}\n{'task_id':ub8d68643-7dd8-57af-0d24-8790032aed0c}\n{\n\tname\tObject|\n\tpermissions 0\n\t{\n\t\tbase_mask\t7fffffff\n\t\towner_mask\t7fffffff\n\t\tgroup_mask\t00000000\n\t\teveryone_mask\t00000000\n\t\tnext_owner_mask\t7fffffff\n\t\tcreat"
"or_id\t13fd9595-a47b-4d64-a5fb-6da645f038e0\n\t\towner_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\tlast_owner_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\tgroup_id\t00000000-0000-0000-0000-000000000000\n\t}\n\tlocal_id\t217444923\n\ttotal_crc\t235\n\ttype\t2\n\ttask_valid\t2\n\ttravel_access\t13\n\tdisplayopts\t2\n\tdisplaytype\tv\n\tpos\t-0.120029509\t-0.00284469454\t-0.0302077383\n\toldpos\t150.710999\t25.8584995\t8.19172001\n\trotation\t0.145459949970245361328125\t-0.1646589934825897216796875\t0.659558117389678955078125\t-0.718826770782470703125\n\tchildpos\t0\t-0.182999998\t-0.26699999\n\tchildrot\t0.991444766521453857421875\t3.271923924330621957778931e-05\t-0.0002416197530692443251609802\t0.1305266767740249633789062\n\tscale\t0.0382982\t0.205957\t0.368276\n\tsit_offset\t0\t0\t0\n\tcamera_eye_offset\t0\t0\t0\n\tcamera_at_offset\t0\t0\t0\n\tsit_quat\t0\t0\t0\t1\n\tsit_hint\t0\n\tstate\t160\n\tmaterial\t3\n\tsoundid\t00000000-0000-0000-0000-000000000000\n\tsoundgain\t0\n\tsoundra"
"dius\t0\n\tsoundflags\t0\n\ttextcolor\t0 0 0 1\n\tselected\t0\n\tselector\t00000000-0000-0000-0000-000000000000\n\tusephysics\t0\n\trotate_x\t1\n\trotate_y\t1\n\trotate_z\t1\n\tphantom\t0\n\tremote_script_access_pin\t0\n\tvolume_detect\t0\n\tblock_grabs\t0\n\tdie_at_edge\t0\n\treturn_at_edge\t0\n\ttemporary\t0\n\tsandbox\t0\n\tsandboxhome\t0\t0\t0\n\tshape 0\n\t{\n\t\tpath 0\n\t\t{\n\t\t\tcurve\t32\n\t\t\tbegin\t0.3\n\t\t\tend\t0.65\n\t\t\tscale_x\t1\n\t\t\tscale_y\t0.05\n\t\t\tshear_x\t0\n\t\t\tshear_y\t0\n\t\t\ttwist\t0\n\t\t\ttwist_begin\t0\n\t\t\tradius_offset\t0\n\t\t\ttaper_x\t0\n\t\t\ttaper_y\t0\n\t\t\trevolutions\t1\n\t\t\tskew\t0\n\t\t}\n\t\tprofile 0\n\t\t{\n\t\t\tcurve\t0\n\t\t\tbegin\t0\n\t\t\tend\t1\n\t\t\thollow\t0\n\t\t}\n\t}\n\tfaces\t3\n\t{\n\t\timageid\te7150bed-3e3e-c698-eb15-d17b178148af\n\t\tcolors\t0.843137 0.156863 0.156863 1\n\t\tscales\t15\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t-1.57084\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0"
"\n\t}\n\t{\n\t\timageid\te7150bed-3e3e-c698-eb15-d17b178148af\n\t\tcolors\t0.843137 0.156863 0.156863 1\n\t\tscales\t15\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t-1.57084\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\te7150bed-3e3e-c698-eb15-d17b178148af\n\t\tcolors\t0.843137 0.156863 0.156863 1\n\t\tscales\t15\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t-1.57084\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\tps_next_crc\t1\n\tgpw_bias\t1\n\tip\t0\n\tcomplete\tTRUE\n\tdelay\t50000\n\tnextstart\t0\n\tbirthtime\t1061087534454174\n\treztime\t1094866329021741\n\tparceltime\t1133568981982889\n\ttax_rate\t1.00326\n\tscratchpad\t0\n\t{\n\t\n\t}\n\tsale_info\t0\n\t{\n\t\tsale_type\tnot\n\t\tsale_price\t10\n\t}\n\tcorrect_family_id\t00000000-0000-0000-0000-000000000000\n\thas_rezzed\t0\n\tpre_link_base_mask\t7fffffff\n\tlinked \tchild\n\tdefault_pay_price\t-2\t1\t5\t10\t20\n}\n{'task_id':ue4b19200-9d33-962f-c8c5-6f"
"25be3a3fd0}\n{\n\tname\tApotheosis_Immolaine_tail|\n\tpermissions 0\n\t{\n\t\tbase_mask\t7fffffff\n\t\towner_mask\t7fffffff\n\t\tgroup_mask\t00000000\n\t\teveryone_mask\t00000000\n\t\tnext_owner_mask\t7fffffff\n\t\tcreator_id\t13fd9595-a47b-4d64-a5fb-6da645f038e0\n\t\towner_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\tlast_owner_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\tgroup_id\t00000000-0000-0000-0000-000000000000\n\t}\n\tlocal_id\t217444924\n\ttotal_crc\t675\n\ttype\t1\n\ttask_valid\t2\n\ttravel_access\t13\n\tdisplayopts\t2\n\tdisplaytype\tv\n\tpos\t-0.34780401\t-0.00968400016\t-0.260098994\n\toldpos\t0\t0\t0\n\trotation\t0.73164522647857666015625\t-0.67541944980621337890625\t-0.07733880728483200073242188\t0.05022468417882919311523438\n\tvelocity\t0\t0\t0\n\tangvel\t0\t0\t0\n\tscale\t0.0382982\t0.32228\t0.383834\n\tsit_offset\t0\t0\t0\n\tcamera_eye_offset\t0\t0\t0\n\tcamera_at_offset\t0\t0\t0\n\tsit_quat\t0\t0\t0\t1\n\tsit_hint\t0\n\tstate\t160\n\tmaterial\t3\n\tsoundid\t00000"
"000-0000-0000-0000-000000000000\n\tsoundgain\t0\n\tsoundradius\t0\n\tsoundflags\t0\n\ttextcolor\t0 0 0 1\n\tselected\t0\n\tselector\t00000000-0000-0000-0000-000000000000\n\tusephysics\t0\n\trotate_x\t1\n\trotate_y\t1\n\trotate_z\t1\n\tphantom\t0\n\tremote_script_access_pin\t0\n\tvolume_detect\t0\n\tblock_grabs\t0\n\tdie_at_edge\t0\n\treturn_at_edge\t0\n\ttemporary\t0\n\tsandbox\t0\n\tsandboxhome\t0\t0\t0\n\tshape 0\n\t{\n\t\tpath 0\n\t\t{\n\t\t\tcurve\t32\n\t\t\tbegin\t0.3\n\t\t\tend\t0.65\n\t\t\tscale_x\t1\n\t\t\tscale_y\t0.05\n\t\t\tshear_x\t0\n\t\t\tshear_y\t0\n\t\t\ttwist\t0\n\t\t\ttwist_begin\t0\n\t\t\tradius_offset\t0\n\t\t\ttaper_x\t0\n\t\t\ttaper_y\t0\n\t\t\trevolutions\t1\n\t\t\tskew\t0\n\t\t}\n\t\tprofile 0\n\t\t{\n\t\t\tcurve\t0\n\t\t\tbegin\t0\n\t\t\tend\t1\n\t\t\thollow\t0\n\t\t}\n\t}\n\tfaces\t3\n\t{\n\t\timageid\te7150bed-3e3e-c698-eb15-d17b178148af\n\t\tcolors\t0.843137 0.156863 0.156863 1\n\t\tscales\t15\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t-1"
".57084\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\te7150bed-3e3e-c698-eb15-d17b178148af\n\t\tcolors\t0.843137 0.156863 0.156863 1\n\t\tscales\t15\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t-1.57084\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\te7150bed-3e3e-c698-eb15-d17b178148af\n\t\tcolors\t0.843137 0.156863 0.156863 1\n\t\tscales\t15\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t-1.57084\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\tps_next_crc\t1\n\tgpw_bias\t1\n\tip\t0\n\tcomplete\tTRUE\n\tdelay\t50000\n\tnextstart\t0\n\tbirthtime\t1061087463950186\n\treztime\t1094866329022555\n\tparceltime\t1133568981984359\n\tdescription\t(No Description)|\n\ttax_rate\t1.01736\n\tnamevalue\tAttachPt U32 RW S 10\n\tnamevalue\tAttachmentOrientation VEC3 RW DS -3.110088, -0.182018, 1.493795\n\tnamevalue\tAttachmentOffset VEC3 RW DS -0.347804, -0.009684, -0.260099\n\tnamevalue\tAttachItemI"
"D STRING RW SV 20f36c3a-b44b-9bc7-87f3-018bfdfc8cda\n\tscratchpad\t0\n\t{\n\t\n\t}\n\tsale_info\t0\n\t{\n\t\tsale_type\tnot\n\t\tsale_price\t10\n\t}\n\torig_asset_id\t8747acbc-d391-1e59-69f1-41d06830e6c0\n\torig_item_id\t20f36c3a-b44b-9bc7-87f3-018bfdfc8cda\n\tfrom_task_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\tcorrect_family_id\t00000000-0000-0000-0000-000000000000\n\thas_rezzed\t0\n\tpre_link_base_mask\t7fffffff\n\tlinked \tlinked\n\tdefault_pay_price\t-2\t1\t5\t10\t20\n}\n");
}
template<> template<>
void URITestObject::test<18>()
{
LLURI u("secondlife:///app/login?first_name=Testert4&last_name=Tester&web_login_key=test");
// if secondlife is the scheme, LLURI should parse /app/login as path, with no authority
ensure_equals("scheme", u.scheme(), "secondlife");
ensure_equals("authority", u.authority(), "");
ensure_equals("path", u.path(), "/app/login");
ensure_equals("pathmap", u.pathArray()[0].asString(), "app");
ensure_equals("pathmap", u.pathArray()[1].asString(), "login");
ensure_equals("query", u.query(), "first_name=Testert4&last_name=Tester&web_login_key=test");
ensure_equals("query map element", u.queryMap()["last_name"].asString(), "Tester");
u = LLURI("secondlife://Da Boom/128/128/128");
// if secondlife is the scheme, LLURI should parse /128/128/128 as path, with Da Boom as authority
ensure_equals("scheme", u.scheme(), "secondlife");
ensure_equals("authority", u.authority(), "Da Boom");
ensure_equals("path", u.path(), "/128/128/128");
ensure_equals("pathmap", u.pathArray()[0].asString(), "128");
ensure_equals("pathmap", u.pathArray()[1].asString(), "128");
ensure_equals("pathmap", u.pathArray()[2].asString(), "128");
ensure_equals("query", u.query(), "");
}
template<> template<>
void URITestObject::test<19>()
{
// Parse about: schemes
LLURI u("about:blank?redirect-http-hack=secondlife%3A%2F%2F%2Fapp%2Flogin%3Ffirst_name%3DCallum%26last_name%3DLinden%26location%3Dspecify%26grid%3Dvaak%26region%3D%2FMorris%2F128%2F128%26web_login_key%3Defaa4795-c2aa-4c58-8966-763c27931e78");
ensure_equals("scheme", u.scheme(), "about");
ensure_equals("authority", u.authority(), "");
ensure_equals("path", u.path(), "blank");
ensure_equals("pathmap", u.pathArray()[0].asString(), "blank");
ensure_equals("query", u.query(), "redirect-http-hack=secondlife:///app/login?first_name=Callum&last_name=Linden&location=specify&grid=vaak&region=/Morris/128/128&web_login_key=efaa4795-c2aa-4c58-8966-763c27931e78");
ensure_equals("query map element", u.queryMap()["redirect-http-hack"].asString(), "secondlife:///app/login?first_name=Callum&last_name=Linden&location=specify&grid=vaak&region=/Morris/128/128&web_login_key=efaa4795-c2aa-4c58-8966-763c27931e78");
}
}

View File

@@ -0,0 +1,162 @@
/**
* @file lluserrelations_tut.cpp
* @author Phoenix
* @date 2006-10-12
* @brief Unit tests for the LLRelationship class.
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "lluserrelations.h"
namespace tut
{
struct user_relationship
{
LLRelationship mRelationship;
};
typedef test_group<user_relationship> user_relationship_t;
typedef user_relationship_t::object user_relationship_object_t;
tut::user_relationship_t tut_user_relationship("relationships");
template<> template<>
void user_relationship_object_t::test<1>()
{
// Test the default construction
ensure(
"No granted rights to",
!mRelationship.isRightGrantedTo(
LLRelationship::GRANT_ONLINE_STATUS));
ensure(
"No granted rights from",
!mRelationship.isRightGrantedFrom(
LLRelationship::GRANT_ONLINE_STATUS));
ensure("No online status",!mRelationship.isOnline());
}
template<> template<>
void user_relationship_object_t::test<2>()
{
// Test some granting
mRelationship.grantRights(
LLRelationship::GRANT_ONLINE_STATUS,
LLRelationship::GRANT_MODIFY_OBJECTS);
ensure(
"Granted rights to has online",
mRelationship.isRightGrantedTo(
LLRelationship::GRANT_ONLINE_STATUS));
ensure(
"Granted rights from does not have online",
!mRelationship.isRightGrantedFrom(
LLRelationship::GRANT_ONLINE_STATUS));
ensure(
"Granted rights to does not have modify",
!mRelationship.isRightGrantedTo(
LLRelationship::GRANT_MODIFY_OBJECTS));
ensure(
"Granted rights from has modify",
mRelationship.isRightGrantedFrom(
LLRelationship::GRANT_MODIFY_OBJECTS));
}
template<> template<>
void user_relationship_object_t::test<3>()
{
// Test revoking
mRelationship.grantRights(
LLRelationship::GRANT_ONLINE_STATUS
| LLRelationship::GRANT_MAP_LOCATION,
LLRelationship::GRANT_ONLINE_STATUS);
ensure(
"Granted rights to has online and map",
mRelationship.isRightGrantedTo(
LLRelationship::GRANT_ONLINE_STATUS
| LLRelationship::GRANT_MAP_LOCATION));
ensure(
"Granted rights from has online",
mRelationship.isRightGrantedFrom(
LLRelationship::GRANT_ONLINE_STATUS));
mRelationship.revokeRights(
LLRelationship::GRANT_MAP_LOCATION,
LLRelationship::GRANT_NONE);
ensure(
"Granted rights revoked map",
!mRelationship.isRightGrantedTo(
LLRelationship::GRANT_ONLINE_STATUS
| LLRelationship::GRANT_MAP_LOCATION));
ensure(
"Granted rights revoked still has online",
mRelationship.isRightGrantedTo(
LLRelationship::GRANT_ONLINE_STATUS));
mRelationship.grantRights(
LLRelationship::GRANT_NONE,
LLRelationship::GRANT_MODIFY_OBJECTS);
ensure(
"Granted rights from still has online",
mRelationship.isRightGrantedFrom(
LLRelationship::GRANT_ONLINE_STATUS));
ensure(
"Granted rights from has full grant",
mRelationship.isRightGrantedFrom(
LLRelationship::GRANT_ONLINE_STATUS
| LLRelationship::GRANT_MODIFY_OBJECTS));
mRelationship.revokeRights(
LLRelationship::GRANT_NONE,
LLRelationship::GRANT_MODIFY_OBJECTS);
ensure(
"Granted rights from still has online",
mRelationship.isRightGrantedFrom(
LLRelationship::GRANT_ONLINE_STATUS));
ensure(
"Granted rights from no longer modify",
!mRelationship.isRightGrantedFrom(
LLRelationship::GRANT_MODIFY_OBJECTS));
}
template<> template<>
void user_relationship_object_t::test<4>()
{
ensure("No online status", !mRelationship.isOnline());
mRelationship.online(true);
ensure("Online status", mRelationship.isOnline());
mRelationship.online(false);
ensure("No online status", !mRelationship.isOnline());
}
/*
template<> template<>
void user_relationship_object_t::test<>()
{
}
*/
}

View File

@@ -0,0 +1,363 @@
/**
* @file lluuidhashmap_tut.cpp
* @author Adroit
* @date 2007-02
* @brief Test cases for LLUUIDHashMap
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "lluuidhashmap.h"
#include "llsdserialize.h"
namespace tut
{
class UUIDTableEntry
{
public:
UUIDTableEntry()
{
mID.setNull();
mValue = 0;
}
UUIDTableEntry(const LLUUID& id, U32 value)
{
mID = id;
mValue = value;
}
~UUIDTableEntry(){};
static BOOL uuidEq(const LLUUID &uuid, const UUIDTableEntry &id_pair)
{
if (uuid == id_pair.mID)
{
return TRUE;
}
return FALSE;
}
const LLUUID& getID() { return mID; }
const U32& getValue() { return mValue; }
protected:
LLUUID mID;
U32 mValue;
};
struct hashmap_test
{
};
typedef test_group<hashmap_test> hash_index_t;
typedef hash_index_t::object hash_index_object_t;
tut::hash_index_t tut_hash_index("hashmap_test");
// stress test
template<> template<>
void hash_index_object_t::test<1>()
{
LLUUIDHashMap<UUIDTableEntry, 32> hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry());
const int numElementsToCheck = 32*256*32;
std::vector<LLUUID> idList(numElementsToCheck);
int i;
for (i = 0; i < numElementsToCheck; i++)
{
LLUUID id;
id.generate();
UUIDTableEntry entry(id, i);
hashTable.set(id, entry);
idList[i] = id;
}
for (i = 0; i < numElementsToCheck; i++)
{
LLUUID idToCheck = idList[i];
UUIDTableEntry entryToCheck = hashTable.get(idToCheck);
ensure("set/get did not work", entryToCheck.getID() == idToCheck && entryToCheck.getValue() == (size_t)i);
}
for (i = 0; i < numElementsToCheck; i++)
{
LLUUID idToCheck = idList[i];
if (i % 2 != 0)
{
hashTable.remove(idToCheck);
}
}
for (i = 0; i < numElementsToCheck; i++)
{
LLUUID idToCheck = idList[i];
ensure("remove or check did not work", (i % 2 == 0 && hashTable.check(idToCheck)) || (i % 2 != 0 && !hashTable.check(idToCheck)));
}
}
// test removing all but one element.
template<> template<>
void hash_index_object_t::test<2>()
{
LLUUIDHashMap<UUIDTableEntry, 2> hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry());
const int numElementsToCheck = 5;
std::vector<LLUUID> idList(numElementsToCheck*10);
int i;
for (i = 0; i < numElementsToCheck; i++)
{
LLUUID id;
id.generate();
UUIDTableEntry entry(id, i);
hashTable.set(id, entry);
idList[i] = id;
}
ensure("getLength failed", hashTable.getLength() == numElementsToCheck);
// remove all but the last element
for (i = 0; i < numElementsToCheck-1; i++)
{
LLUUID idToCheck = idList[i];
hashTable.remove(idToCheck);
}
// there should only be one element left now.
ensure("getLength failed", hashTable.getLength() == 1);
for (i = 0; i < numElementsToCheck; i++)
{
LLUUID idToCheck = idList[i];
if (i != numElementsToCheck - 1)
{
ensure("remove did not work", hashTable.check(idToCheck) == FALSE);
}
else
{
UUIDTableEntry entryToCheck = hashTable.get(idToCheck);
ensure("remove did not work", entryToCheck.getID() == idToCheck && entryToCheck.getValue() == (size_t)i);
}
}
}
// test overriding of value already set.
template<> template<>
void hash_index_object_t::test<3>()
{
LLUUIDHashMap<UUIDTableEntry, 5> hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry());
const int numElementsToCheck = 10;
std::vector<LLUUID> idList(numElementsToCheck);
int i;
for (i = 0; i < numElementsToCheck; i++)
{
LLUUID id;
id.generate();
UUIDTableEntry entry(id, i);
hashTable.set(id, entry);
idList[i] = id;
}
for (i = 0; i < numElementsToCheck; i++)
{
LLUUID id = idList[i];
// set new entry with value = i+numElementsToCheck
UUIDTableEntry entry(id, i+numElementsToCheck);
hashTable.set(id, entry);
}
for (i = 0; i < numElementsToCheck; i++)
{
LLUUID idToCheck = idList[i];
UUIDTableEntry entryToCheck = hashTable.get(idToCheck);
ensure("set/get did not work", entryToCheck.getID() == idToCheck && entryToCheck.getValue() == (size_t)(i+numElementsToCheck));
}
}
// test removeAll()
template<> template<>
void hash_index_object_t::test<4>()
{
LLUUIDHashMap<UUIDTableEntry, 5> hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry());
const int numElementsToCheck = 10;
std::vector<LLUUID> idList(numElementsToCheck);
int i;
for (i = 0; i < numElementsToCheck; i++)
{
LLUUID id;
id.generate();
UUIDTableEntry entry(id, i);
hashTable.set(id, entry);
idList[i] = id;
}
hashTable.removeAll();
ensure("removeAll failed", hashTable.getLength() == 0);
}
// test sparse map - force it by creating 256 entries that fall into 256 different nodes
template<> template<>
void hash_index_object_t::test<5>()
{
LLUUIDHashMap<UUIDTableEntry, 2> hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry());
const int numElementsToCheck = 256;
std::vector<LLUUID> idList(numElementsToCheck);
int i;
for (i = 0; i < numElementsToCheck; i++)
{
LLUUID id;
id.generate();
// LLUUIDHashMap uses mData[0] to pick the bucket
// overwrite mData[0] so that it ranges from 0 to 255
id.mData[0] = i;
UUIDTableEntry entry(id, i);
hashTable.set(id, entry);
idList[i] = id;
}
for (i = 0; i < numElementsToCheck; i++)
{
LLUUID idToCheck = idList[i];
UUIDTableEntry entryToCheck = hashTable.get(idToCheck);
ensure("set/get did not work for sparse map", entryToCheck.getID() == idToCheck && entryToCheck.getValue() == (size_t)i);
}
for (i = 0; i < numElementsToCheck; i++)
{
LLUUID idToCheck = idList[i];
if (i % 2 != 0)
{
hashTable.remove(idToCheck);
}
}
for (i = 0; i < numElementsToCheck; i++)
{
LLUUID idToCheck = idList[i];
ensure("remove or check did not work for sparse map", (i % 2 == 0 && hashTable.check(idToCheck)) || (i % 2 != 0 && !hashTable.check(idToCheck)));
}
}
// iterator
template<> template<>
void hash_index_object_t::test<6>()
{
LLUUIDHashMap<UUIDTableEntry, 2> hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry());
LLUUIDHashMapIter<UUIDTableEntry, 2> hashIter(&hashTable);
const int numElementsToCheck = 256;
std::vector<LLUUID> idList(numElementsToCheck);
int i;
for (i = 0; i < numElementsToCheck; i++)
{
LLUUID id;
id.generate();
// LLUUIDHashMap uses mData[0] to pick the bucket
// overwrite mData[0] so that it ranges from 0 to 255
// to create a sparse map
id.mData[0] = i;
UUIDTableEntry entry(id, i);
hashTable.set(id, entry);
idList[i] = id;
}
hashIter.first();
int numElementsIterated = 0;
while(!hashIter.done())
{
numElementsIterated++;
UUIDTableEntry tableEntry = *hashIter;
LLUUID id = tableEntry.getID();
hashIter.next();
ensure("Iteration failed for sparse map", tableEntry.getValue() < (size_t)numElementsToCheck && idList[tableEntry.getValue()] == tableEntry.getID());
}
ensure("iteration count failed", numElementsIterated == numElementsToCheck);
}
// remove after middle of iteration
template<> template<>
void hash_index_object_t::test<7>()
{
LLUUIDHashMap<UUIDTableEntry, 2> hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry());
LLUUIDHashMapIter<UUIDTableEntry, 2> hashIter(&hashTable);
const int numElementsToCheck = 256;
std::vector<LLUUID> idList(numElementsToCheck);
int i;
LLUUID uuidtoSearch;
for (i = 0; i < numElementsToCheck; i++)
{
LLUUID id;
id.generate();
// LLUUIDHashMap uses mData[0] to pick the bucket
// overwrite mData[0] so that it ranges from 0 to 255
// to create a sparse map
id.mData[0] = i;
UUIDTableEntry entry(id, i);
hashTable.set(id, entry);
idList[i] = id;
// pick uuid somewhere in the middle
if (i == 5)
{
uuidtoSearch = id;
}
}
hashIter.first();
int numElementsIterated = 0;
while(!hashIter.done())
{
numElementsIterated++;
UUIDTableEntry tableEntry = *hashIter;
LLUUID id = tableEntry.getID();
if (uuidtoSearch == id)
{
break;
}
hashIter.next();
}
// current iterator implementation will not allow any remove operations
// until ALL elements have been iterated over. this seems to be
// an unnecessary restriction. Iterator should have a method to
// reset() its state so that further operations (inckuding remove)
// can be performed on the HashMap without having to iterate thru
// all the remaining nodes.
// hashIter.reset();
// hashTable.remove(uuidtoSearch);
// ensure("remove after iteration reset failed", hashTable.check(uuidtoSearch) == FALSE);
}
}

63
indra/test/llxfer_tut.cpp Normal file
View File

@@ -0,0 +1,63 @@
/**
* @file llxfer_tut.cpp
* @author Moss
* @date 2007-04-17
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "lltut.h"
#include "llxfer_file.h"
namespace tut
{
struct llxfer_data
{
};
typedef test_group<llxfer_data> llxfer_test;
typedef llxfer_test::object llxfer_object;
tut::llxfer_test llxfer("llxfer");
template<> template<>
void llxfer_object::test<1>()
{
// test that we handle an oversized filename correctly.
std::string oversized_filename;
U32 i;
for (i=0; i<LL_MAX_PATH*2; ++i) // create oversized filename
{
oversized_filename += 'X';
}
LLXfer_File xff(oversized_filename, FALSE, 1);
ensure("oversized local_filename nul-terminated",
xff.getFileName().length() < LL_MAX_PATH);
}
}

View File

@@ -0,0 +1,137 @@
/**
* @file llxorcipher_tut.cpp
* @author Adroit
* @date 2007-03
* @brief llxorcipher, llnullcipher test cases.
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "lltut.h"
#include "llxorcipher.h"
#include "llnullcipher.h"
namespace tut
{
struct cipher
{
};
typedef test_group<cipher> cipher_t;
typedef cipher_t::object cipher_object_t;
tut::cipher_t tut_cipher("cipher");
//encrypt->decrypt
template<> template<>
void cipher_object_t::test<1>()
{
const U32 len = 3;
const U8 pad[] = "abc";
const char str[] = "SecondLife";
const S32 str_len = sizeof(str);
U8 encrypted[str_len];
U8 decrypted[str_len];
LLXORCipher xorCipher(pad, len);
LLXORCipher xorCipher1(pad, len);
U32 length = xorCipher.requiredEncryptionSpace(50);
ensure("requiredEncryptionSpace() function failed", (length == 50));
U32 lenEncrypted = xorCipher.encrypt((U8 *) str, str_len, encrypted, str_len);
ensure("Encryption failed", (lenEncrypted == str_len));
U32 lenDecrypted = xorCipher1.decrypt(encrypted, str_len, decrypted, str_len);
ensure("Decryption failed", (lenDecrypted == str_len));
ensure_memory_matches("LLXORCipher Encrypt/Decrypt failed", str, str_len, decrypted, lenDecrypted);
}
// operator=
template<> template<>
void cipher_object_t::test<2>()
{
const U8 pad[] = "ABCDEFGHIJKLMNOPQ"; // pad len longer than data to be ciphered
const U32 pad_len = sizeof(pad);
const U8 pad1[] = "SecondLife";
const U32 pad_len1 = sizeof(pad1);
const char str[] = "To Be Ciphered";
const S32 str_len = sizeof(str);
U8 encrypted[str_len];
U8 decrypted[str_len];
LLXORCipher xorCipher(pad, pad_len);
LLXORCipher xorCipher1(pad1, pad_len1);
xorCipher.encrypt((U8 *) str, str_len, encrypted, str_len);
// make xorCipher1 same as xorCipher..so that xorCipher1 can decrypt what was
// encrypted using xorCipher
xorCipher1 = xorCipher;
U32 lenDecrypted = xorCipher1.decrypt(encrypted, str_len, decrypted, str_len);
ensure_memory_matches("LLXORCipher operator= failed", str, str_len, decrypted, lenDecrypted);
}
//in place encrypt->decrypt
template<> template<>
void cipher_object_t::test<3>()
{
U32 padNum = 0x12349087;
const U8* pad = (U8*) &padNum;
const U32 pad_len = sizeof(U32);
char str[] = "To Be Ciphered a long string.........!!!.";
char str1[] = "To Be Ciphered a long string.........!!!."; // same as str
const S32 str_len = sizeof(str);
LLXORCipher xorCipher(pad, pad_len);
LLXORCipher xorCipher1(pad, pad_len);
xorCipher.encrypt((U8 *) str, str_len);
// it should not be the same as original data!
ensure("LLXORCipher: In Place encrypt failed", memcmp(str, str1, str_len) != 0);
xorCipher1.decrypt((U8 *) str, str_len);
// it should not be the same as original data!
ensure_memory_matches("LLXORCipher: In Place decrypt failed", str, str_len, str1, str_len);
}
//LLNullCipher encrypt->decrypt
template<> template<>
void cipher_object_t::test<4>()
{
const char str[] = "SecondLife";
const S32 str_len = sizeof(str);
U8 encrypted[str_len];
U8 decrypted[str_len];
LLNullCipher nullCipher;
LLNullCipher nullCipher1;
U32 length = nullCipher.requiredEncryptionSpace(50);
ensure("LLNullCipher::requiredEncryptionSpace() function failed", (length == 50));
U32 len1 = nullCipher.encrypt((U8 *) str, str_len, encrypted, str_len);
ensure_memory_matches("LLNullCipher - Source transformed during encryption.", encrypted, len1, str, str_len);
U32 len2 = nullCipher1.decrypt(encrypted, str_len, decrypted, str_len);
ensure_memory_matches("LLNullCipher - Decryption failed", decrypted, len2, str, str_len);
}
}

324
indra/test/m3math_tut.cpp Normal file
View File

@@ -0,0 +1,324 @@
/**
* @file m3math_tut.cpp
* @author Adroit
* @date 2007-03
* @brief Test cases of m3math.h
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "lltut.h"
#include "linden_common.h"
#include "m3math.h"
#include "v3math.h"
#include "v4math.h"
#include "m4math.h"
#include "llquaternion.h"
#include "v3dmath.h"
namespace tut
{
struct m3math_test
{
};
typedef test_group<m3math_test> m3math_test_t;
typedef m3math_test_t::object m3math_test_object_t;
tut::m3math_test_t tut_m3math_test("m3math_test");
//test case for identity() fn.
template<> template<>
void m3math_test_object_t::test<1>()
{
LLMatrix3 llmat3_obj;
llmat3_obj.identity();
ensure("LLMatrix3::identity failed", 1.f == llmat3_obj.mMatrix[0][0] &&
0.f == llmat3_obj.mMatrix[0][1] &&
0.f == llmat3_obj.mMatrix[0][2] &&
0.f == llmat3_obj.mMatrix[1][0] &&
1.f == llmat3_obj.mMatrix[1][1] &&
0.f == llmat3_obj.mMatrix[1][2] &&
0.f == llmat3_obj.mMatrix[2][0] &&
0.f == llmat3_obj.mMatrix[2][1] &&
1.f == llmat3_obj.mMatrix[2][2]);
}
//test case for LLMatrix3& zero() fn.
template<> template<>
void m3math_test_object_t::test<2>()
{
LLMatrix3 llmat3_obj(30, 1, 2, 3);
llmat3_obj.zero();
ensure("LLMatrix3::zero failed", 0.f == llmat3_obj.zero().mMatrix[0][0] &&
0.f == llmat3_obj.zero().mMatrix[0][1] &&
0.f == llmat3_obj.zero().mMatrix[0][2] &&
0.f == llmat3_obj.zero().mMatrix[1][0] &&
0.f == llmat3_obj.zero().mMatrix[1][1] &&
0.f == llmat3_obj.zero().mMatrix[1][2] &&
0.f == llmat3_obj.zero().mMatrix[2][0] &&
0.f == llmat3_obj.zero().mMatrix[2][1] &&
0.f == llmat3_obj.zero().mMatrix[2][2]);
}
//test case for setRows(const LLVector3 &x_axis, const LLVector3 &y_axis, const LLVector3 &z_axis) fns.
template<> template<>
void m3math_test_object_t::test<3>()
{
LLMatrix3 llmat3_obj;
LLVector3 vect1(2, 1, 4);
LLVector3 vect2(3, 5, 7);
LLVector3 vect3(6, 9, 7);
llmat3_obj.setRows(vect1, vect2, vect3);
ensure("LLVector3::setRows failed ", 2 == llmat3_obj.mMatrix[0][0] &&
1 == llmat3_obj.mMatrix[0][1] &&
4 == llmat3_obj.mMatrix[0][2] &&
3 == llmat3_obj.mMatrix[1][0] &&
5 == llmat3_obj.mMatrix[1][1] &&
7 == llmat3_obj.mMatrix[1][2] &&
6 == llmat3_obj.mMatrix[2][0] &&
9 == llmat3_obj.mMatrix[2][1] &&
7 == llmat3_obj.mMatrix[2][2]);
}
//test case for getFwdRow(), getLeftRow(), getUpRow() fns.
template<> template<>
void m3math_test_object_t::test<4>()
{
LLMatrix3 llmat3_obj;
LLVector3 vect1(2, 1, 4);
LLVector3 vect2(3, 5, 7);
LLVector3 vect3(6, 9, 7);
llmat3_obj.setRows(vect1, vect2, vect3);
ensure("LLVector3::getFwdRow failed ", vect1 == llmat3_obj.getFwdRow());
ensure("LLVector3::getLeftRow failed ", vect2 == llmat3_obj.getLeftRow());
ensure("LLVector3::getUpRow failed ", vect3 == llmat3_obj.getUpRow());
}
//test case for operator*(const LLMatrix3 &a, const LLMatrix3 &b)
template<> template<>
void m3math_test_object_t::test<5>()
{
LLMatrix3 llmat_obj1;
LLMatrix3 llmat_obj2;
LLMatrix3 llmat_obj3;
LLVector3 llvec1(1, 3, 5);
LLVector3 llvec2(3, 6, 1);
LLVector3 llvec3(4, 6, 9);
LLVector3 llvec4(1, 1, 5);
LLVector3 llvec5(3, 6, 8);
LLVector3 llvec6(8, 6, 2);
LLVector3 llvec7(0, 0, 0);
LLVector3 llvec8(0, 0, 0);
LLVector3 llvec9(0, 0, 0);
llmat_obj1.setRows(llvec1, llvec2, llvec3);
llmat_obj2.setRows(llvec4, llvec5, llvec6);
llmat_obj3.setRows(llvec7, llvec8, llvec9);
llmat_obj3 = llmat_obj1 * llmat_obj2;
ensure("LLMatrix3::operator*(const LLMatrix3 &a, const LLMatrix3 &b) failed",
50 == llmat_obj3.mMatrix[0][0] &&
49 == llmat_obj3.mMatrix[0][1] &&
39 == llmat_obj3.mMatrix[0][2] &&
29 == llmat_obj3.mMatrix[1][0] &&
45 == llmat_obj3.mMatrix[1][1] &&
65 == llmat_obj3.mMatrix[1][2] &&
94 == llmat_obj3.mMatrix[2][0] &&
94 == llmat_obj3.mMatrix[2][1] &&
86 == llmat_obj3.mMatrix[2][2]);
}
//test case for operator*(const LLVector3 &a, const LLMatrix3 &b)
template<> template<>
void m3math_test_object_t::test<6>()
{
LLMatrix3 llmat_obj1;
LLVector3 llvec(1, 3, 5);
LLVector3 res_vec(0, 0, 0);
LLVector3 llvec1(1, 3, 5);
LLVector3 llvec2(3, 6, 1);
LLVector3 llvec3(4, 6, 9);
llmat_obj1.setRows(llvec1, llvec2, llvec3);
res_vec = llvec * llmat_obj1;
LLVector3 expected_result(30, 51, 53);
ensure("LLMatrix3::operator*(const LLVector3 &a, const LLMatrix3 &b) failed", res_vec == expected_result);
}
//test case for operator*(const LLVector3d &a, const LLMatrix3 &b)
template<> template<>
void m3math_test_object_t::test<7>()
{
LLMatrix3 llmat_obj1;
LLVector3d llvec3d1;
LLVector3d llvec3d2(0, 3, 4);
LLVector3 llvec1(1, 3, 5);
LLVector3 llvec2(3, 2, 1);
LLVector3 llvec3(4, 6, 0);
llmat_obj1.setRows(llvec1, llvec2, llvec3);
llvec3d1 = llvec3d2 * llmat_obj1;
LLVector3d expected_result(25, 30, 3);
ensure("LLMatrix3::operator*(const LLVector3 &a, const LLMatrix3 &b) failed", llvec3d1 == expected_result);
}
// test case for operator==(const LLMatrix3 &a, const LLMatrix3 &b)
template<> template<>
void m3math_test_object_t::test<8>()
{
LLMatrix3 llmat_obj1;
LLMatrix3 llmat_obj2;
LLVector3 llvec1(1, 3, 5);
LLVector3 llvec2(3, 6, 1);
LLVector3 llvec3(4, 6, 9);
llmat_obj1.setRows(llvec1, llvec2, llvec3);
llmat_obj2.setRows(llvec1, llvec2, llvec3);
ensure("LLMatrix3::operator==(const LLMatrix3 &a, const LLMatrix3 &b) failed", llmat_obj1 == llmat_obj2);
llmat_obj2.setRows(llvec2, llvec2, llvec3);
ensure("LLMatrix3::operator!=(const LLMatrix3 &a, const LLMatrix3 &b) failed", llmat_obj1 != llmat_obj2);
}
//test case for quaternion() fn.
template<> template<>
void m3math_test_object_t::test<9>()
{
LLMatrix3 llmat_obj1;
LLQuaternion llmat_quat;
LLVector3 llmat1(2.0f, 1.0f, 6.0f);
LLVector3 llmat2(1.0f, 1.0f, 3.0f);
LLVector3 llmat3(1.0f, 7.0f, 5.0f);
llmat_obj1.setRows(llmat1, llmat2, llmat3);
llmat_quat = llmat_obj1.quaternion();
ensure("LLMatrix3::quaternion failed ", is_approx_equal(-0.66666669f, llmat_quat.mQ[0]) &&
is_approx_equal(-0.83333337f, llmat_quat.mQ[1]) &&
is_approx_equal(0.0f, llmat_quat.mQ[2]) &&
is_approx_equal(1.5f, llmat_quat.mQ[3]));
}
//test case for transpose() fn.
template<> template<>
void m3math_test_object_t::test<10>()
{
LLMatrix3 llmat_obj;
LLVector3 llvec1(1, 2, 3);
LLVector3 llvec2(3, 2, 1);
LLVector3 llvec3(2, 2, 2);
llmat_obj.setRows(llvec1, llvec2, llvec3);
llmat_obj.transpose();
LLVector3 resllvec1(1, 3, 2);
LLVector3 resllvec2(2, 2, 2);
LLVector3 resllvec3(3, 1, 2);
LLMatrix3 expectedllmat_obj;
expectedllmat_obj.setRows(resllvec1, resllvec2, resllvec3);
ensure("LLMatrix3::transpose failed ", llmat_obj == expectedllmat_obj);
}
//test case for determinant() fn.
template<> template<>
void m3math_test_object_t::test<11>()
{
LLMatrix3 llmat_obj1;
LLVector3 llvec1(1, 2, 3);
LLVector3 llvec2(3, 2, 1);
LLVector3 llvec3(2, 2, 2);
llmat_obj1.setRows(llvec1, llvec2, llvec3);
ensure("LLMatrix3::determinant failed ", 0.0f == llmat_obj1.determinant());
}
//test case for orthogonalize() fn.
template<> template<>
void m3math_test_object_t::test<12>()
{
LLMatrix3 llmat_obj;
LLVector3 llvec1(1, 4, 3);
LLVector3 llvec2(1, 2, 0);
LLVector3 llvec3(2, 4, 2);
llmat_obj.setRows(llvec1, llvec2, llvec3);
llmat_obj.orthogonalize();
ensure("LLMatrix3::orthogonalize failed ", is_approx_equal(0.19611613f, llmat_obj.mMatrix[0][0]) &&
is_approx_equal(0.78446454f, llmat_obj.mMatrix[0][1]) &&
is_approx_equal(0.58834839f, llmat_obj.mMatrix[0][2]) &&
is_approx_equal(0.47628206f, llmat_obj.mMatrix[1][0]) &&
is_approx_equal(0.44826555f, llmat_obj.mMatrix[1][1]) &&
is_approx_equal(-0.75644791f, llmat_obj.mMatrix[1][2]) &&
is_approx_equal(-0.85714287f, llmat_obj.mMatrix[2][0]) &&
is_approx_equal(0.42857143f, llmat_obj.mMatrix[2][1]) &&
is_approx_equal(-0.28571427f, llmat_obj.mMatrix[2][2]));
}
//test case for adjointTranspose() fn.
template<> template<>
void m3math_test_object_t::test<13>()
{
LLMatrix3 llmat_obj;
LLVector3 llvec1(3, 2, 1);
LLVector3 llvec2(6, 2, 1);
LLVector3 llvec3(3, 6, 8);
llmat_obj.setRows(llvec1, llvec2, llvec3);
llmat_obj.adjointTranspose();
ensure("LLMatrix3::adjointTranspose failed ", 10 == llmat_obj.mMatrix[0][0] &&
-45 == llmat_obj.mMatrix[1][0] &&
30 == llmat_obj.mMatrix[2][0] &&
-10 == llmat_obj.mMatrix[0][1] &&
21 == llmat_obj.mMatrix[1][1] &&
-12 == llmat_obj.mMatrix[2][1] &&
0 == llmat_obj.mMatrix[0][2] &&
3 == llmat_obj.mMatrix[1][2] &&
-6 == llmat_obj.mMatrix[2][2]);
}
/* TBD: Need to add test cases for getEulerAngles() and setRot() functions */
}

File diff suppressed because it is too large Load Diff

726
indra/test/math.cpp Normal file
View File

@@ -0,0 +1,726 @@
/**
* @file math.cpp
* @author Phoenix
* @date 2005-09-26
* @brief Tests for the llmath library.
*
* $LicenseInfo:firstyear=2005&license=viewergpl$
*
* Copyright (c) 2005-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "lltut.h"
#include "llcrc.h"
#include "llline.h"
#include "llmath.h"
#include "llrand.h"
#include "llsphere.h"
#include "lluuid.h"
#include "v3math.h"
namespace tut
{
struct math_data
{
};
typedef test_group<math_data> math_test;
typedef math_test::object math_object;
tut::math_test tm("basic_linden_math");
template<> template<>
void math_object::test<1>()
{
S32 val = 89543;
val = llabs(val);
ensure("integer absolute value 1", (89543 == val));
val = -500;
val = llabs(val);
ensure("integer absolute value 2", (500 == val));
}
template<> template<>
void math_object::test<2>()
{
F32 val = -2583.4f;
val = llabs(val);
ensure("float absolute value 1", (2583.4f == val));
val = 430903.f;
val = llabs(val);
ensure("float absolute value 2", (430903.f == val));
}
template<> template<>
void math_object::test<3>()
{
F64 val = 387439393.987329839;
val = llabs(val);
ensure("double absolute value 1", (387439393.987329839 == val));
val = -8937843.9394878;
val = llabs(val);
ensure("double absolute value 2", (8937843.9394878 == val));
}
template<> template<>
void math_object::test<4>()
{
F32 val = 430903.9f;
S32 val1 = lltrunc(val);
ensure("float truncate value 1", (430903 == val1));
val = -2303.9f;
val1 = lltrunc(val);
ensure("float truncate value 2", (-2303 == val1));
}
template<> template<>
void math_object::test<5>()
{
F64 val = 387439393.987329839 ;
S32 val1 = lltrunc(val);
ensure("float truncate value 1", (387439393 == val1));
val = -387439393.987329839;
val1 = lltrunc(val);
ensure("float truncate value 2", (-387439393 == val1));
}
template<> template<>
void math_object::test<6>()
{
F32 val = 430903.2f;
S32 val1 = llfloor(val);
ensure("float llfloor value 1", (430903 == val1));
val = -430903.9f;
val1 = llfloor(val);
ensure("float llfloor value 2", (-430904 == val1));
}
template<> template<>
void math_object::test<7>()
{
F32 val = 430903.2f;
S32 val1 = llceil(val);
ensure("float llceil value 1", (430904 == val1));
val = -430903.9f;
val1 = llceil(val);
ensure("float llceil value 2", (-430903 == val1));
}
template<> template<>
void math_object::test<8>()
{
F32 val = 430903.2f;
S32 val1 = llround(val);
ensure("float llround value 1", (430903 == val1));
val = -430903.9f;
val1 = llround(val);
ensure("float llround value 2", (-430904 == val1));
}
template<> template<>
void math_object::test<9>()
{
F32 val = 430905.2654f, nearest = 100.f;
val = llround(val, nearest);
ensure("float llround value 1", (430900 == val));
val = -430905.2654f, nearest = 10.f;
val = llround(val, nearest);
ensure("float llround value 1", (-430910 == val));
}
template<> template<>
void math_object::test<10>()
{
F64 val = 430905.2654, nearest = 100.0;
val = llround(val, nearest);
ensure("double llround value 1", (430900 == val));
val = -430905.2654, nearest = 10.0;
val = llround(val, nearest);
ensure("double llround value 1", (-430910.00000 == val));
}
template<> template<>
void math_object::test<11>()
{
const F32 F_PI = 3.1415926535897932384626433832795f;
F32 angle = 3506.f;
angle = llsimple_angle(angle);
ensure("llsimple_angle value 1", (angle <=F_PI && angle >= -F_PI));
angle = -431.f;
angle = llsimple_angle(angle);
ensure("llsimple_angle value 1", (angle <=F_PI && angle >= -F_PI));
}
}
namespace tut
{
struct uuid_data
{
LLUUID id;
};
typedef test_group<uuid_data> uuid_test;
typedef uuid_test::object uuid_object;
tut::uuid_test tu("uuid");
template<> template<>
void uuid_object::test<1>()
{
ensure("uuid null", id.isNull());
id.generate();
ensure("generate not null", id.notNull());
id.setNull();
ensure("set null", id.isNull());
}
template<> template<>
void uuid_object::test<2>()
{
id.generate();
LLUUID a(id);
ensure_equals("copy equal", id, a);
a.generate();
ensure_not_equals("generate not equal", id, a);
a = id;
ensure_equals("assignment equal", id, a);
}
template<> template<>
void uuid_object::test<3>()
{
id.generate();
LLUUID copy(id);
LLUUID mask;
mask.generate();
copy ^= mask;
ensure_not_equals("mask not equal", id, copy);
copy ^= mask;
ensure_equals("mask back", id, copy);
}
template<> template<>
void uuid_object::test<4>()
{
id.generate();
std::string id_str = id.asString();
LLUUID copy(id_str.c_str());
ensure_equals("string serialization", id, copy);
}
}
namespace tut
{
struct crc_data
{
};
typedef test_group<crc_data> crc_test;
typedef crc_test::object crc_object;
tut::crc_test tc("crc");
template<> template<>
void crc_object::test<1>()
{
/* Test buffer update and individual char update */
const char TEST_BUFFER[] = "hello &#$)$&Nd0";
LLCRC c1, c2;
c1.update((U8*)TEST_BUFFER, sizeof(TEST_BUFFER) - 1);
char* rh = (char*)TEST_BUFFER;
while(*rh != '\0')
{
c2.update(*rh);
++rh;
}
ensure_equals("crc update 1", c1.getCRC(), c2.getCRC());
}
template<> template<>
void crc_object::test<2>()
{
/* Test mixing of buffer and individual char update */
const char TEST_BUFFER1[] = "Split Buffer one $^%$%#@$";
const char TEST_BUFFER2[] = "Split Buffer two )(8723#5dsds";
LLCRC c1, c2;
c1.update((U8*)TEST_BUFFER1, sizeof(TEST_BUFFER1) - 1);
char* rh = (char*)TEST_BUFFER2;
while(*rh != '\0')
{
c1.update(*rh);
++rh;
}
rh = (char*)TEST_BUFFER1;
while(*rh != '\0')
{
c2.update(*rh);
++rh;
}
c2.update((U8*)TEST_BUFFER2, sizeof(TEST_BUFFER2) - 1);
ensure_equals("crc update 2", c1.getCRC(), c2.getCRC());
}
}
namespace tut
{
struct sphere_data
{
};
typedef test_group<sphere_data> sphere_test;
typedef sphere_test::object sphere_object;
tut::sphere_test tsphere("LLSphere");
template<> template<>
void sphere_object::test<1>()
{
// test LLSphere::contains() and ::overlaps()
S32 number_of_tests = 10;
for (S32 test = 0; test < number_of_tests; ++test)
{
LLVector3 first_center(1.f, 1.f, 1.f);
F32 first_radius = 3.f;
LLSphere first_sphere( first_center, first_radius );
F32 half_millimeter = 0.0005f;
LLVector3 direction( ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f);
direction.normalize();
F32 distance = ll_frand(first_radius - 2.f * half_millimeter);
LLVector3 second_center = first_center + distance * direction;
F32 second_radius = first_radius - distance - half_millimeter;
LLSphere second_sphere( second_center, second_radius );
ensure("first sphere should contain the second", first_sphere.contains(second_sphere));
ensure("first sphere should overlap the second", first_sphere.overlaps(second_sphere));
distance = first_radius + ll_frand(first_radius);
second_center = first_center + distance * direction;
second_radius = distance - first_radius + half_millimeter;
second_sphere.set( second_center, second_radius );
ensure("first sphere should NOT contain the second", !first_sphere.contains(second_sphere));
ensure("first sphere should overlap the second", first_sphere.overlaps(second_sphere));
distance = first_radius + ll_frand(first_radius) + half_millimeter;
second_center = first_center + distance * direction;
second_radius = distance - first_radius - half_millimeter;
second_sphere.set( second_center, second_radius );
ensure("first sphere should NOT contain the second", !first_sphere.contains(second_sphere));
ensure("first sphere should NOT overlap the second", !first_sphere.overlaps(second_sphere));
}
}
template<> template<>
void sphere_object::test<2>()
{
// test LLSphere::getBoundingSphere()
S32 number_of_tests = 100;
S32 number_of_spheres = 10;
F32 sphere_center_range = 32.f;
F32 sphere_radius_range = 5.f;
for (S32 test = 0; test < number_of_tests; ++test)
{
// gegnerate a bunch of random sphere
std::vector< LLSphere > sphere_list;
for (S32 sphere_count=0; sphere_count < number_of_spheres; ++sphere_count)
{
LLVector3 direction( ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f);
direction.normalize();
F32 distance = ll_frand(sphere_center_range);
LLVector3 center = distance * direction;
F32 radius = ll_frand(sphere_radius_range);
LLSphere sphere( center, radius );
sphere_list.push_back(sphere);
}
// compute the bounding sphere
LLSphere bounding_sphere = LLSphere::getBoundingSphere(sphere_list);
// make sure all spheres are inside the bounding sphere
{
std::vector< LLSphere >::const_iterator sphere_itr;
for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr)
{
ensure("sphere should be contained by the bounding sphere", bounding_sphere.contains(*sphere_itr));
}
}
// TODO -- improve LLSphere::getBoundingSphere() to the point where
// we can reduce the 'expansion' in the two tests below to about
// 2 mm or less
F32 expansion = 0.005f;
// move all spheres out a little bit
// and count how many are NOT contained
{
std::vector< LLVector3 > uncontained_directions;
std::vector< LLSphere >::iterator sphere_itr;
for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr)
{
LLVector3 direction = sphere_itr->getCenter() - bounding_sphere.getCenter();
direction.normalize();
sphere_itr->setCenter( sphere_itr->getCenter() + expansion * direction );
if (! bounding_sphere.contains( *sphere_itr ) )
{
uncontained_directions.push_back(direction);
}
}
ensure("when moving spheres out there should be at least two uncontained spheres",
uncontained_directions.size() > 1);
/* TODO -- when the bounding sphere algorithm is improved we can open up this test
* at the moment it occasionally fails when the sphere collection is tight and small
* (2 meters or less)
if (2 == uncontained_directions.size() )
{
// if there were only two uncontained spheres then
// the two directions should be nearly opposite
F32 dir_dot = uncontained_directions[0] * uncontained_directions[1];
ensure("two uncontained spheres should lie opposite the bounding center", dir_dot < -0.95f);
}
*/
}
// compute the new bounding sphere
bounding_sphere = LLSphere::getBoundingSphere(sphere_list);
// increase the size of all spheres a little bit
// and count how many are NOT contained
{
std::vector< LLVector3 > uncontained_directions;
std::vector< LLSphere >::iterator sphere_itr;
for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr)
{
LLVector3 direction = sphere_itr->getCenter() - bounding_sphere.getCenter();
direction.normalize();
sphere_itr->setRadius( sphere_itr->getRadius() + expansion );
if (! bounding_sphere.contains( *sphere_itr ) )
{
uncontained_directions.push_back(direction);
}
}
ensure("when boosting sphere radii there should be at least two uncontained spheres",
uncontained_directions.size() > 1);
/* TODO -- when the bounding sphere algorithm is improved we can open up this test
* at the moment it occasionally fails when the sphere collection is tight and small
* (2 meters or less)
if (2 == uncontained_directions.size() )
{
// if there were only two uncontained spheres then
// the two directions should be nearly opposite
F32 dir_dot = uncontained_directions[0] * uncontained_directions[1];
ensure("two uncontained spheres should lie opposite the bounding center", dir_dot < -0.95f);
}
*/
}
}
}
}
namespace tut
{
F32 SMALL_RADIUS = 1.0f;
F32 MEDIUM_RADIUS = 5.0f;
F32 LARGE_RADIUS = 10.0f;
struct line_data
{
};
typedef test_group<line_data> line_test;
typedef line_test::object line_object;
tut::line_test tline("LLLine");
template<> template<>
void line_object::test<1>()
{
// this is a test for LLLine::intersects(point) which returns TRUE
// if the line passes within some tolerance of point
// these tests will have some floating point error,
// so we need to specify how much error is ok
F32 allowable_relative_error = 0.00001f;
S32 number_of_tests = 100;
for (S32 test = 0; test < number_of_tests; ++test)
{
// generate some random point to be on the line
LLVector3 point_on_line( ll_frand(2.f) - 1.f,
ll_frand(2.f) - 1.f,
ll_frand(2.f) - 1.f);
point_on_line.normalize();
point_on_line *= ll_frand(LARGE_RADIUS);
// generate some random point to "intersect"
LLVector3 random_direction ( ll_frand(2.f) - 1.f,
ll_frand(2.f) - 1.f,
ll_frand(2.f) - 1.f);
random_direction.normalize();
LLVector3 random_offset( ll_frand(2.f) - 1.f,
ll_frand(2.f) - 1.f,
ll_frand(2.f) - 1.f);
random_offset.normalize();
random_offset *= ll_frand(SMALL_RADIUS);
LLVector3 point = point_on_line + MEDIUM_RADIUS * random_direction
+ random_offset;
// compute the axis of approach (a unit vector between the points)
LLVector3 axis_of_approach = point - point_on_line;
axis_of_approach.normalize();
// compute the direction of the the first line (perp to axis_of_approach)
LLVector3 first_dir( ll_frand(2.f) - 1.f,
ll_frand(2.f) - 1.f,
ll_frand(2.f) - 1.f);
first_dir.normalize();
F32 dot = first_dir * axis_of_approach;
first_dir -= dot * axis_of_approach; // subtract component parallel to axis
first_dir.normalize();
// construct the line
LLVector3 another_point_on_line = point_on_line + ll_frand(LARGE_RADIUS) * first_dir;
LLLine line(another_point_on_line, point_on_line);
// test that the intersection point is within MEDIUM_RADIUS + SMALL_RADIUS
F32 test_radius = MEDIUM_RADIUS + SMALL_RADIUS;
test_radius += (LARGE_RADIUS * allowable_relative_error);
ensure("line should pass near intersection point", line.intersects(point, test_radius));
test_radius = allowable_relative_error * (point - point_on_line).length();
ensure("line should intersect point used to define it", line.intersects(point_on_line, test_radius));
}
}
template<> template<>
void line_object::test<2>()
{
/*
These tests fail intermittently on all platforms - see DEV-16600
Commenting this out until dev has time to investigate.
// this is a test for LLLine::nearestApproach(LLLIne) method
// which computes the point on a line nearest another line
// these tests will have some floating point error,
// so we need to specify how much error is ok
// TODO -- make nearestApproach() algorithm more accurate so
// we can tighten the allowable_error. Most tests are tighter
// than one milimeter, however when doing randomized testing
// you can walk into inaccurate cases.
F32 allowable_relative_error = 0.001f;
S32 number_of_tests = 100;
for (S32 test = 0; test < number_of_tests; ++test)
{
// generate two points to be our known nearest approaches
LLVector3 some_point( ll_frand(2.f) - 1.f,
ll_frand(2.f) - 1.f,
ll_frand(2.f) - 1.f);
some_point.normalize();
some_point *= ll_frand(LARGE_RADIUS);
LLVector3 another_point( ll_frand(2.f) - 1.f,
ll_frand(2.f) - 1.f,
ll_frand(2.f) - 1.f);
another_point.normalize();
another_point *= ll_frand(LARGE_RADIUS);
// compute the axis of approach (a unit vector between the points)
LLVector3 axis_of_approach = another_point - some_point;
axis_of_approach.normalize();
// compute the direction of the the first line (perp to axis_of_approach)
LLVector3 first_dir( ll_frand(2.f) - 1.f,
ll_frand(2.f) - 1.f,
ll_frand(2.f) - 1.f);
F32 dot = first_dir * axis_of_approach;
first_dir -= dot * axis_of_approach; // subtract component parallel to axis
first_dir.normalize(); // normalize
// compute the direction of the the second line
LLVector3 second_dir( ll_frand(2.f) - 1.f,
ll_frand(2.f) - 1.f,
ll_frand(2.f) - 1.f);
dot = second_dir * axis_of_approach;
second_dir -= dot * axis_of_approach;
second_dir.normalize();
// make sure the lines aren't too parallel,
dot = fabsf(first_dir * second_dir);
if (dot > 0.99f)
{
// skip this test, we're not interested in testing
// the intractible cases
continue;
}
// construct the lines
LLVector3 first_point = some_point + ll_frand(LARGE_RADIUS) * first_dir;
LLLine first_line(first_point, some_point);
LLVector3 second_point = another_point + ll_frand(LARGE_RADIUS) * second_dir;
LLLine second_line(second_point, another_point);
// compute the points of nearest approach
LLVector3 some_computed_point = first_line.nearestApproach(second_line);
LLVector3 another_computed_point = second_line.nearestApproach(first_line);
// compute the error
F32 first_error = (some_point - some_computed_point).length();
F32 scale = llmax((some_point - another_point).length(), some_point.length());
scale = llmax(scale, another_point.length());
scale = llmax(scale, 1.f);
F32 first_relative_error = first_error / scale;
F32 second_error = (another_point - another_computed_point).length();
F32 second_relative_error = second_error / scale;
//if (first_relative_error > allowable_relative_error)
//{
// std::cout << "first_error = " << first_error
// << " first_relative_error = " << first_relative_error
// << " scale = " << scale
// << " dir_dot = " << (first_dir * second_dir)
// << std::endl;
//}
//if (second_relative_error > allowable_relative_error)
//{
// std::cout << "second_error = " << second_error
// << " second_relative_error = " << second_relative_error
// << " scale = " << scale
// << " dist = " << (some_point - another_point).length()
// << " dir_dot = " << (first_dir * second_dir)
// << std::endl;
//}
// test that the errors are small
ensure("first line should accurately compute its closest approach",
first_relative_error <= allowable_relative_error);
ensure("second line should accurately compute its closest approach",
second_relative_error <= allowable_relative_error);
}
*/
}
F32 ALMOST_PARALLEL = 0.99f;
template<> template<>
void line_object::test<3>()
{
// this is a test for LLLine::getIntersectionBetweenTwoPlanes() method
// first some known tests
LLLine xy_plane(LLVector3(0.f, 0.f, 2.f), LLVector3(0.f, 0.f, 3.f));
LLLine yz_plane(LLVector3(2.f, 0.f, 0.f), LLVector3(3.f, 0.f, 0.f));
LLLine zx_plane(LLVector3(0.f, 2.f, 0.f), LLVector3(0.f, 3.f, 0.f));
LLLine x_line;
LLLine y_line;
LLLine z_line;
bool x_success = LLLine::getIntersectionBetweenTwoPlanes(x_line, xy_plane, zx_plane);
bool y_success = LLLine::getIntersectionBetweenTwoPlanes(y_line, yz_plane, xy_plane);
bool z_success = LLLine::getIntersectionBetweenTwoPlanes(z_line, zx_plane, yz_plane);
ensure("xy and zx planes should intersect", x_success);
ensure("yz and xy planes should intersect", y_success);
ensure("zx and yz planes should intersect", z_success);
LLVector3 direction = x_line.getDirection();
ensure("x_line should be parallel to x_axis", fabs(direction.mV[VX]) == 1.f
&& 0.f == direction.mV[VY]
&& 0.f == direction.mV[VZ] );
direction = y_line.getDirection();
ensure("y_line should be parallel to y_axis", 0.f == direction.mV[VX]
&& fabs(direction.mV[VY]) == 1.f
&& 0.f == direction.mV[VZ] );
direction = z_line.getDirection();
ensure("z_line should be parallel to z_axis", 0.f == direction.mV[VX]
&& 0.f == direction.mV[VY]
&& fabs(direction.mV[VZ]) == 1.f );
// next some random tests
F32 allowable_relative_error = 0.0001f;
S32 number_of_tests = 20;
for (S32 test = 0; test < number_of_tests; ++test)
{
// generate the known line
LLVector3 some_point( ll_frand(2.f) - 1.f,
ll_frand(2.f) - 1.f,
ll_frand(2.f) - 1.f);
some_point.normalize();
some_point *= ll_frand(LARGE_RADIUS);
LLVector3 another_point( ll_frand(2.f) - 1.f,
ll_frand(2.f) - 1.f,
ll_frand(2.f) - 1.f);
another_point.normalize();
another_point *= ll_frand(LARGE_RADIUS);
LLLine known_intersection(some_point, another_point);
// compute a plane that intersect the line
LLVector3 point_on_plane( ll_frand(2.f) - 1.f,
ll_frand(2.f) - 1.f,
ll_frand(2.f) - 1.f);
point_on_plane.normalize();
point_on_plane *= ll_frand(LARGE_RADIUS);
LLVector3 plane_normal = (point_on_plane - some_point) % known_intersection.getDirection();
plane_normal.normalize();
LLLine first_plane(point_on_plane, point_on_plane + plane_normal);
// compute a different plane that intersect the line
LLVector3 point_on_different_plane( ll_frand(2.f) - 1.f,
ll_frand(2.f) - 1.f,
ll_frand(2.f) - 1.f);
point_on_different_plane.normalize();
point_on_different_plane *= ll_frand(LARGE_RADIUS);
LLVector3 different_plane_normal = (point_on_different_plane - another_point) % known_intersection.getDirection();
different_plane_normal.normalize();
LLLine second_plane(point_on_different_plane, point_on_different_plane + different_plane_normal);
if (fabs(plane_normal * different_plane_normal) > ALMOST_PARALLEL)
{
// the two planes are approximately parallel, so we won't test this case
continue;
}
LLLine measured_intersection;
bool success = LLLine::getIntersectionBetweenTwoPlanes(
measured_intersection,
first_plane,
second_plane);
ensure("plane intersection should succeed", success);
F32 dot = fabs(known_intersection.getDirection() * measured_intersection.getDirection());
ensure("measured intersection should be parallel to known intersection",
dot > ALMOST_PARALLEL);
ensure("measured intersection should pass near known point",
measured_intersection.intersects(some_point, LARGE_RADIUS * allowable_relative_error));
}
}
}

154
indra/test/message_tut.cpp Normal file
View File

@@ -0,0 +1,154 @@
/**
* @file lldatapacker_tut.cpp
* @date 2007-04
* @brief LLDataPacker test cases.
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "lltut.h"
#include "llapr.h"
#include "llmessageconfig.h"
#include "llsdserialize.h"
#include "llversionserver.h"
#include "message.h"
#include "message_prehash.h"
namespace
{
struct Response : public LLHTTPNode::Response
{
virtual void result(const LLSD&) {}
virtual void status(S32 code, const std::string& message)
{
mStatus = code;
}
virtual void extendedResult(S32 code, const std::string& message, const LLSD& headers) { }
S32 mStatus;
};
}
namespace tut
{
struct LLMessageSystemTestData
{
std::string mTestConfigDir;
std::string mSep;
LLMessageSystemTestData()
{
static bool init = false;
if(!init)
{
ll_init_apr();
//init_prehash_data();
init = true;
}
const F32 circuit_heartbeat_interval=5;
const F32 circuit_timeout=100;
// currently test disconnected message system
start_messaging_system("notafile", 13035,
LL_VERSION_MAJOR,
LL_VERSION_MINOR,
LL_VERSION_PATCH,
FALSE,
"notasharedsecret",
NULL,
false,
circuit_heartbeat_interval,
circuit_timeout
);
// generate temp dir
std::ostringstream ostr;
#if LL_WINDOWS
mSep = "\\";
ostr << "C:" << mSep;
#else
mSep = "/";
ostr << mSep << "tmp" << mSep;
#endif
LLUUID random;
random.generate();
ostr << "message-test-" << random;
mTestConfigDir = ostr.str();
LLFile::mkdir(mTestConfigDir);
writeConfigFile(LLSD());
LLMessageConfig::initClass("simulator", ostr.str());
}
~LLMessageSystemTestData()
{
// not end_messaging_system()
delete gMessageSystem;
gMessageSystem = NULL;
// rm contents of temp dir
std::ostringstream ostr;
ostr << mTestConfigDir << mSep << "message.xml";
int rmfile = LLFile::remove(ostr.str());
ensure_equals("rmfile value", rmfile, 0);
// rm temp dir
int rmdir = LLFile::rmdir(mTestConfigDir);
ensure_equals("rmdir value", rmdir, 0);
}
void writeConfigFile(const LLSD& config)
{
std::ostringstream ostr;
ostr << mTestConfigDir << mSep << "message.xml";
llofstream file(ostr.str());
if (file.is_open())
{
LLSDSerialize::toPrettyXML(config, file);
}
file.close();
}
};
typedef test_group<LLMessageSystemTestData> LLMessageSystemTestGroup;
typedef LLMessageSystemTestGroup::object LLMessageSystemTestObject;
LLMessageSystemTestGroup messageTestGroup("LLMessageSystem");
template<> template<>
void LLMessageSystemTestObject::test<1>()
// dispatch unknown message
{
const char* name = "notamessasge";
const LLSD message;
const LLPointer<Response> response = new Response();
gMessageSystem->dispatch(name, message, response);
ensure_equals(response->mStatus, 404);
}
}

View File

@@ -0,0 +1,89 @@
/**
* @file mock_http_client.cpp
* @brief Framework for testing HTTP requests
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llsdhttpserver.h"
#include "lliohttpserver.h"
namespace tut
{
class SuccessNode : public LLHTTPNode
{
public:
void get(ResponsePtr r, const LLSD& context) const
{
LLSD result;
result["state"] = "complete";
result["test"] = "test";
r->result(result);
}
void post(ResponsePtr r, const LLSD& context, const LLSD& input) const
{
LLSD result;
result["state"] = "complete";
result["test"] = "test";
r->result(result);
}
};
class ErrorNode : public LLHTTPNode
{
public:
void get(ResponsePtr r, const LLSD& context) const
{ r->status(599, "Intentional error"); }
void post(ResponsePtr r, const LLSD& context, const LLSD& input) const
{ r->status(input["status"], input["reason"]); }
};
class TimeOutNode : public LLHTTPNode
{
public:
void get(ResponsePtr r, const LLSD& context) const
{
/* do nothing, the request will eventually time out */
}
};
LLSD storage;
class LLSDStorageNode : public LLHTTPNode
{
public:
LLSD get() const{ return storage; }
LLSD put(const LLSD& value) const{ storage = value; return LLSD(); }
};
LLHTTPRegistration<LLSDStorageNode> gStorageNode("/test/storage");
LLHTTPRegistration<SuccessNode> gSuccessNode("/test/success");
LLHTTPRegistration<ErrorNode> gErrorNode("/test/error");
LLHTTPRegistration<TimeOutNode> gTimeOutNode("/test/timeout");
}

View File

@@ -0,0 +1,197 @@
/**
* @file mock_http_client.cpp
* @brief Framework for testing HTTP requests
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llsdhttpserver.h"
#include "lliohttpserver.h"
#include "llhttpclient.h"
#include "llformat.h"
#include "llpipeutil.h"
#include "llpumpio.h"
namespace tut
{
struct MockHttpClient
{
public:
MockHttpClient()
{
apr_pool_create(&mPool, NULL);
mServerPump = new LLPumpIO(mPool);
mClientPump = new LLPumpIO(mPool);
LLHTTPClient::setPump(*mClientPump);
}
~MockHttpClient()
{
delete mServerPump;
delete mClientPump;
apr_pool_destroy(mPool);
}
void setupTheServer()
{
LLHTTPNode& root = LLIOHTTPServer::create(mPool, *mServerPump, 8888);
LLHTTPStandardServices::useServices();
LLHTTPRegistrar::buildAllServices(root);
}
void runThePump(float timeout = 100.0f)
{
LLTimer timer;
timer.setTimerExpirySec(timeout);
while(!mSawCompleted && !timer.hasExpired())
{
if (mServerPump)
{
mServerPump->pump();
mServerPump->callback();
}
if (mClientPump)
{
mClientPump->pump();
mClientPump->callback();
}
}
}
void killServer()
{
delete mServerPump;
mServerPump = NULL;
}
private:
apr_pool_t* mPool;
LLPumpIO* mServerPump;
LLPumpIO* mClientPump;
protected:
void ensureStatusOK()
{
if (mSawError)
{
std::string msg =
llformat("error() called when not expected, status %d",
mStatus);
fail(msg);
}
}
void ensureStatusError()
{
if (!mSawError)
{
fail("error() wasn't called");
}
}
LLSD getResult()
{
return mResult;
}
protected:
bool mSawError;
U32 mStatus;
std::string mReason;
bool mSawCompleted;
LLSD mResult;
bool mResultDeleted;
class Result : public LLHTTPClient::Responder
{
protected:
Result(MockHttpClient& client)
: mClient(client)
{
}
public:
static boost::intrusive_ptr<Result> build(MockHttpClient& client)
{
return boost::intrusive_ptr<Result>(new Result(client));
}
~Result()
{
mClient.mResultDeleted = true;
}
virtual void error(U32 status, const std::string& reason)
{
mClient.mSawError = true;
mClient.mStatus = status;
mClient.mReason = reason;
}
virtual void result(const LLSD& content)
{
mClient.mResult = content;
}
virtual void completed(
U32 status, const std::string& reason,
const LLSD& content)
{
LLHTTPClient::Responder::completed(status, reason, content);
mClient.mSawCompleted = true;
}
private:
MockHttpClient& mClient;
};
friend class Result;
protected:
void reset()
{
mSawError = false;
mStatus = 0;
mSawCompleted = false;
mResult.clear();
mResultDeleted = false;
}
LLHTTPClient::ResponderPtr newResult()
{
reset();
return Result::build(*this);
}
};
}

View File

@@ -0,0 +1,501 @@
/**
* @file linkability.cpp
* @author andrew@lindenlab.com
* @date 2007-04-23
* @brief Tests for the LLPrimLinkInfo template which computes the linkability of prims
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "lltut.h"
#include "llprimlinkinfo.h"
#include "llrand.h"
// helper function
void randomize_sphere(LLSphere& sphere, F32 center_range, F32 radius_range)
{
F32 radius = ll_frand(2.f * radius_range) - radius_range;
LLVector3 center;
for (S32 i=0; i<3; ++i)
{
center.mV[i] = ll_frand(2.f * center_range) - center_range;
}
sphere.setRadius(radius);
sphere.setCenter(center);
}
// helper function. Same as above with a min and max radius.
void randomize_sphere(LLSphere& sphere, F32 center_range, F32 minimum_radius, F32 maximum_radius)
{
F32 radius = ll_frand(maximum_radius - minimum_radius) + minimum_radius;
LLVector3 center;
for (S32 i=0; i<3; ++i)
{
center.mV[i] = ll_frand(2.f * center_range) - center_range;
}
sphere.setRadius(radius);
sphere.setCenter(center);
}
// helper function
bool random_sort( const LLPrimLinkInfo< S32 >&, const LLPrimLinkInfo< S32 >& b)
{
return (ll_rand(64) < 32);
}
namespace tut
{
struct linkable_data
{
LLPrimLinkInfo<S32> info;
};
typedef test_group<linkable_data> linkable_test;
typedef linkable_test::object linkable_object;
tut::linkable_test wtf("prim linkability");
template<> template<>
void linkable_object::test<1>()
{
// Here we test the boundary of the LLPrimLinkInfo::canLink() method
// between semi-random middle-sized objects.
S32 number_of_tests = 100;
for (S32 test = 0; test < number_of_tests; ++test)
{
// compute the radii that would provide the above max link distance
F32 first_radius = 0.f;
F32 second_radius = 0.f;
// compute a random center for the first sphere
// compute some random max link distance
F32 max_link_span = ll_frand(MAX_OBJECT_SPAN);
if (max_link_span < OBJECT_SPAN_BONUS)
{
max_link_span += OBJECT_SPAN_BONUS;
}
LLVector3 first_center(
ll_frand(2.f * max_link_span) - max_link_span,
ll_frand(2.f * max_link_span) - max_link_span,
ll_frand(2.f * max_link_span) - max_link_span);
// put the second sphere at the right distance from the origin
// such that it is within the max_link_distance of the first
LLVector3 direction(ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f);
direction.normalize();
F32 half_milimeter = 0.0005f;
LLVector3 second_center;
// max_span = 3 * (first_radius + second_radius) + OBJECT_SPAN_BONUS
// make sure they link at short distances
{
second_center = first_center + (OBJECT_SPAN_BONUS - half_milimeter) * direction;
LLPrimLinkInfo<S32> first_info(0, LLSphere(first_center, first_radius) );
LLPrimLinkInfo<S32> second_info(1, LLSphere(second_center, second_radius) );
ensure("these nearby objects should link", first_info.canLink(second_info) );
}
// make sure they fail to link if we move them apart just a little bit
{
second_center = first_center + (OBJECT_SPAN_BONUS + half_milimeter) * direction;
LLPrimLinkInfo<S32> first_info(0, LLSphere(first_center, first_radius) );
LLPrimLinkInfo<S32> second_info(1, LLSphere(second_center, second_radius) );
ensure("these nearby objects should NOT link", !first_info.canLink(second_info) );
}
// make sure the objects link or not at medium distances
{
first_radius = 0.3f * ll_frand(max_link_span - OBJECT_SPAN_BONUS);
// This is the exact second radius that will link at exactly our random max_link_distance
second_radius = ((max_link_span - OBJECT_SPAN_BONUS) / 3.f) - first_radius;
second_center = first_center + (max_link_span - first_radius - second_radius - half_milimeter) * direction;
LLPrimLinkInfo<S32> first_info(0, LLSphere(first_center, first_radius) );
LLPrimLinkInfo<S32> second_info(1, LLSphere(second_center, second_radius) );
ensure("these objects should link", first_info.canLink(second_info) );
}
// make sure they fail to link if we move them apart just a little bit
{
// move the second sphere such that it is a little too far from the first
second_center += (2.f * half_milimeter) * direction;
LLPrimLinkInfo<S32> first_info(0, LLSphere(first_center, first_radius) );
LLPrimLinkInfo<S32> second_info(1, LLSphere(second_center, second_radius) );
ensure("these objects should NOT link", !first_info.canLink(second_info) );
}
// make sure things don't link at far distances
{
second_center = first_center + (MAX_OBJECT_SPAN + 2.f * half_milimeter) * direction;
second_radius = 0.3f * MAX_OBJECT_SPAN;
LLPrimLinkInfo<S32> first_info(0, LLSphere(first_center, first_radius) );
LLPrimLinkInfo<S32> second_info(1, LLSphere(second_center, second_radius) );
ensure("these objects should NOT link", !first_info.canLink(second_info) );
}
}
}
template<> template<>
void linkable_object::test<2>()
{
// Consider a row of eight spheres in a row, each 10m in diameter and centered
// at 10m intervals: 01234567.
F32 radius = 5.f;
F32 spacing = 10.f;
LLVector3 line_direction(ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f);
line_direction.normalize();
LLVector3 first_center(ll_frand(2.f * spacing) -spacing, ll_frand(2.f * spacing) - spacing, ll_frand(2.f * spacing) - spacing);
LLPrimLinkInfo<S32> infos[8];
for (S32 index = 0; index < 8; ++index)
{
LLVector3 center = first_center + ((F32)(index) * spacing) * line_direction;
infos[index].set(index, LLSphere(center, radius));
}
// Max span for 2 spheres of 5m radius is 3 * (5 + 5) + 1 = 31m
// spheres 0&2 have a 30m span (from outside edge to outside edge) and should link
{
LLPrimLinkInfo<S32> root_info = infos[0];
std::list< LLPrimLinkInfo<S32> > info_list;
info_list.push_back(infos[2]);
root_info.mergeLinkableSet(info_list);
S32 prim_count = root_info.getPrimCount();
ensure_equals("0&2 prim count should be 2", prim_count, 2);
ensure_equals("0&2 unlinkable list should have length 0", (S32) info_list.size(), 0);
}
// spheres 0&3 have a 40 meter span and should NOT link outright
{
LLPrimLinkInfo<S32> root_info = infos[0];
std::list< LLPrimLinkInfo<S32> > info_list;
info_list.push_back(infos[3]);
root_info.mergeLinkableSet(info_list);
S32 prim_count = root_info.getPrimCount();
ensure_equals("0&4 prim count should be 1", prim_count, 1);
ensure_equals("0&4 unlinkable list should have length 1", (S32) info_list.size(), 1);
}
// spheres 0-4 should link no matter what order : 01234
// Total span = 50m, 012 link with a r=15.5 giving max span of 3 * (15.5 + 5) + 1 = 62.5, but the cap is 54m
{
LLPrimLinkInfo<S32> root_info = infos[0];
std::list< LLPrimLinkInfo<S32> > info_list;
for (S32 index = 1; index < 5; ++index)
{
info_list.push_back(infos[index]);
}
root_info.mergeLinkableSet(info_list);
S32 prim_count = root_info.getPrimCount();
ensure_equals("01234 prim count should be 5", prim_count, 5);
ensure_equals("01234 unlinkable list should have length 0", (S32) info_list.size(), 0);
}
// spheres 0-5 should link no matter what order : 04321
{
LLPrimLinkInfo<S32> root_info = infos[0];
std::list< LLPrimLinkInfo<S32> > info_list;
for (S32 index = 4; index > 0; --index)
{
info_list.push_back(infos[index]);
}
root_info.mergeLinkableSet(info_list);
S32 prim_count = root_info.getPrimCount();
ensure_equals("04321 prim count should be 5", prim_count, 5);
ensure_equals("04321 unlinkable list should have length 0", (S32) info_list.size(), 0);
}
// spheres 0-4 should link no matter what order : 01423
{
LLPrimLinkInfo<S32> root_info = infos[0];
std::list< LLPrimLinkInfo<S32> > info_list;
info_list.push_back(infos[1]);
info_list.push_back(infos[4]);
info_list.push_back(infos[2]);
info_list.push_back(infos[3]);
root_info.mergeLinkableSet(info_list);
S32 prim_count = root_info.getPrimCount();
ensure_equals("01423 prim count should be 5", prim_count, 5);
ensure_equals("01423 unlinkable list should have length 0", (S32) info_list.size(), 0);
}
// spheres 0-5 should NOT fully link, only 0-4
{
LLPrimLinkInfo<S32> root_info = infos[0];
std::list< LLPrimLinkInfo<S32> > info_list;
for (S32 index = 1; index < 6; ++index)
{
info_list.push_back(infos[index]);
}
root_info.mergeLinkableSet(info_list);
S32 prim_count = root_info.getPrimCount();
ensure_equals("012345 prim count should be 5", prim_count, 5);
ensure_equals("012345 unlinkable list should have length 1", (S32) info_list.size(), 1);
std::list< LLPrimLinkInfo<S32> >::iterator info_itr = info_list.begin();
if (info_itr != info_list.end())
{
// examine the contents of the unlinked info
std::list<S32> unlinked_indecies;
info_itr->getData(unlinked_indecies);
// make sure there is only one index in the unlinked_info
ensure_equals("012345 unlinkable index count should be 1", (S32) unlinked_indecies.size(), 1);
// make sure its value is 6
std::list<S32>::iterator unlinked_index_itr = unlinked_indecies.begin();
S32 unlinkable_index = *unlinked_index_itr;
ensure_equals("012345 unlinkable index should be 5", (S32) unlinkable_index, 5);
}
}
// spheres 0-7 should NOT fully link, only 0-5
{
LLPrimLinkInfo<S32> root_info = infos[0];
std::list< LLPrimLinkInfo<S32> > info_list;
for (S32 index = 1; index < 8; ++index)
{
info_list.push_back(infos[index]);
}
root_info.mergeLinkableSet(info_list);
S32 prim_count = root_info.getPrimCount();
ensure_equals("01234567 prim count should be 5", prim_count, 5);
// Should be 1 linkinfo on unlinkable that has 2 prims
ensure_equals("01234567 unlinkable list should have length 1", (S32) info_list.size(), 1);
std::list< LLPrimLinkInfo<S32> >::iterator info_itr = info_list.begin();
if (info_itr != info_list.end())
{
// make sure there is only one index in the unlinked_info
std::list<S32> unlinked_indecies;
info_itr->getData(unlinked_indecies);
ensure_equals("0123456 unlinkable index count should be 3", (S32) unlinked_indecies.size(), 3);
// make sure its values are 6 and 7
std::list<S32>::iterator unlinked_index_itr = unlinked_indecies.begin();
S32 unlinkable_index = *unlinked_index_itr;
ensure_equals("0123456 first unlinkable index should be 5", (S32) unlinkable_index, 5);
++unlinked_index_itr;
unlinkable_index = *unlinked_index_itr;
ensure_equals("0123456 second unlinkable index should be 6", (S32) unlinkable_index, 6);
++unlinked_index_itr;
unlinkable_index = *unlinked_index_itr;
ensure_equals("0123456 third unlinkable index should be 7", (S32) unlinkable_index, 7);
}
}
}
template<> template<>
void linkable_object::test<3>()
{
// Here we test the link results between an LLPrimLinkInfo and a set of
// randomized LLPrimLinkInfos where the expected results are known.
S32 number_of_tests = 5;
for (S32 test = 0; test < number_of_tests; ++test)
{
// the radii are known
F32 first_radius = 1.f;
F32 second_radius = 2.f;
F32 third_radius = 3.f;
// compute the distances
F32 half_milimeter = 0.0005f;
F32 max_first_second_span = 3.f * (first_radius + second_radius) + OBJECT_SPAN_BONUS;
F32 linkable_distance = max_first_second_span - first_radius - second_radius - half_milimeter;
F32 max_full_span = 3.f * (0.5f * max_first_second_span + third_radius) + OBJECT_SPAN_BONUS;
F32 unlinkable_distance = max_full_span - 0.5f * linkable_distance - third_radius + half_milimeter;
// compute some random directions
LLVector3 first_direction(ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f);
first_direction.normalize();
LLVector3 second_direction(ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f);
second_direction.normalize();
LLVector3 third_direction(ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f);
third_direction.normalize();
// compute the centers
LLVector3 first_center = ll_frand(10.f) * first_direction;
LLVector3 second_center = first_center + ll_frand(linkable_distance) * second_direction;
LLVector3 first_join_center = 0.5f * (first_center + second_center);
LLVector3 third_center = first_join_center + unlinkable_distance * third_direction;
// make sure the second info links and the third does not
{
// initialize the infos
S32 index = 0;
LLPrimLinkInfo<S32> first_info(index++, LLSphere(first_center, first_radius));
LLPrimLinkInfo<S32> second_info(index++, LLSphere(second_center, second_radius));
LLPrimLinkInfo<S32> third_info(index++, LLSphere(third_center, third_radius));
// put the second and third infos in a list
std::list< LLPrimLinkInfo<S32> > info_list;
info_list.push_back(second_info);
info_list.push_back(third_info);
// merge the list with the first_info
first_info.mergeLinkableSet(info_list);
S32 prim_count = first_info.getPrimCount();
ensure_equals("prim count should be 2", prim_count, 2);
ensure_equals("unlinkable list should have length 1", (S32) info_list.size(), 1);
}
// reverse the order and make sure we get the same results
{
// initialize the infos
S32 index = 0;
LLPrimLinkInfo<S32> first_info(index++, LLSphere(first_center, first_radius));
LLPrimLinkInfo<S32> second_info(index++, LLSphere(second_center, second_radius));
LLPrimLinkInfo<S32> third_info(index++, LLSphere(third_center, third_radius));
// build the list in the reverse order
std::list< LLPrimLinkInfo<S32> > info_list;
info_list.push_back(third_info);
info_list.push_back(second_info);
// merge the list with the first_info
first_info.mergeLinkableSet(info_list);
S32 prim_count = first_info.getPrimCount();
ensure_equals("prim count should be 2", prim_count, 2);
ensure_equals("unlinkable list should have length 1", (S32) info_list.size(), 1);
}
}
}
template<> template<>
void linkable_object::test<4>()
{
// Here we test whether linkability is invarient under permutations
// of link order. To do this we generate a bunch of random spheres
// and then try to link them in different ways.
//
// NOTE: the linkability will only be invarient if there is only one
// linkable solution. Multiple solutions will exist if the set of
// candidates are larger than the maximum linkable distance, or more
// numerous than a single linked object can contain. This is easily
// understood by considering a very large set of link candidates,
// and first linking preferentially to the left until linking fails,
// then doing the same to the right -- the final solutions will differ.
// Hence for this test we must generate candidate sets that lie within
// the linkability envelope of a single object.
//
// NOTE: a random set of objects will tend to either be totally linkable
// or totally not. That is, the random orientations that
F32 root_center_range = 0.f;
F32 min_prim_radius = 0.1f;
F32 max_prim_radius = 2.f;
// Linkability is min(MAX_OBJECT_SPAN,3 *( R1 + R2 ) + BONUS)
// 3 * (min_prim_radius + min_prim_radius) + OBJECT_SPAN_BONUS = 6 * min_prim_radius + OBJECT_SPAN_BONUS;
// Use .45 instead of .5 to gaurantee objects are within the minimum span.
F32 child_center_range = 0.45f * ( (6*min_prim_radius) + OBJECT_SPAN_BONUS );
S32 number_of_tests = 100;
S32 number_of_spheres = 10;
S32 number_of_scrambles = 10;
S32 number_of_random_bubble_sorts = 10;
for (S32 test = 0; test < number_of_tests; ++test)
{
LLSphere sphere;
S32 sphere_index = 0;
// build the root piece
randomize_sphere(sphere, root_center_range, min_prim_radius, max_prim_radius);
info.set( sphere_index++, sphere );
// build the unlinked pieces
std::list< LLPrimLinkInfo<S32> > info_list;
for (; sphere_index < number_of_spheres; ++sphere_index)
{
randomize_sphere(sphere, child_center_range, min_prim_radius, max_prim_radius);
LLPrimLinkInfo<S32> child_info( sphere_index, sphere );
info_list.push_back(child_info);
}
// declare the variables used to store the results
std::list<S32> first_linked_list;
{
// the link attempt will modify our original info's, so we
// have to make copies of the originals for testing
LLPrimLinkInfo<S32> test_info( 0, LLSphere(info.getCenter(), 0.5f * info.getDiameter()) );
std::list< LLPrimLinkInfo<S32> > test_list;
test_list.assign(info_list.begin(), info_list.end());
// try to link
test_info.mergeLinkableSet(test_list);
ensure("All prims should link, but did not.",test_list.empty());
// store the results
test_info.getData(first_linked_list);
first_linked_list.sort();
}
// try to link the spheres in various random orders
for (S32 scramble = 0; scramble < number_of_scrambles; ++scramble)
{
LLPrimLinkInfo<S32> test_info(0, LLSphere(info.getCenter(), 0.5f * info.getDiameter()) );
// scramble the order of the info_list
std::list< LLPrimLinkInfo<S32> > test_list;
test_list.assign(info_list.begin(), info_list.end());
for (S32 i = 0; i < number_of_random_bubble_sorts; i++)
{
test_list.sort(random_sort);
}
// try to link
test_info.mergeLinkableSet(test_list);
// get the results
std::list<S32> linked_list;
test_info.getData(linked_list);
linked_list.sort();
ensure_equals("linked set size should be order independent",linked_list.size(),first_linked_list.size());
}
}
}
}

View File

@@ -0,0 +1,229 @@
/**
* @file reflection_tut.cpp
* @date May 2006
* @brief Reflection unit tests.
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "lltut.h"
#include "reflective.h"
#include "metaclasst.h"
#include "metapropertyt.h"
//#include "referencemetaproperty.h"
#include "stdtypes.h"
//#include "reflectivemetapropertyt.h"
namespace tut
{
class TestAggregatedData : public LLReflective
{
public:
TestAggregatedData() {;}
virtual const LLMetaClass& getMetaClass() const;
private:
};
class TestReflectionData : public LLReflective
{
public:
TestReflectionData() : mInt(42), mString("foo"), mNullPtr(NULL), mPtr(new TestAggregatedData()), mRef(*(new TestAggregatedData)) {;}
virtual ~TestReflectionData() {delete mPtr;}
virtual const LLMetaClass& getMetaClass() const;
static U32 getPropertyCount() {return 5;}
private:
friend class LLMetaClassT<TestReflectionData>;
S32 mInt;
std::string mString;
TestAggregatedData* mNullPtr;
TestAggregatedData* mPtr;
TestAggregatedData mObj;
TestAggregatedData& mRef;
};
}
template <>
void LLMetaClassT<tut::TestReflectionData>::reflectProperties(LLMetaClass& meta_class)
{
reflectProperty(meta_class, "mInt", &tut::TestReflectionData::mInt);
reflectProperty(meta_class, "mString", &tut::TestReflectionData::mString);
reflectPtrProperty(meta_class, "mNullPtr", &tut::TestReflectionData::mNullPtr);
reflectPtrProperty(meta_class, "mPtr", &tut::TestReflectionData::mPtr);
reflectProperty(meta_class, "mObj", &tut::TestReflectionData::mObj);
//reflectProperty(meta_class, "mRef", &tut::TestReflectionData::mRef); // AARGH!
}
namespace tut
{
// virtual
const LLMetaClass& TestReflectionData::getMetaClass() const
{
return LLMetaClassT<TestReflectionData>::instance();
}
const LLMetaClass& TestAggregatedData::getMetaClass() const
{
return LLMetaClassT<TestAggregatedData>::instance();
}
}
namespace tut
{
typedef tut::test_group<TestReflectionData> TestReflectionGroup;
typedef TestReflectionGroup::object TestReflectionObject;
TestReflectionGroup gTestReflectionGroup("reflection");
template<> template<>
void TestReflectionObject::test<1>()
{
// Check properties can be found.
const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance();
const LLMetaProperty* null = NULL;
ensure_not_equals(meta_class.findProperty("mInt"), null);
ensure_not_equals(meta_class.findProperty("mString"), null);
}
template<> template<>
void TestReflectionObject::test<2>()
{
// Check non-existent property cannot be found.
const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance();
const LLMetaProperty* null = NULL;
ensure_equals(meta_class.findProperty("foo"), null);
}
template<> template<>
void TestReflectionObject::test<3>()
{
// Check integer property has correct value.
const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance();
ensure_equals(meta_class.findProperty("mInt")->getLLSD(this).asInteger(), 42);
}
template<> template<>
void TestReflectionObject::test<4>()
{
// Check string property has correct value.
const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance();
ensure_equals(meta_class.findProperty("mString")->getLLSD(this).asString(), std::string("foo"));
}
template<> template<>
void TestReflectionObject::test<5>()
{
// Check NULL reference property has correct value.
const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance();
const LLReflective* null = NULL;
ensure_equals(meta_class.findProperty("mNullPtr")->get(this), null);
}
template<> template<>
void TestReflectionObject::test<6>()
{
// Check reference property has correct value.
const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance();
const LLReflective* null = NULL;
const LLReflective* ref = meta_class.findProperty("mPtr")->get(this);
ensure_not_equals(ref, null);
}
template<> template<>
void TestReflectionObject::test<7>()
{
// Check reflective property has correct value.
const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance();
const LLReflective* null = NULL;
const LLReflective* ref = meta_class.findProperty("mObj")->get(this);
ensure_not_equals(ref, null);
}
template<> template<>
void TestReflectionObject::test<8>()
{
// Check property count.
const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance();
ensure_equals(meta_class.getPropertyCount(), TestReflectionData::getPropertyCount());
}
template<> template<>
void TestReflectionObject::test<9>()
{
// Check property iteration.
const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance();
U32 count = 0;
LLMetaClass::PropertyIterator iter;
for(iter = meta_class.beginProperties(); iter != meta_class.endProperties(); ++iter)
{
++count;
}
ensure_equals(count, TestReflectionData::getPropertyCount());
}
template<> template<>
void TestReflectionObject::test<10>()
{
// Check meta classes of different types do not compare equal.
const LLMetaClass* reflection_data_meta_class = &(LLMetaClassT<TestReflectionData>::instance());
const LLMetaClass* aggregated_data_meta_class = &(LLMetaClassT<TestAggregatedData>::instance());
ensure_not_equals(reflection_data_meta_class, aggregated_data_meta_class);
}
template<> template<>
void TestReflectionObject::test<11>()
{
// Check class cast checks.
const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance();
TestAggregatedData* aggregated_data = new TestAggregatedData();
LLMetaClass::PropertyIterator iter;
U32 exception_count = 0;
for(iter = meta_class.beginProperties(); iter != meta_class.endProperties(); ++iter)
{
try
{
const LLMetaProperty* property = (*iter).second;
const LLReflective* reflective = property->get(aggregated_data); // Wrong reflective type, should throw exception.
// useless op to get rid of compiler warning.
reflective = NULL;
}
catch(...)
{
++exception_count;
}
}
ensure_equals(exception_count, getPropertyCount());
}
}

367
indra/test/test.cpp Normal file
View File

@@ -0,0 +1,367 @@
/**
* @file test.cpp
* @author Phoenix
* @date 2005-09-26
* @brief Entry point for the test app.
*
* $LicenseInfo:firstyear=2005&license=viewergpl$
*
* Copyright (c) 2005-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
/**
*
* You can add tests by creating a new cpp file in this directory, and
* rebuilding. There are at most 50 tests per testgroup without a
* little bit of template parameter and makefile tweaking.
*
*/
#include "linden_common.h"
#include "llerrorcontrol.h"
#include "lltut.h"
#include "apr_pools.h"
#include "apr_getopt.h"
extern void ll_init_apr();
// the CTYPE_WORKAROUND is needed for linux dev stations that don't
// have the broken libc6 packages needed by our out-of-date static
// libs (such as libcrypto and libcurl). -- Leviathan 20060113
#ifdef CTYPE_WORKAROUND
# include "ctype_workaround.h"
#endif
namespace tut
{
std::string sSourceDir;
test_runner_singleton runner;
}
class LLTestCallback : public tut::callback
{
public:
LLTestCallback(bool verbose_mode, std::ostream *stream) :
mVerboseMode(verbose_mode),
mTotalTests(0),
mPassedTests(0),
mFailedTests(0),
mSkippedTests(0),
mStream(stream)
{
}
void run_started()
{
//std::cout << "run_started" << std::endl;
}
void test_completed(const tut::test_result& tr)
{
++mTotalTests;
std::ostringstream out;
out << "[" << tr.group << ", " << tr.test << "] ";
switch(tr.result)
{
case tut::test_result::ok:
++mPassedTests;
out << "ok";
break;
case tut::test_result::fail:
++mFailedTests;
out << "fail";
break;
case tut::test_result::ex:
++mFailedTests;
out << "exception";
break;
case tut::test_result::warn:
++mFailedTests;
out << "test destructor throw";
break;
case tut::test_result::term:
++mFailedTests;
out << "abnormal termination";
break;
case tut::test_result::skip:
++mSkippedTests;
out << "skipped known failure";
break;
default:
++mFailedTests;
out << "unknown";
}
if(mVerboseMode || (tr.result != tut::test_result::ok))
{
if(!tr.message.empty())
{
out << ": '" << tr.message << "'";
}
if (mStream)
{
*mStream << out.str() << std::endl;
}
std::cout << out.str() << std::endl;
}
}
void run_completed()
{
if (mStream)
{
run_completed_(*mStream);
}
run_completed_(std::cout);
if (mFailedTests > 0)
{
exit(1);
}
}
private:
void run_completed_(std::ostream &stream)
{
stream << std::endl;
stream << "Total Tests: " << mTotalTests << std::endl;
stream << "Passed Tests: " << mPassedTests << std::endl;
stream << std::endl;
stream << "Total Tests: " << mTotalTests << std::endl;
stream << "Passed Tests: " << mPassedTests << std::endl;
if (mSkippedTests > 0)
{
stream << "Skipped known failures: " << mSkippedTests
<< std::endl;
}
if(mFailedTests > 0)
{
stream << "*********************************" << std::endl;
stream << "Failed Tests: " << mFailedTests << std::endl;
stream << "Please report or fix the problem." << std::endl;
stream << "*********************************" << std::endl;
}
}
protected:
bool mVerboseMode;
int mTotalTests;
int mPassedTests;
int mFailedTests;
int mSkippedTests;
std::ostream *mStream;
};
static const apr_getopt_option_t TEST_CL_OPTIONS[] =
{
{"help", 'h', 0, "Print the help message."},
{"list", 'l', 0, "List available test groups."},
{"verbose", 'v', 0, "Verbose output."},
{"group", 'g', 1, "Run test group specified by option argument."},
{"output", 'o', 1, "Write output to the named file."},
{"sourcedir", 's', 1, "Project source file directory from CMake."},
{"touch", 't', 1, "Touch the given file if all tests succeed"},
{"wait", 'w', 0, "Wait for input before exit."},
{"debug", 'd', 0, "Emit full debug logs."},
{0, 0, 0, 0}
};
void stream_usage(std::ostream& s, const char* app)
{
s << "Usage: " << app << " [OPTIONS]" << std::endl
<< std::endl;
s << "This application runs the unit tests." << std::endl << std::endl;
s << "Options: " << std::endl;
const apr_getopt_option_t* option = &TEST_CL_OPTIONS[0];
while(option->name)
{
s << " ";
s << " -" << (char)option->optch << ", --" << option->name
<< std::endl;
s << "\t" << option->description << std::endl << std::endl;
++option;
}
s << "Examples:" << std::endl;
s << " " << app << " --verbose" << std::endl;
s << "\tRun all the tests and report all results." << std::endl;
s << " " << app << " --list" << std::endl;
s << "\tList all available test groups." << std::endl;
s << " " << app << " --group=uuid" << std::endl;
s << "\tRun the test group 'uuid'." << std::endl;
}
void stream_groups(std::ostream& s, const char* app)
{
s << "Registered test groups:" << std::endl;
tut::groupnames gl = tut::runner.get().list_groups();
tut::groupnames::const_iterator it = gl.begin();
tut::groupnames::const_iterator end = gl.end();
for(; it != end; ++it)
{
s << " " << *(it) << std::endl;
}
}
void wouldHaveCrashed(const std::string& message)
{
tut::fail("llerrs message: " + message);
}
int main(int argc, char **argv)
{
LLError::initForApplication(".");
LLError::setFatalFunction(wouldHaveCrashed);
LLError::setDefaultLevel(LLError::LEVEL_ERROR);
//< *TODO: should come from error config file. Note that we
// have a command line option that sets this to debug.
#ifdef CTYPE_WORKAROUND
ctype_workaround();
#endif
ll_init_apr();
apr_pool_t* pool = NULL;
if(APR_SUCCESS != apr_pool_create(&pool, NULL))
{
std::cerr << "Unable to initialize pool" << std::endl;
return 1;
}
apr_getopt_t* os = NULL;
if(APR_SUCCESS != apr_getopt_init(&os, pool, argc, argv))
{
std::cerr << "Unable to pool" << std::endl;
return 1;
}
// values used for controlling application
bool verbose_mode = false;
bool wait_at_exit = false;
std::string test_group;
// values use for options parsing
apr_status_t apr_err;
const char* opt_arg = NULL;
int opt_id = 0;
std::ofstream *output = NULL;
const char *touch = NULL;
while(true)
{
apr_err = apr_getopt_long(os, TEST_CL_OPTIONS, &opt_id, &opt_arg);
if(APR_STATUS_IS_EOF(apr_err)) break;
if(apr_err)
{
char buf[255]; /* Flawfinder: ignore */
std::cerr << "Error parsing options: "
<< apr_strerror(apr_err, buf, 255) << std::endl;
return 1;
}
switch (opt_id)
{
case 'g':
test_group.assign(opt_arg);
break;
case 'h':
stream_usage(std::cout, argv[0]);
return 0;
break;
case 'l':
stream_groups(std::cout, argv[0]);
return 0;
case 'v':
verbose_mode = true;
break;
case 'o':
output = new std::ofstream;
output->open(opt_arg);
break;
case 's': // --sourcedir
tut::sSourceDir = opt_arg;
// For convenience, so you can use tut::sSourceDir + "myfile"
tut::sSourceDir += '/';
break;
case 't':
touch = opt_arg;
break;
case 'w':
wait_at_exit = true;
break;
case 'd':
// *TODO: should come from error config file. We set it to
// ERROR by default, so this allows full debug levels.
LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
break;
default:
stream_usage(std::cerr, argv[0]);
return 1;
break;
}
}
// run the tests
LLTestCallback callback(verbose_mode, output);
tut::runner.get().set_callback(&callback);
if(test_group.empty())
{
tut::runner.get().run_tests();
}
else
{
tut::runner.get().run_tests(test_group);
}
if (wait_at_exit)
{
std::cerr << "Waiting for input before exiting..." << std::endl;
std::cin.get();
}
if (output)
{
output->close();
delete output;
}
if (touch)
{
std::ofstream s;
s.open(touch);
s << "ok" << std::endl;
s.close();
}
apr_terminate();
return 0;
}

50
indra/test/test.h Normal file
View File

@@ -0,0 +1,50 @@
/**
* @file test.h
* @author James
* @date 2009-01-12
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
*
* Copyright (c) 2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef TEST_H
#define TEST_H
#include <string>
namespace tut
{
// Source code directory from CMake, used for loading test data and
// configuration. For example:
//
// loadMyConfig( sSourceDir + "config.dat" );
//
// Use sparingly, as hitting the file system slows down test execution
// and hence every compile. JC
extern std::string sSourceDir;
}
#endif

View File

@@ -0,0 +1,140 @@
#!/usr/bin/python
"""
@file test_llmanifest.py
@author Ryan Williams
@brief Test cases for LLManifest library.
$LicenseInfo:firstyear=2006&license=viewergpl$
Copyright (c) 2006-2009, Linden Research, Inc.
Second Life Viewer Source Code
The source code in this file ("Source Code") is provided by Linden Lab
to you under the terms of the GNU General Public License, version 2.0
("GPL"), unless you have obtained a separate licensing agreement
("Other License"), formally executed by you and Linden Lab. Terms of
the GPL can be found in doc/GPL-license.txt in this distribution, or
online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
There are special exceptions to the terms and conditions of the GPL as
it is applied to this Source Code. View the full text of the exception
in the file doc/FLOSS-exception.txt in this software distribution, or
online at
http://secondlifegrid.net/programs/open_source/licensing/flossexception
By copying, modifying or distributing this software, you acknowledge
that you have read and understood your obligations described above,
and agree to abide by those obligations.
ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
COMPLETENESS OR PERFORMANCE.
$/LicenseInfo$
"""
from indra.util import llmanifest
import os.path
import os
import unittest
class DemoManifest(llmanifest.LLManifest):
def construct(self):
super(DemoManifest, self).construct()
if self.prefix("dir_1"):
self.path("test_a")
self.path(src="test_b", dst="test_dst_b")
self.path("*.test")
self.path("*.tex", "*.jpg")
if self.prefix("nested", dst=""):
self.path("deep")
self.end_prefix()
self.end_prefix("dir_1")
class Demo_ArchManifest(llmanifest.LLManifest):
pass
class TestLLManifest(unittest.TestCase):
mode='static'
def setUp(self):
self.m = llmanifest.LLManifest({'source':'src', 'dest':'dst', 'grid':'default', 'platform':'darwin', 'version':(1,2,3,4),
'artwork':'art', 'build':'build'})
def testproperwindowspath(self):
self.assertEqual(llmanifest.proper_windows_path("C:\Program Files", "cygwin"),"/cygdrive/c/Program Files")
self.assertEqual(llmanifest.proper_windows_path("C:\Program Files", "windows"), "C:\Program Files")
self.assertEqual(llmanifest.proper_windows_path("/cygdrive/c/Program Files/NSIS", "windows"), "C:\Program Files\NSIS")
self.assertEqual(llmanifest.proper_windows_path("/cygdrive/c/Program Files/NSIS", "cygwin"), "/cygdrive/c/Program Files/NSIS")
def testpathancestors(self):
self.assertEqual(["dir"], [p for p in llmanifest.path_ancestors("dir")])
self.assertEqual(["dir/sub", "dir"], [p for p in llmanifest.path_ancestors("dir/sub")])
self.assertEqual(["dir/sub", "dir"], [p for p in llmanifest.path_ancestors("dir/sub/")])
self.assertEqual(["dir/sub/two", "dir/sub", "dir"], [p for p in llmanifest.path_ancestors("dir/sub/two")])
def testforplatform(self):
self.assertEqual(llmanifest.LLManifest.for_platform('demo'), DemoManifest)
def tmp_test():
return llmanifest.LLManifest.for_platform('extant')
self.assertRaises(KeyError, tmp_test)
ExtantManifest = llmanifest.LLManifestRegistry('ExtantManifest', (llmanifest.LLManifest,), {})
self.assertEqual(llmanifest.LLManifest.for_platform('extant'), ExtantManifest)
self.assertEqual(llmanifest.LLManifest.for_platform('demo', 'Arch'), Demo_ArchManifest)
def testprefix(self):
self.assertEqual(self.m.get_src_prefix(), "src")
self.assertEqual(self.m.get_dst_prefix(), "dst")
self.m.prefix("level1")
self.assertEqual(self.m.get_src_prefix(), "src/level1")
self.assertEqual(self.m.get_dst_prefix(), "dst/level1")
self.m.end_prefix()
self.m.prefix(src="src", dst="dst")
self.assertEqual(self.m.get_src_prefix(), "src/src")
self.assertEqual(self.m.get_dst_prefix(), "dst/dst")
self.m.end_prefix()
def testendprefix(self):
self.assertEqual(self.m.get_src_prefix(), "src")
self.assertEqual(self.m.get_dst_prefix(), "dst")
self.m.prefix("levela")
self.m.end_prefix()
self.assertEqual(self.m.get_src_prefix(), "src")
self.assertEqual(self.m.get_dst_prefix(), "dst")
self.m.prefix("level1")
self.m.end_prefix("level1")
self.assertEqual(self.m.get_src_prefix(), "src")
self.assertEqual(self.m.get_dst_prefix(), "dst")
self.m.prefix("level1")
def tmp_test():
self.m.end_prefix("mismatch")
self.assertRaises(ValueError, tmp_test)
def testruncommand(self):
self.assertEqual("Hello\n", self.m.run_command("echo Hello"))
def exit_1_test():
self.m.run_command("exit 1")
self.assertRaises(RuntimeError, exit_1_test)
def not_found_test():
self.m.run_command("test_command_that_should_not_be_found")
self.assertRaises(RuntimeError, not_found_test)
def testpathof(self):
self.assertEqual(self.m.src_path_of("a"), "src/a")
self.assertEqual(self.m.dst_path_of("a"), "dst/a")
self.m.prefix("tmp")
self.assertEqual(self.m.src_path_of("b/c"), "src/tmp/b/c")
self.assertEqual(self.m.dst_path_of("b/c"), "dst/tmp/b/c")
def testcmakedirs(self):
self.m.cmakedirs("test_dir_DELETE/nested/dir")
self.assert_(os.path.exists("test_dir_DELETE/nested/dir"))
self.assert_(os.path.isdir("test_dir_DELETE"))
self.assert_(os.path.isdir("test_dir_DELETE/nested"))
self.assert_(os.path.isdir("test_dir_DELETE/nested/dir"))
os.removedirs("test_dir_DELETE/nested/dir")
if __name__ == '__main__':
unittest.main()

455
indra/test/v2math_tut.cpp Normal file
View File

@@ -0,0 +1,455 @@
/**
* @file v2math_tut.cpp
* @author Adroit
* @date 2007-02
* @brief v2math test cases.
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "lltut.h"
#include "v2math.h"
namespace tut
{
struct v2math_data
{
};
typedef test_group<v2math_data> v2math_test;
typedef v2math_test::object v2math_object;
tut::v2math_test v2math_testcase("v2math");
template<> template<>
void v2math_object::test<1>()
{
LLVector2 vec2;
ensure("LLVector2:Fail to initialize ", (0.f == vec2.mV[VX] && 0.f == vec2.mV[VY]));
F32 x =2.0f, y = 3.2f ;
LLVector2 vec3(x,y);
ensure("LLVector2(F32 x, F32 y):Fail to initialize ", (x == vec3.mV[VX]) && (y == vec3.mV[VY]));
const F32 vec[2] = {3.2f, 4.5f};
LLVector2 vec4(vec);
ensure("LLVector2(const F32 *vec):Fail to initialize ", (vec[0] == vec4.mV[VX]) && (vec[1] == vec4.mV[VY]));
vec4.clearVec();
ensure("clearVec():Fail to clean the values ", (0.f == vec4.mV[VX] && 0.f == vec4.mV[VY]));
vec3.zeroVec();
ensure("zeroVec():Fail to fill the zero ", (0.f == vec3.mV[VX] && 0.f == vec3.mV[VY]));
}
template<> template<>
void v2math_object::test<2>()
{
F32 x = 123.356f, y = 2387.453f;
LLVector2 vec2,vec3;
vec2.setVec(x, y);
ensure("1:setVec: Fail ", (x == vec2.mV[VX]) && (y == vec2.mV[VY]));
vec3.setVec(vec2);
ensure("2:setVec: Fail " ,(vec2 == vec3));
vec3.zeroVec();
const F32 vec[2] = {3.24653f, 457653.4f};
vec3.setVec(vec);
ensure("3:setVec: Fail ", (vec[0] == vec3.mV[VX]) && (vec[1] == vec3.mV[VY]));
}
template<> template<>
void v2math_object::test<3>()
{
F32 x = 2.2345f, y = 3.5678f ;
LLVector2 vec2(x,y);
ensure("magVecSquared:Fail ", is_approx_equal(vec2.magVecSquared(), (x*x + y*y)));
ensure("magVec:Fail ", is_approx_equal(vec2.magVec(), fsqrtf(x*x + y*y)));
}
template<> template<>
void v2math_object::test<4>()
{
F32 x =-2.0f, y = -3.0f ;
LLVector2 vec2(x,y);
ensure_equals("abs():Fail", vec2.abs(), TRUE);
ensure("abs() x", is_approx_equal(vec2.mV[VX], 2.f));
ensure("abs() y", is_approx_equal(vec2.mV[VY], 3.f));
ensure("isNull():Fail ", FALSE == vec2.isNull()); //Returns TRUE if vector has a _very_small_ length
x =.00000001f, y = .000001001f;
vec2.setVec(x, y);
ensure("isNull(): Fail ", TRUE == vec2.isNull());
}
template<> template<>
void v2math_object::test<5>()
{
F32 x =1.f, y = 2.f;
LLVector2 vec2(x, y), vec3;
vec3 = vec3.scaleVec(vec2);
ensure("scaleVec: Fail ", vec3.mV[VX] == 0. && vec3.mV[VY] == 0.);
ensure("isExactlyZero(): Fail", TRUE == vec3.isExactlyZero());
vec3.setVec(2.f, 1.f);
vec3 = vec3.scaleVec(vec2);
ensure("scaleVec: Fail ", (2.f == vec3.mV[VX]) && (2.f == vec3.mV[VY]));
ensure("isExactlyZero():Fail", FALSE == vec3.isExactlyZero());
}
template<> template<>
void v2math_object::test<6>()
{
F32 x1 =1.f, y1 = 2.f, x2 = -2.3f, y2 = 1.11f;
F32 val1, val2;
LLVector2 vec2(x1, y1), vec3(x2, y2), vec4;
vec4 = vec2 + vec3 ;
val1 = x1+x2;
val2 = y1+y2;
ensure("1:operator+ failed",(val1 == vec4.mV[VX]) && ((val2 == vec4.mV[VY])));
vec2.clearVec();
vec3.clearVec();
x1 = -.235f, y1 = -24.32f, x2 = -2.3f, y2 = 1.f;
vec2.setVec(x1, y1);
vec3.setVec(x2, y2);
vec4 = vec2 + vec3;
val1 = x1+x2;
val2 = y1+y2;
ensure("2:operator+ failed",(val1 == vec4.mV[VX]) && ((val2 == vec4.mV[VY])));
}
template<> template<>
void v2math_object::test<7>()
{
F32 x1 =1.f, y1 = 2.f, x2 = -2.3f, y2 = 1.11f;
F32 val1, val2;
LLVector2 vec2(x1, y1), vec3(x2, y2), vec4;
vec4 = vec2 - vec3 ;
val1 = x1-x2;
val2 = y1-y2;
ensure("1:operator- failed",(val1 == vec4.mV[VX]) && ((val2 == vec4.mV[VY])));
vec2.clearVec();
vec3.clearVec();
vec4.clearVec();
x1 = -.235f, y1 = -24.32f, x2 = -2.3f, y2 = 1.f;
vec2.setVec(x1, y1);
vec3.setVec(x2, y2);
vec4 = vec2 - vec3;
val1 = x1-x2;
val2 = y1-y2;
ensure("2:operator- failed",(val1 == vec4.mV[VX]) && ((val2 == vec4.mV[VY])));
}
template<> template<>
void v2math_object::test<8>()
{
F32 x1 =1.f, y1 = 2.f, x2 = -2.3f, y2 = 1.11f;
F32 val1, val2;
LLVector2 vec2(x1, y1), vec3(x2, y2);
val1 = vec2 * vec3;
val2 = x1*x2 + y1*y2;
ensure("1:operator* failed",(val1 == val2));
vec3.clearVec();
F32 mulVal = 4.332f;
vec3 = vec2 * mulVal;
val1 = x1*mulVal;
val2 = y1*mulVal;
ensure("2:operator* failed",(val1 == vec3.mV[VX]) && (val2 == vec3.mV[VY]));
vec3.clearVec();
vec3 = mulVal * vec2;
ensure("3:operator* failed",(val1 == vec3.mV[VX]) && (val2 == vec3.mV[VY]));
}
template<> template<>
void v2math_object::test<9>()
{
F32 x1 =1.f, y1 = 2.f, div = 3.2f;
F32 val1, val2;
LLVector2 vec2(x1, y1), vec3;
vec3 = vec2 / div;
val1 = x1 / div;
val2 = y1 / div;
ensure("1:operator/ failed", is_approx_equal(val1, vec3.mV[VX]) && is_approx_equal(val2, vec3.mV[VY]));
vec3.clearVec();
x1 = -.235f, y1 = -24.32f, div = -2.2f;
vec2.setVec(x1, y1);
vec3 = vec2 / div;
val1 = x1 / div;
val2 = y1 / div;
ensure("2:operator/ failed", is_approx_equal(val1, vec3.mV[VX]) && is_approx_equal(val2, vec3.mV[VY]));
}
template<> template<>
void v2math_object::test<10>()
{
F32 x1 =1.f, y1 = 2.f, x2 = -2.3f, y2 = 1.11f;
F32 val1, val2;
LLVector2 vec2(x1, y1), vec3(x2, y2), vec4;
vec4 = vec2 % vec3;
val1 = x1*y2 - x2*y1;
val2 = y1*x2 - y2*x1;
ensure("1:operator% failed",(val1 == vec4.mV[VX]) && (val2 == vec4.mV[VY]));
vec2.clearVec();
vec3.clearVec();
vec4.clearVec();
x1 = -.235f, y1 = -24.32f, x2 = -2.3f, y2 = 1.f;
vec2.setVec(x1, y1);
vec3.setVec(x2, y2);
vec4 = vec2 % vec3;
val1 = x1*y2 - x2*y1;
val2 = y1*x2 - y2*x1;
ensure("2:operator% failed",(val1 == vec4.mV[VX]) && (val2 == vec4.mV[VY]));
}
template<> template<>
void v2math_object::test<11>()
{
F32 x1 =1.f, y1 = 2.f;
LLVector2 vec2(x1, y1), vec3(x1, y1);
ensure("1:operator== failed",(vec2 == vec3));
vec2.clearVec();
vec3.clearVec();
x1 = -.235f, y1 = -24.32f;
vec2.setVec(x1, y1);
vec3.setVec(vec2);
ensure("2:operator== failed",(vec2 == vec3));
}
template<> template<>
void v2math_object::test<12>()
{
F32 x1 = 1.f, y1 = 2.f,x2 = 2.332f, y2 = -1.23f;
LLVector2 vec2(x1, y1), vec3(x2, y2);
ensure("1:operator!= failed",(vec2 != vec3));
vec2.clearVec();
vec3.clearVec();
vec2.setVec(x1, y1);
vec3.setVec(vec2);
ensure("2:operator!= failed", (FALSE == (vec2 != vec3)));
}
template<> template<>
void v2math_object::test<13>()
{
F32 x1 = 1.f, y1 = 2.f,x2 = 2.332f, y2 = -1.23f;
F32 val1, val2;
LLVector2 vec2(x1, y1), vec3(x2, y2);
vec2 +=vec3;
val1 = x1+x2;
val2 = y1+y2;
ensure("1:operator+= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY]));
vec2.setVec(x1, y1);
vec2 -=vec3;
val1 = x1-x2;
val2 = y1-y2;
ensure("2:operator-= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY]));
vec2.clearVec();
vec3.clearVec();
x1 = -21.000466f, y1 = 2.98382f,x2 = 0.332f, y2 = -01.23f;
vec2.setVec(x1, y1);
vec3.setVec(x2, y2);
vec2 +=vec3;
val1 = x1+x2;
val2 = y1+y2;
ensure("3:operator+= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY]));
vec2.setVec(x1, y1);
vec2 -=vec3;
val1 = x1-x2;
val2 = y1-y2;
ensure("4:operator-= failed", is_approx_equal(val1, vec2.mV[VX]) && is_approx_equal(val2, vec2.mV[VY]));
}
template<> template<>
void v2math_object::test<14>()
{
F32 x1 =1.f, y1 = 2.f;
F32 val1, val2, mulVal = 4.332f;
LLVector2 vec2(x1, y1);
vec2 /=mulVal;
val1 = x1 / mulVal;
val2 = y1 / mulVal;
ensure("1:operator/= failed", is_approx_equal(val1, vec2.mV[VX]) && is_approx_equal(val2, vec2.mV[VY]));
vec2.clearVec();
x1 = .213f, y1 = -2.34f, mulVal = -.23f;
vec2.setVec(x1, y1);
vec2 /=mulVal;
val1 = x1 / mulVal;
val2 = y1 / mulVal;
ensure("2:operator/= failed", is_approx_equal(val1, vec2.mV[VX]) && is_approx_equal(val2, vec2.mV[VY]));
}
template<> template<>
void v2math_object::test<15>()
{
F32 x1 =1.f, y1 = 2.f;
F32 val1, val2, mulVal = 4.332f;
LLVector2 vec2(x1, y1);
vec2 *=mulVal;
val1 = x1*mulVal;
val2 = y1*mulVal;
ensure("1:operator*= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY]));
vec2.clearVec();
x1 = .213f, y1 = -2.34f, mulVal = -.23f;
vec2.setVec(x1, y1);
vec2 *=mulVal;
val1 = x1*mulVal;
val2 = y1*mulVal;
ensure("2:operator*= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY]));
}
template<> template<>
void v2math_object::test<16>()
{
F32 x1 =1.f, y1 = 2.f, x2 = -2.3f, y2 = 1.11f;
F32 val1, val2;
LLVector2 vec2(x1, y1), vec3(x2, y2);
vec2 %= vec3;
val1 = x1*y2 - x2*y1;
val2 = y1*x2 - y2*x1;
ensure("1:operator%= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY]));
}
template<> template<>
void v2math_object::test<17>()
{
F32 x1 =1.f, y1 = 2.f;
LLVector2 vec2(x1, y1),vec3;
vec3 = -vec2;
ensure("1:operator- failed",(-vec3 == vec2));
}
template<> template<>
void v2math_object::test<18>()
{
F32 x1 =1.f, y1 = 2.f;
std::ostringstream stream1, stream2;
LLVector2 vec2(x1, y1),vec3;
stream1 << vec2;
vec3.setVec(x1, y1);
stream2 << vec3;
ensure("1:operator << failed",(stream1.str() == stream2.str()));
}
template<> template<>
void v2math_object::test<19>()
{
F32 x1 =1.0f, y1 = 2.0f, x2 = -.32f, y2 = .2234f;
LLVector2 vec2(x1, y1),vec3(x2, y2);
ensure("1:operator < failed",(vec3 < vec2));
x1 = 1.0f, y1 = 2.0f, x2 = 1.0f, y2 = 3.2234f;
vec2.setVec(x1, y1);
vec3.setVec(x2, y2);
ensure("2:operator < failed", (FALSE == vec3 < vec2));
}
template<> template<>
void v2math_object::test<20>()
{
F32 x1 =1.0f, y1 = 2.0f;
LLVector2 vec2(x1, y1);
ensure("1:operator [] failed",( x1 == vec2[0]));
ensure("2:operator [] failed",( y1 == vec2[1]));
vec2.clearVec();
x1 = 23.0f, y1 = -.2361f;
vec2.setVec(x1, y1);
F32 ref1 = vec2[0];
ensure("3:operator [] failed", ( ref1 == x1));
F32 ref2 = vec2[1];
ensure("4:operator [] failed", ( ref2 == y1));
}
template<> template<>
void v2math_object::test<21>()
{
F32 x1 =1.f, y1 = 2.f, x2 = -.32f, y2 = .2234f;
F32 val1, val2;
LLVector2 vec2(x1, y1),vec3(x2, y2);
val1 = dist_vec_squared2D(vec2, vec3);
val2 = (x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2);
ensure_equals("dist_vec_squared2D values are not equal",val2, val1);
val1 = dist_vec_squared(vec2, vec3);
ensure_equals("dist_vec_squared values are not equal",val2, val1);
val1 = dist_vec(vec2, vec3);
val2 = fsqrtf((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2));
ensure_equals("dist_vec values are not equal",val2, val1);
}
template<> template<>
void v2math_object::test<22>()
{
F32 x1 =1.f, y1 = 2.f, x2 = -.32f, y2 = .2234f,fVal = .0121f;
F32 val1, val2;
LLVector2 vec2(x1, y1),vec3(x2, y2);
LLVector2 vec4 = lerp(vec2, vec3, fVal);
val1 = x1 + (x2 - x1) * fVal;
val2 = y1 + (y2 - y1) * fVal;
ensure("lerp values are not equal", ((val1 == vec4.mV[VX]) && (val2 == vec4.mV[VY])));
}
template<> template<>
void v2math_object::test<23>()
{
F32 x1 =1.f, y1 = 2.f;
F32 val1, val2;
LLVector2 vec2(x1, y1);
F32 vecMag = vec2.normVec();
F32 mag = fsqrtf(x1*x1 + y1*y1);
F32 oomag = 1.f / mag;
val1 = x1 * oomag;
val2 = y1 * oomag;
ensure("normVec failed", is_approx_equal(val1, vec2.mV[VX]) && is_approx_equal(val2, vec2.mV[VY]) && is_approx_equal(vecMag, mag));
x1 =.00000001f, y1 = 0.f;
vec2.setVec(x1, y1);
vecMag = vec2.normVec();
ensure("normVec failed should be 0.", 0. == vec2.mV[VX] && 0. == vec2.mV[VY] && vecMag == 0.);
}
}

315
indra/test/v3color_tut.cpp Normal file
View File

@@ -0,0 +1,315 @@
/**
* @file v3color_tut.cpp
* @author Adroit
* @date 2007-03
* @brief v3color test cases.
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "lltut.h"
#include "v3color.h"
namespace tut
{
struct v3color_data
{
};
typedef test_group<v3color_data> v3color_test;
typedef v3color_test::object v3color_object;
tut::v3color_test v3color_testcase("v3color");
template<> template<>
void v3color_object::test<1>()
{
LLColor3 llcolor3;
ensure("1:LLColor3:Fail to initialize ", (0.0f == llcolor3.mV[0]) && (0.0f == llcolor3.mV[1]) && (0.0f == llcolor3.mV[2]));
F32 r = 2.0f, g = 3.2f, b = 1.f;
F32 v1,v2,v3;
LLColor3 llcolor3a(r,g,b);
ensure("2:LLColor3:Fail to initialize " ,(2.0f == llcolor3a.mV[0]) && (3.2f == llcolor3a.mV[1]) && (1.f == llcolor3a.mV[2]));
const F32 vec[3] = {2.0f, 3.2f,1.f};
LLColor3 llcolor3b(vec);
ensure("3:LLColor3:Fail to initialize " ,(2.0f == llcolor3b.mV[0]) && (3.2f == llcolor3b.mV[1]) && (1.f == llcolor3b.mV[2]));
const char* str = "561122";
LLColor3 llcolor3c(str);
v1 = (F32)86.0f/255.0f; // 0x56 = 86
v2 = (F32)17.0f/255.0f; // 0x11 = 17
v3 = (F32)34.0f/255.f; // 0x22 = 34
ensure("4:LLColor3:Fail to initialize " ,(v1 == llcolor3c.mV[0]) && (v2 == llcolor3c.mV[1]) && (v3 == llcolor3c.mV[2]));
}
template<> template<>
void v3color_object::test<2>()
{
LLColor3 llcolor3;
llcolor3.setToBlack();
ensure("setToBlack:Fail to set black ", ((llcolor3.mV[0] == 0.f) && (llcolor3.mV[1] == 0.f) && (llcolor3.mV[2] == 0.f)));
llcolor3.setToWhite();
ensure("setToWhite:Fail to set white ", ((llcolor3.mV[0] == 1.f) && (llcolor3.mV[1] == 1.f) && (llcolor3.mV[2] == 1.f)));
}
template<> template<>
void v3color_object::test<3>()
{
F32 r = 2.3436212f, g = 1231.f, b = 4.7849321232f;
LLColor3 llcolor3, llcolor3a;
llcolor3.setVec(r,g,b);
ensure("1:setVec(r,g,b) Fail ",((r == llcolor3.mV[0]) && (g == llcolor3.mV[1]) && (b == llcolor3.mV[2])));
llcolor3a.setVec(llcolor3);
ensure_equals("2:setVec(LLColor3) Fail ", llcolor3,llcolor3a);
F32 vec[3] = {1.2324f, 2.45634f, .234563f};
llcolor3.setToBlack();
llcolor3.setVec(vec);
ensure("3:setVec(F32*) Fail ",((vec[0] == llcolor3.mV[0]) && (vec[1] == llcolor3.mV[1]) && (vec[2] == llcolor3.mV[2])));
}
template<> template<>
void v3color_object::test<4>()
{
F32 r = 2.3436212f, g = 1231.f, b = 4.7849321232f;
LLColor3 llcolor3(r,g,b);
ensure("magVecSquared:Fail ", is_approx_equal(llcolor3.magVecSquared(), (r*r + g*g + b*b)));
ensure("magVec:Fail ", is_approx_equal(llcolor3.magVec(), fsqrtf(r*r + g*g + b*b)));
}
template<> template<>
void v3color_object::test<5>()
{
F32 r = 2.3436212f, g = 1231.f, b = 4.7849321232f;
F32 val1, val2,val3;
LLColor3 llcolor3(r,g,b);
F32 vecMag = llcolor3.normVec();
F32 mag = fsqrtf(r*r + g*g + b*b);
F32 oomag = 1.f / mag;
val1 = r * oomag;
val2 = g * oomag;
val3 = b * oomag;
ensure("1:normVec failed ", (is_approx_equal(val1, llcolor3.mV[0]) && is_approx_equal(val2, llcolor3.mV[1]) && is_approx_equal(val3, llcolor3.mV[2]) && is_approx_equal(vecMag, mag)));
r = .000000000f, g = 0.f, b = 0.0f;
llcolor3.setVec(r,g,b);
vecMag = llcolor3.normVec();
ensure("2:normVec failed should be 0. ", (0. == llcolor3.mV[0] && 0. == llcolor3.mV[1] && 0. == llcolor3.mV[2] && vecMag == 0.));
}
template<> template<>
void v3color_object::test<6>()
{
F32 r = 2.3436212f, g = -1231.f, b = .7849321232f;
std::ostringstream stream1, stream2;
LLColor3 llcolor3(r,g,b),llcolor3a;
stream1 << llcolor3;
llcolor3a.setVec(r,g,b);
stream2 << llcolor3a;
ensure("operator << failed ", (stream1.str() == stream2.str()));
}
template<> template<>
void v3color_object::test<7>()
{
F32 r = 2.3436212f, g = -1231.f, b = .7849321232f;
LLColor3 llcolor3(r,g,b),llcolor3a;
llcolor3a = llcolor3;
ensure("operator == failed ", (llcolor3a == llcolor3));
}
template<> template<>
void v3color_object::test<8>()
{
F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f;
LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2),llcolor3b;
llcolor3b = llcolor3 + llcolor3a ;
ensure("1:operator+ failed",is_approx_equal(r1+r2 ,llcolor3b.mV[0]) && is_approx_equal(g1+g2,llcolor3b.mV[1])&& is_approx_equal(b1+b2,llcolor3b.mV[2]));
r1 = -.235f, g1 = -24.32f, b1 = 2.13f, r2 = -2.3f, g2 = 1.f, b2 = 34.21f;
llcolor3.setVec(r1,g1,b1);
llcolor3a.setVec(r2,g2,b2);
llcolor3b = llcolor3 + llcolor3a;
ensure("2:operator+ failed",is_approx_equal(r1+r2 ,llcolor3b.mV[0]) && is_approx_equal(g1+g2,llcolor3b.mV[1])&& is_approx_equal(b1+b2,llcolor3b.mV[2]));
}
template<> template<>
void v3color_object::test<9>()
{
F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f;
LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2),llcolor3b;
llcolor3b = llcolor3 - llcolor3a ;
ensure("1:operator- failed",is_approx_equal(r1-r2 ,llcolor3b.mV[0]) && is_approx_equal(g1-g2,llcolor3b.mV[1])&& is_approx_equal(b1-b2,llcolor3b.mV[2]));
r1 = -.235f, g1 = -24.32f, b1 = 2.13f, r2 = -2.3f, g2 = 1.f, b2 = 34.21f;
llcolor3.setVec(r1,g1,b1);
llcolor3a.setVec(r2,g2,b2);
llcolor3b = llcolor3 - llcolor3a;
ensure("2:operator- failed",is_approx_equal(r1-r2 ,llcolor3b.mV[0]) && is_approx_equal(g1-g2,llcolor3b.mV[1])&& is_approx_equal(b1-b2,llcolor3b.mV[2]));
}
template<> template<>
void v3color_object::test<10>()
{
F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f;
LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2),llcolor3b;
llcolor3b = llcolor3 * llcolor3a;
ensure("1:operator* failed",is_approx_equal(r1*r2 ,llcolor3b.mV[0]) && is_approx_equal(g1*g2,llcolor3b.mV[1])&& is_approx_equal(b1*b2,llcolor3b.mV[2]));
llcolor3a.setToBlack();
F32 mulVal = 4.332f;
llcolor3a = llcolor3 * mulVal;
ensure("2:operator* failed",is_approx_equal(r1*mulVal ,llcolor3a.mV[0]) && is_approx_equal(g1*mulVal,llcolor3a.mV[1])&& is_approx_equal(b1*mulVal,llcolor3a.mV[2]));
llcolor3a.setToBlack();
llcolor3a = mulVal * llcolor3;
ensure("3:operator* failed",is_approx_equal(r1*mulVal ,llcolor3a.mV[0]) && is_approx_equal(g1*mulVal,llcolor3a.mV[1])&& is_approx_equal(b1*mulVal,llcolor3a.mV[2]));
}
template<> template<>
void v3color_object::test<11>()
{
F32 r = 2.3436212f, g = 1231.f, b = 4.7849321232f;
LLColor3 llcolor3(r,g,b),llcolor3a;
llcolor3a = -llcolor3;
ensure("operator- failed ", (-llcolor3a == llcolor3));
}
template<> template<>
void v3color_object::test<12>()
{
F32 r = 2.3436212f, g = 1231.f, b = 4.7849321232f;
LLColor3 llcolor3(r,g,b),llcolor3a(r,g,b);
ensure_equals("1:operator== failed",llcolor3a,llcolor3);
r = 13.3436212f, g = -11.f, b = .7849321232f;
llcolor3.setVec(r,g,b);
llcolor3a.setVec(r,g,b);
ensure_equals("2:operator== failed",llcolor3a,llcolor3);
}
template<> template<>
void v3color_object::test<13>()
{
F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f;
LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2);
ensure("1:operator!= failed",(llcolor3 != llcolor3a));
llcolor3.setToBlack();
llcolor3a.setVec(llcolor3);
ensure("2:operator!= failed", ( FALSE == (llcolor3a != llcolor3)));
}
template<> template<>
void v3color_object::test<14>()
{
F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f;
LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2);
llcolor3a += llcolor3;
ensure("1:operator+= failed",is_approx_equal(r1+r2 ,llcolor3a.mV[0]) && is_approx_equal(g1+g2,llcolor3a.mV[1])&& is_approx_equal(b1+b2,llcolor3a.mV[2]));
llcolor3.setVec(r1,g1,b1);
llcolor3a.setVec(r2,g2,b2);
llcolor3a += llcolor3;
ensure("2:operator+= failed",is_approx_equal(r1+r2 ,llcolor3a.mV[0]) && is_approx_equal(g1+g2,llcolor3a.mV[1])&& is_approx_equal(b1+b2,llcolor3a.mV[2]));
}
template<> template<>
void v3color_object::test<15>()
{
F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f;
LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2);
llcolor3a -= llcolor3;
ensure("1:operator-= failed", is_approx_equal(r2-r1, llcolor3a.mV[0]));
ensure("2:operator-= failed", is_approx_equal(g2-g1, llcolor3a.mV[1]));
ensure("3:operator-= failed", is_approx_equal(b2-b1, llcolor3a.mV[2]));
llcolor3.setVec(r1,g1,b1);
llcolor3a.setVec(r2,g2,b2);
llcolor3a -= llcolor3;
ensure("4:operator-= failed", is_approx_equal(r2-r1, llcolor3a.mV[0]));
ensure("5:operator-= failed", is_approx_equal(g2-g1, llcolor3a.mV[1]));
ensure("6:operator-= failed", is_approx_equal(b2-b1, llcolor3a.mV[2]));
}
template<> template<>
void v3color_object::test<16>()
{
F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f;
LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2);
llcolor3a *= llcolor3;
ensure("1:operator*= failed",is_approx_equal(r1*r2 ,llcolor3a.mV[0]) && is_approx_equal(g1*g2,llcolor3a.mV[1])&& is_approx_equal(b1*b2,llcolor3a.mV[2]));
F32 mulVal = 4.332f;
llcolor3 *=mulVal;
ensure("2:operator*= failed",is_approx_equal(r1*mulVal ,llcolor3.mV[0]) && is_approx_equal(g1*mulVal,llcolor3.mV[1])&& is_approx_equal(b1*mulVal,llcolor3.mV[2]));
}
template<> template<>
void v3color_object::test<17>()
{
F32 r = 2.3436212f, g = -1231.f, b = .7849321232f;
LLColor3 llcolor3(r,g,b);
llcolor3.clamp();
ensure("1:clamp:Fail to clamp " ,(1.0f == llcolor3.mV[0]) && (0.f == llcolor3.mV[1]) && (b == llcolor3.mV[2]));
r = -2.3436212f, g = -1231.f, b = 67.7849321232f;
llcolor3.setVec(r,g,b);
llcolor3.clamp();
ensure("2:clamp:Fail to clamp " ,(0.f == llcolor3.mV[0]) && (0.f == llcolor3.mV[1]) && (1.f == llcolor3.mV[2]));
}
template<> template<>
void v3color_object::test<18>()
{
F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f;
F32 val = 2.3f,val1,val2,val3;
LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2);
val1 = r1 + (r2 - r1)* val;
val2 = g1 + (g2 - g1)* val;
val3 = b1 + (b2 - b1)* val;
LLColor3 llcolor3b = lerp(llcolor3,llcolor3a,val);
ensure("lerp failed ", ((val1 ==llcolor3b.mV[0])&& (val2 ==llcolor3b.mV[1]) && (val3 ==llcolor3b.mV[2])));
}
template<> template<>
void v3color_object::test<19>()
{
F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f;
LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2);
F32 val = distVec(llcolor3,llcolor3a);
ensure("distVec failed ", is_approx_equal(fsqrtf((r1-r2)*(r1-r2) + (g1-g2)*(g1-g2) + (b1-b2)*(b1-b2)) ,val));
F32 val1 = distVec_squared(llcolor3,llcolor3a);
ensure("distVec_squared failed ", is_approx_equal(((r1-r2)*(r1-r2) + (g1-g2)*(g1-g2) + (b1-b2)*(b1-b2)) ,val1));
}
template<> template<>
void v3color_object::test<20>()
{
F32 r1 = 1.02223f, g1 = 22222.212f, b1 = 122222.00002f;
LLColor3 llcolor31(r1,g1,b1);
LLSD sd = llcolor31.getValue();
LLColor3 llcolor32;
llcolor32.setValue(sd);
ensure_equals("LLColor3::setValue/getValue failed", llcolor31, llcolor32);
LLColor3 llcolor33(sd);
ensure_equals("LLColor3(LLSD) failed", llcolor31, llcolor33);
}
}

532
indra/test/v3dmath_tut.cpp Normal file
View File

@@ -0,0 +1,532 @@
/**
* @file v3dmath_tut.cpp
* @author Adroit
* @date 2007-03
* @brief v3dmath test cases.
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "lltut.h"
#include "llquaternion.h"
#include "m3math.h"
#include "v4math.h"
#include "llsd.h"
#include "v3dmath.h"
#include "v3dmath.h"
namespace tut
{
struct v3dmath_data
{
};
typedef test_group<v3dmath_data> v3dmath_test;
typedef v3dmath_test::object v3dmath_object;
tut::v3dmath_test v3dmath_testcase("v3dmath");
template<> template<>
void v3dmath_object::test<1>()
{
LLVector3d vec3D;
ensure("1:LLVector3d:Fail to initialize ", ((0 == vec3D.mdV[VX]) && (0 == vec3D.mdV[VY]) && (0 == vec3D.mdV[VZ])));
F64 x = 2.32f, y = 1.212f, z = -.12f;
LLVector3d vec3Da(x,y,z);
ensure("2:LLVector3d:Fail to initialize ", ((2.32f == vec3Da.mdV[VX]) && (1.212f == vec3Da.mdV[VY]) && (-.12f == vec3Da.mdV[VZ])));
const F64 vec[3] = {1.2f ,3.2f, -4.2f};
LLVector3d vec3Db(vec);
ensure("3:LLVector3d:Fail to initialize ", ((1.2f == vec3Db.mdV[VX]) && (3.2f == vec3Db.mdV[VY]) && (-4.2f == vec3Db.mdV[VZ])));
LLVector3 vec3((F32)x,(F32)y,(F32)z);
LLVector3d vec3Dc(vec3);
ensure_equals("4:LLVector3d Fail to initialize",vec3Da,vec3Dc);
}
template<> template<>
void v3dmath_object::test<2>()
{
S32 a = -235;
LLSD llsd(a);
LLVector3d vec3d(llsd);
LLSD sd = vec3d.getValue();
LLVector3d vec3da(sd);
ensure("1:getValue:Fail ", (vec3d == vec3da));
}
template<> template<>
void v3dmath_object::test<3>()
{
F64 a = 232345521.411132;
LLSD llsd(a);
LLVector3d vec3d;
vec3d.setValue(llsd);
LLSD sd = vec3d.getValue();
LLVector3d vec3da(sd);
ensure("1:setValue:Fail to initialize ", (vec3d == vec3da));
}
template<> template<>
void v3dmath_object::test<4>()
{
F64 a[3] = {222231.43222, 12345.2343, -434343.33222};
LLSD llsd;
llsd[0] = a[0];
llsd[1] = a[1];
llsd[2] = a[2];
LLVector3d vec3D;
vec3D = llsd;
ensure("1:operator=:Fail to initialize ", ((llsd[0].asReal()== vec3D.mdV[VX]) && (llsd[1].asReal() == vec3D.mdV[VY]) && (llsd[2].asReal() == vec3D.mdV[VZ])));
}
template<> template<>
void v3dmath_object::test<5>()
{
F64 x = 2.32f, y = 1.212f, z = -.12f;
LLVector3d vec3D(x,y,z);
vec3D.clearVec();
ensure("1:clearVec:Fail to initialize ", ((0 == vec3D.mdV[VX]) && (0 == vec3D.mdV[VY]) && (0 == vec3D.mdV[VZ])));
vec3D.setVec(x,y,z);
ensure("2:setVec:Fail to initialize ", ((x == vec3D.mdV[VX]) && (y == vec3D.mdV[VY]) && (z == vec3D.mdV[VZ])));
vec3D.zeroVec();
ensure("3:zeroVec:Fail to initialize ", ((0 == vec3D.mdV[VX]) && (0 == vec3D.mdV[VY]) && (0 == vec3D.mdV[VZ])));
vec3D.clearVec();
LLVector3 vec3((F32)x,(F32)y,(F32)z);
vec3D.setVec(vec3);
ensure("4:setVec:Fail to initialize ", ((x == vec3D.mdV[VX]) && (y == vec3D.mdV[VY]) && (z == vec3D.mdV[VZ])));
vec3D.clearVec();
const F64 vec[3] = {x,y,z};
vec3D.setVec(vec);
ensure("5:setVec:Fail to initialize ", ((x == vec3D.mdV[VX]) && (y == vec3D.mdV[VY]) && (z == vec3D.mdV[VZ])));
LLVector3d vec3Da;
vec3Da.setVec(vec3D);
ensure_equals("6:setVec: Fail to initialize", vec3D, vec3Da);
}
template<> template<>
void v3dmath_object::test<6>()
{
F64 x = -2.32, y = 1.212, z = -.12;
LLVector3d vec3D(x,y,z);
vec3D.abs();
ensure("1:abs:Fail ", ((-x == vec3D.mdV[VX]) && (y == vec3D.mdV[VY]) && (-z == vec3D.mdV[VZ])));
ensure("2:isNull():Fail ", (FALSE == vec3D.isNull()));
vec3D.clearVec();
x =.00000001, y = .000001001, z = .000001001;
vec3D.setVec(x,y,z);
ensure("3:isNull():Fail ", (TRUE == vec3D.isNull()));
ensure("4:isExactlyZero():Fail ", (FALSE == vec3D.isExactlyZero()));
x =.0000000, y = .00000000, z = .00000000;
vec3D.setVec(x,y,z);
ensure("5:isExactlyZero():Fail ", (TRUE == vec3D.isExactlyZero()));
}
template<> template<>
void v3dmath_object::test<7>()
{
F64 x = -2.32, y = 1.212, z = -.12;
LLVector3d vec3D(x,y,z);
ensure("1:operator [] failed",( x == vec3D[0]));
ensure("2:operator [] failed",( y == vec3D[1]));
ensure("3:operator [] failed",( z == vec3D[2]));
vec3D.clearVec();
x = 23.23, y = -.2361, z = 3.25;
vec3D.setVec(x,y,z);
F64 &ref1 = vec3D[0];
ensure("4:operator [] failed",( ref1 == vec3D[0]));
F64 &ref2 = vec3D[1];
ensure("5:operator [] failed",( ref2 == vec3D[1]));
F64 &ref3 = vec3D[2];
ensure("6:operator [] failed",( ref3 == vec3D[2]));
}
template<> template<>
void v3dmath_object::test<8>()
{
F32 x = 1.f, y = 2.f, z = -1.f;
LLVector4 vec4(x,y,z);
LLVector3d vec3D;
vec3D = vec4;
ensure("1:operator=:Fail to initialize ", ((vec4.mV[VX] == vec3D.mdV[VX]) && (vec4.mV[VY] == vec3D.mdV[VY]) && (vec4.mV[VZ] == vec3D.mdV[VZ])));
}
template<> template<>
void v3dmath_object::test<9>()
{
F64 x1 = 1.78787878, y1 = 232322.2121, z1 = -12121.121212;
F64 x2 = 1.2, y2 = 2.5, z2 = 1.;
LLVector3d vec3D(x1,y1,z1),vec3Da(x2,y2,z2),vec3Db;
vec3Db = vec3Da+ vec3D;
ensure("1:operator+:Fail to initialize ", ((x1+x2 == vec3Db.mdV[VX]) && (y1+y2 == vec3Db.mdV[VY]) && (z1+z2 == vec3Db.mdV[VZ])));
x1 = -2.45, y1 = 2.1, z1 = 3.0;
vec3D.clearVec();
vec3Da.clearVec();
vec3D.setVec(x1,y1,z1);
vec3Da += vec3D;
ensure_equals("2:operator+=: Fail to initialize", vec3Da,vec3D);
vec3Da += vec3D;
ensure("3:operator+=:Fail to initialize ", ((2*x1 == vec3Da.mdV[VX]) && (2*y1 == vec3Da.mdV[VY]) && (2*z1 == vec3Da.mdV[VZ])));
}
template<> template<>
void v3dmath_object::test<10>()
{
F64 x1 = 1., y1 = 2., z1 = -1.1;
F64 x2 = 1.2, y2 = 2.5, z2 = 1.;
LLVector3d vec3D(x1,y1,z1),vec3Da(x2,y2,z2),vec3Db;
vec3Db = vec3Da - vec3D;
ensure("1:operator-:Fail to initialize ", ((x2-x1 == vec3Db.mdV[VX]) && (y2-y1 == vec3Db.mdV[VY]) && (z2-z1 == vec3Db.mdV[VZ])));
x1 = -2.45, y1 = 2.1, z1 = 3.0;
vec3D.clearVec();
vec3Da.clearVec();
vec3D.setVec(x1,y1,z1);
vec3Da -=vec3D;
ensure("2:operator-=:Fail to initialize ", ((2.45 == vec3Da.mdV[VX]) && (-2.1 == vec3Da.mdV[VY]) && (-3.0 == vec3Da.mdV[VZ])));
vec3Da -= vec3D;
ensure("3:operator-=:Fail to initialize ", ((-2*x1 == vec3Da.mdV[VX]) && (-2*y1 == vec3Da.mdV[VY]) && (-2*z1 == vec3Da.mdV[VZ])));
}
template<> template<>
void v3dmath_object::test<11>()
{
F64 x1 = 1., y1 = 2., z1 = -1.1;
F64 x2 = 1.2, y2 = 2.5, z2 = 1.;
LLVector3d vec3D(x1,y1,z1),vec3Da(x2,y2,z2);
F64 res = vec3D * vec3Da;
ensure_approximately_equals(
"1:operator* failed",
res,
(x1*x2 + y1*y2 + z1*z2),
8);
vec3Da.clearVec();
F64 mulVal = 4.2;
vec3Da = vec3D * mulVal;
ensure_approximately_equals(
"2a:operator* failed",
vec3Da.mdV[VX],
x1*mulVal,
8);
ensure_approximately_equals(
"2b:operator* failed",
vec3Da.mdV[VY],
y1*mulVal,
8);
ensure_approximately_equals(
"2c:operator* failed",
vec3Da.mdV[VZ],
z1*mulVal,
8);
vec3Da.clearVec();
vec3Da = mulVal * vec3D;
ensure_approximately_equals(
"3a:operator* failed",
vec3Da.mdV[VX],
x1*mulVal,
8);
ensure_approximately_equals(
"3b:operator* failed",
vec3Da.mdV[VY],
y1*mulVal,
8);
ensure_approximately_equals(
"3c:operator* failed",
vec3Da.mdV[VZ],
z1*mulVal,
8);
vec3D *= mulVal;
ensure_approximately_equals(
"4a:operator*= failed",
vec3D.mdV[VX],
x1*mulVal,
8);
ensure_approximately_equals(
"4b:operator*= failed",
vec3D.mdV[VY],
y1*mulVal,
8);
ensure_approximately_equals(
"4c:operator*= failed",
vec3D.mdV[VZ],
z1*mulVal,
8);
}
template<> template<>
void v3dmath_object::test<12>()
{
F64 x1 = 1., y1 = 2., z1 = -1.1;
F64 x2 = 1.2, y2 = 2.5, z2 = 1.;
F64 val1, val2, val3;
LLVector3d vec3D(x1,y1,z1),vec3Da(x2,y2,z2), vec3Db;
vec3Db = vec3D % vec3Da;
val1 = y1*z2 - y2*z1;
val2 = z1*x2 -z2*x1;
val3 = x1*y2-x2*y1;
ensure("1:operator% failed",(val1 == vec3Db.mdV[VX]) && (val2 == vec3Db.mdV[VY]) && (val3 == vec3Db.mdV[VZ]));
vec3D %= vec3Da;
ensure("2:operator%= failed",
is_approx_equal(vec3D.mdV[VX],vec3Db.mdV[VX]) &&
is_approx_equal(vec3D.mdV[VY],vec3Db.mdV[VY]) &&
is_approx_equal(vec3D.mdV[VZ],vec3Db.mdV[VZ]) );
}
template<> template<>
void v3dmath_object::test<13>()
{
F64 x1 = 1., y1 = 2., z1 = -1.1,div = 4.2;
F64 t = 1.f / div;
LLVector3d vec3D(x1,y1,z1), vec3Da;
vec3Da = vec3D/div;
ensure_approximately_equals(
"1a:operator/ failed",
vec3Da.mdV[VX],
x1*t,
8);
ensure_approximately_equals(
"1b:operator/ failed",
vec3Da.mdV[VY],
y1*t,
8);
ensure_approximately_equals(
"1c:operator/ failed",
vec3Da.mdV[VZ],
z1*t,
8);
x1 = 1.23, y1 = 4., z1 = -2.32;
vec3D.clearVec();
vec3Da.clearVec();
vec3D.setVec(x1,y1,z1);
vec3Da = vec3D/div;
ensure_approximately_equals(
"2a:operator/ failed",
vec3Da.mdV[VX],
x1*t,
8);
ensure_approximately_equals(
"2b:operator/ failed",
vec3Da.mdV[VY],
y1*t,
8);
ensure_approximately_equals(
"2c:operator/ failed",
vec3Da.mdV[VZ],
z1*t,
8);
vec3D /= div;
ensure_approximately_equals(
"3a:operator/= failed",
vec3D.mdV[VX],
x1*t,
8);
ensure_approximately_equals(
"3b:operator/= failed",
vec3D.mdV[VY],
y1*t,
8);
ensure_approximately_equals(
"3c:operator/= failed",
vec3D.mdV[VZ],
z1*t,
8);
}
template<> template<>
void v3dmath_object::test<14>()
{
F64 x1 = 1., y1 = 2., z1 = -1.1;
LLVector3d vec3D(x1,y1,z1), vec3Da;
ensure("1:operator!= failed",(TRUE == (vec3D !=vec3Da)));
vec3Da = vec3D;
ensure("2:operator== failed",(vec3D ==vec3Da));
vec3D.clearVec();
vec3Da.clearVec();
x1 = .211, y1 = 21.111, z1 = 23.22;
vec3D.setVec(x1,y1,z1);
vec3Da.setVec(x1,y1,z1);
ensure("3:operator== failed",(vec3D ==vec3Da));
ensure("4:operator!= failed",(FALSE == (vec3D !=vec3Da)));
}
template<> template<>
void v3dmath_object::test<15>()
{
F64 x1 = 1., y1 = 2., z1 = -1.1;
LLVector3d vec3D(x1,y1,z1), vec3Da;
std::ostringstream stream1, stream2;
stream1 << vec3D;
vec3Da.setVec(x1,y1,z1);
stream2 << vec3Da;
ensure("1:operator << failed",(stream1.str() == stream2.str()));
}
template<> template<>
void v3dmath_object::test<16>()
{
F64 x1 = 1.23, y1 = 2.0, z1 = 4.;
std::string buf("1.23 2. 4");
LLVector3d vec3D, vec3Da(x1,y1,z1);
LLVector3d::parseVector3d(buf, &vec3D);
ensure_equals("1:parseVector3d: failed " , vec3D, vec3Da);
}
template<> template<>
void v3dmath_object::test<17>()
{
F64 x1 = 1., y1 = 2., z1 = -1.1;
LLVector3d vec3D(x1,y1,z1), vec3Da;
vec3Da = -vec3D;
ensure("1:operator- failed", (vec3D == - vec3Da));
}
template<> template<>
void v3dmath_object::test<18>()
{
F64 x = 1., y = 2., z = -1.1;
LLVector3d vec3D(x,y,z);
F64 res = (x*x + y*y + z*z) - vec3D.magVecSquared();
ensure("1:magVecSquared:Fail ", ((-F_APPROXIMATELY_ZERO <= res)&& (res <=F_APPROXIMATELY_ZERO)));
res = fsqrtf(x*x + y*y + z*z) - vec3D.magVec();
ensure("2:magVec: Fail ", ((-F_APPROXIMATELY_ZERO <= res)&& (res <=F_APPROXIMATELY_ZERO)));
}
template<> template<>
void v3dmath_object::test<19>()
{
F64 x = 1., y = 2., z = -1.1;
LLVector3d vec3D(x,y,z);
F64 mag = vec3D.normVec();
mag = 1.f/ mag;
ensure_approximately_equals(
"1a:normVec: Fail ",
vec3D.mdV[VX],
x * mag,
8);
ensure_approximately_equals(
"1b:normVec: Fail ",
vec3D.mdV[VY],
y * mag,
8);
ensure_approximately_equals(
"1c:normVec: Fail ",
vec3D.mdV[VZ],
z * mag,
8);
x = 0.000000001, y = 0.000000001, z = 0.000000001;
vec3D.clearVec();
vec3D.setVec(x,y,z);
mag = vec3D.normVec();
ensure_approximately_equals(
"2a:normVec: Fail ",
vec3D.mdV[VX],
x * mag,
8);
ensure_approximately_equals(
"2b:normVec: Fail ",
vec3D.mdV[VY],
y * mag,
8);
ensure_approximately_equals(
"2c:normVec: Fail ",
vec3D.mdV[VZ],
z * mag,
8);
}
template<> template<>
void v3dmath_object::test<20>()
{
F64 x1 = 1111.232222;
F64 y1 = 2222222222.22;
F64 z1 = 422222222222.0;
std::string buf("1111.232222 2222222222.22 422222222222");
LLVector3d vec3Da, vec3Db(x1,y1,z1);
LLVector3d::parseVector3d(buf, &vec3Da);
ensure_equals("1:parseVector3 failed", vec3Da, vec3Db);
}
template<> template<>
void v3dmath_object::test<21>()
{
F64 x1 = 1., y1 = 2., z1 = -1.1;
F64 x2 = 1.2, y2 = 2.5, z2 = 1.;
F64 val = 2.3f,val1,val2,val3;
val1 = x1 + (x2 - x1)* val;
val2 = y1 + (y2 - y1)* val;
val3 = z1 + (z2 - z1)* val;
LLVector3d vec3Da(x1,y1,z1),vec3Db(x2,y2,z2);
LLVector3d vec3d = lerp(vec3Da,vec3Db,val);
ensure("1:lerp failed", ((val1 ==vec3d.mdV[VX])&& (val2 ==vec3d.mdV[VY]) && (val3 ==vec3d.mdV[VZ])));
}
template<> template<>
void v3dmath_object::test<22>()
{
F64 x = 2.32, y = 1.212, z = -.12;
F64 min = 0.0001, max = 3.0;
LLVector3d vec3d(x,y,z);
ensure("1:clamp:Fail ", (TRUE == (vec3d.clamp(min, max))));
x = 0.000001f, z = 5.3f;
vec3d.setVec(x,y,z);
ensure("2:clamp:Fail ", (TRUE == (vec3d.clamp(min, max))));
}
template<> template<>
void v3dmath_object::test<23>()
{
F64 x = 10., y = 20., z = -15.;
F64 epsilon = .23425;
LLVector3d vec3Da(x,y,z), vec3Db(x,y,z);
ensure("1:are_parallel: Fail ", (TRUE == are_parallel(vec3Da,vec3Db,epsilon)));
F64 x1 = -12., y1 = -20., z1 = -100.;
vec3Db.clearVec();
vec3Db.setVec(x1,y1,z1);
ensure("2:are_parallel: Fail ", (FALSE == are_parallel(vec3Da,vec3Db,epsilon)));
}
template<> template<>
void v3dmath_object::test<24>()
{
#if LL_WINDOWS && _MSC_VER < 1400
skip("This fails on VS2003!");
#else
F64 x = 10., y = 20., z = -15.;
F64 angle1, angle2;
LLVector3d vec3Da(x,y,z), vec3Db(x,y,z);
angle1 = angle_between(vec3Da, vec3Db);
ensure("1:angle_between: Fail ", (0 == angle1));
F64 x1 = -1., y1 = -20., z1 = -1.;
vec3Da.clearVec();
vec3Da.setVec(x1,y1,z1);
angle2 = angle_between(vec3Da, vec3Db);
vec3Db.normVec();
vec3Da.normVec();
F64 angle = vec3Db*vec3Da;
angle = acos(angle);
ensure("2:angle_between: Fail ", (angle == angle2));
#endif
}
}

574
indra/test/v3math_tut.cpp Normal file
View File

@@ -0,0 +1,574 @@
/**
* @file v3math_tut.cpp
* @author Adroit
* @date 2007-02
* @brief v3math test cases.
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "lltut.h"
#include "llquaternion.h"
#include "linden_common.h"
#include "llquantize.h"
#include "v3dmath.h"
#include "m3math.h"
#include "v4math.h"
#include "llsd.h"
#include "v3math.h"
namespace tut
{
struct v3math_data
{
};
typedef test_group<v3math_data> v3math_test;
typedef v3math_test::object v3math_object;
tut::v3math_test v3math_testcase("v3math");
template<> template<>
void v3math_object::test<1>()
{
LLVector3 vec3;
ensure("1:LLVector3:Fail to initialize ", ((0.f == vec3.mV[VX]) && (0.f == vec3.mV[VY]) && (0.f == vec3.mV[VZ])));
F32 x = 2.32f, y = 1.212f, z = -.12f;
LLVector3 vec3a(x,y,z);
ensure("2:LLVector3:Fail to initialize ", ((2.32f == vec3a.mV[VX]) && (1.212f == vec3a.mV[VY]) && (-.12f == vec3a.mV[VZ])));
const F32 vec[3] = {1.2f ,3.2f, -4.2f};
LLVector3 vec3b(vec);
ensure("3:LLVector3:Fail to initialize ", ((1.2f == vec3b.mV[VX]) && (3.2f == vec3b.mV[VY]) && (-4.2f == vec3b.mV[VZ])));
}
template<> template<>
void v3math_object::test<2>()
{
F32 x = 2.32f, y = 1.212f, z = -.12f;
LLVector3 vec3(x,y,z);
LLVector3d vector3d(vec3);
LLVector3 vec3a(vector3d);
ensure("1:LLVector3:Fail to initialize ", vec3 == vec3a);
LLVector4 vector4(vec3);
LLVector3 vec3b(vector4);
ensure("2:LLVector3:Fail to initialize ", vec3 == vec3b);
}
template<> template<>
void v3math_object::test<3>()
{
S32 a = 231;
LLSD llsd(a);
LLVector3 vec3(llsd);
LLSD sd = vec3.getValue();
LLVector3 vec3a(sd);
ensure("1:LLVector3:Fail to initialize ", (vec3 == vec3a));
}
template<> template<>
void v3math_object::test<4>()
{
S32 a = 231;
LLSD llsd(a);
LLVector3 vec3(llsd),vec3a;
vec3a = vec3;
ensure("1:Operator= Fail to initialize " ,(vec3 == vec3a));
}
template<> template<>
void v3math_object::test<5>()
{
F32 x = 2.32f, y = 1.212f, z = -.12f;
LLVector3 vec3(x,y,z);
ensure("1:isFinite= Fail to initialize ", (TRUE == vec3.isFinite()));//need more test cases:
vec3.clearVec();
ensure("2:clearVec:Fail to set values ", ((0.f == vec3.mV[VX]) && (0.f == vec3.mV[VY]) && (0.f == vec3.mV[VZ])));
vec3.setVec(x,y,z);
ensure("3:setVec:Fail to set values ", ((2.32f == vec3.mV[VX]) && (1.212f == vec3.mV[VY]) && (-.12f == vec3.mV[VZ])));
vec3.zeroVec();
ensure("4:zeroVec:Fail to set values ", ((0.f == vec3.mV[VX]) && (0.f == vec3.mV[VY]) && (0.f == vec3.mV[VZ])));
}
template<> template<>
void v3math_object::test<6>()
{
F32 x = 2.32f, y = 1.212f, z = -.12f;
LLVector3 vec3(x,y,z),vec3a;
vec3.abs();
ensure("1:abs:Fail ", ((x == vec3.mV[VX]) && (y == vec3.mV[VY]) && (-z == vec3.mV[VZ])));
vec3a.setVec(vec3);
ensure("2:setVec:Fail to initialize ", (vec3a == vec3));
const F32 vec[3] = {1.2f ,3.2f, -4.2f};
vec3.clearVec();
vec3.setVec(vec);
ensure("3:setVec:Fail to initialize ", ((1.2f == vec3.mV[VX]) && (3.2f == vec3.mV[VY]) && (-4.2f == vec3.mV[VZ])));
vec3a.clearVec();
LLVector3d vector3d(vec3);
vec3a.setVec(vector3d);
ensure("4:setVec:Fail to initialize ", (vec3 == vec3a));
LLVector4 vector4(vec3);
vec3a.clearVec();
vec3a.setVec(vector4);
ensure("5:setVec:Fail to initialize ", (vec3 == vec3a));
}
template<> template<>
void v3math_object::test<7>()
{
F32 x = 2.32f, y = 3.212f, z = -.12f;
F32 min = 0.0001f, max = 3.0f;
LLVector3 vec3(x,y,z);
ensure("1:clamp:Fail ", TRUE == vec3.clamp(min, max) && x == vec3.mV[VX] && max == vec3.mV[VY] && min == vec3.mV[VZ]);
x = 1.f, y = 2.2f, z = 2.8f;
vec3.setVec(x,y,z);
ensure("2:clamp:Fail ", FALSE == vec3.clamp(min, max));
}
template<> template<>
void v3math_object::test<8>()
{
F32 x = 2.32f, y = 1.212f, z = -.12f;
LLVector3 vec3(x,y,z);
ensure("1:magVecSquared:Fail ", is_approx_equal(vec3.magVecSquared(), (x*x + y*y + z*z)));
ensure("2:magVec:Fail ", is_approx_equal(vec3.magVec(), fsqrtf(x*x + y*y + z*z)));
}
template<> template<>
void v3math_object::test<9>()
{
F32 x =-2.0f, y = -3.0f, z = 1.23f ;
LLVector3 vec3(x,y,z);
ensure("1:abs():Fail ", (TRUE == vec3.abs()));
ensure("2:isNull():Fail", (FALSE == vec3.isNull())); //Returns TRUE if vector has a _very_small_ length
x =.00000001f, y = .000001001f, z = .000001001f;
vec3.setVec(x,y,z);
ensure("3:isNull(): Fail ", (TRUE == vec3.isNull()));
}
template<> template<>
void v3math_object::test<10>()
{
F32 x =-2.0f, y = -3.0f, z = 1.f ;
LLVector3 vec3(x,y,z),vec3a;
ensure("1:isExactlyZero():Fail ", (TRUE == vec3a.isExactlyZero()));
vec3a = vec3a.scaleVec(vec3);
ensure("2:scaleVec: Fail ", vec3a.mV[VX] == 0.f && vec3a.mV[VY] == 0.f && vec3a.mV[VZ] == 0.f);
vec3a.setVec(x,y,z);
vec3a = vec3a.scaleVec(vec3);
ensure("3:scaleVec: Fail ", ((4 == vec3a.mV[VX]) && (9 == vec3a.mV[VY]) &&(1 == vec3a.mV[VZ])));
ensure("4:isExactlyZero():Fail ", (FALSE == vec3.isExactlyZero()));
}
template<> template<>
void v3math_object::test<11>()
{
F32 x =20.0f, y = 30.0f, z = 15.f ;
F32 angle = 100.f;
LLVector3 vec3(x,y,z),vec3a(1.f,2.f,3.f);
vec3a = vec3a.rotVec(angle, vec3);
LLVector3 vec3b(1.f,2.f,3.f);
vec3b = vec3b.rotVec(angle, vec3);
ensure_equals("rotVec():Fail" ,vec3b,vec3a);
}
template<> template<>
void v3math_object::test<12>()
{
F32 x =-2.0f, y = -3.0f, z = 1.f ;
LLVector3 vec3(x,y,z);
ensure("1:operator [] failed",( x == vec3[0]));
ensure("2:operator [] failed",( y == vec3[1]));
ensure("3:operator [] failed",( z == vec3[2]));
vec3.clearVec();
x = 23.f, y = -.2361f, z = 3.25;
vec3.setVec(x,y,z);
F32 &ref1 = vec3[0];
ensure("4:operator [] failed",( ref1 == vec3[0]));
F32 &ref2 = vec3[1];
ensure("5:operator [] failed",( ref2 == vec3[1]));
F32 &ref3 = vec3[2];
ensure("6:operator [] failed",( ref3 == vec3[2]));
}
template<> template<>
void v3math_object::test<13>()
{
F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f;
F32 val1, val2, val3;
LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2), vec3b;
vec3b = vec3 + vec3a ;
val1 = x1+x2;
val2 = y1+y2;
val3 = z1+z2;
ensure("1:operator+ failed",(val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ]));
vec3.clearVec();
vec3a.clearVec();
vec3b.clearVec();
x1 = -.235f, y1 = -24.32f,z1 = 2.13f, x2 = -2.3f, y2 = 1.f, z2 = 34.21f;
vec3.setVec(x1,y1,z1);
vec3a.setVec(x2,y2,z2);
vec3b = vec3 + vec3a;
val1 = x1+x2;
val2 = y1+y2;
val3 = z1+z2;
ensure("2:operator+ failed",(val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ]));
}
template<> template<>
void v3math_object::test<14>()
{
F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f;
F32 val1, val2, val3;
LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2), vec3b;
vec3b = vec3 - vec3a ;
val1 = x1-x2;
val2 = y1-y2;
val3 = z1-z2;
ensure("1:operator- failed",(val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ]));
vec3.clearVec();
vec3a.clearVec();
vec3b.clearVec();
x1 = -.235f, y1 = -24.32f,z1 = 2.13f, x2 = -2.3f, y2 = 1.f, z2 = 34.21f;
vec3.setVec(x1,y1,z1);
vec3a.setVec(x2,y2,z2);
vec3b = vec3 - vec3a;
val1 = x1-x2;
val2 = y1-y2;
val3 = z1-z2;
ensure("2:operator- failed",(val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ]));
}
template<> template<>
void v3math_object::test<15>()
{
F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f;
F32 val1, val2, val3;
LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2);
val1 = vec3 * vec3a;
val2 = x1*x2 + y1*y2 + z1*z2;
ensure_equals("1:operator* failed",val1,val2);
vec3a.clearVec();
F32 mulVal = 4.332f;
vec3a = vec3 * mulVal;
val1 = x1*mulVal;
val2 = y1*mulVal;
val3 = z1*mulVal;
ensure("2:operator* failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY])&& (val3 == vec3a.mV[VZ]));
vec3a.clearVec();
vec3a = mulVal * vec3;
ensure("3:operator* failed ", (val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY])&& (val3 == vec3a.mV[VZ]));
}
template<> template<>
void v3math_object::test<16>()
{
F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f;
F32 val1, val2, val3;
LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2), vec3b;
vec3b = vec3 % vec3a ;
val1 = y1*z2 - y2*z1;
val2 = z1*x2 -z2*x1;
val3 = x1*y2-x2*y1;
ensure("1:operator% failed",(val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ]));
vec3.clearVec();
vec3a.clearVec();
vec3b.clearVec();
x1 =112.f, y1 = 22.3f,z1 = 1.2f, x2 = -2.3f, y2 = 341.11f, z2 = 1234.234f;
vec3.setVec(x1,y1,z1);
vec3a.setVec(x2,y2,z2);
vec3b = vec3 % vec3a ;
val1 = y1*z2 - y2*z1;
val2 = z1*x2 -z2*x1;
val3 = x1*y2-x2*y1;
ensure("2:operator% failed ", (val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ]));
}
template<> template<>
void v3math_object::test<17>()
{
F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, div = 3.2f;
F32 t = 1.f / div, val1, val2, val3;
LLVector3 vec3(x1,y1,z1), vec3a;
vec3a = vec3 / div;
val1 = x1 * t;
val2 = y1 * t;
val3 = z1 *t;
ensure("1:operator/ failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY]) && (val3 == vec3a.mV[VZ]));
vec3a.clearVec();
x1 = -.235f, y1 = -24.32f, z1 = .342f, div = -2.2f;
t = 1.f / div;
vec3.setVec(x1,y1,z1);
vec3a = vec3 / div;
val1 = x1 * t;
val2 = y1 * t;
val3 = z1 *t;
ensure("2:operator/ failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY]) && (val3 == vec3a.mV[VZ]));
}
template<> template<>
void v3math_object::test<18>()
{
F32 x1 =1.f, y1 = 2.f,z1 = 1.2f;
LLVector3 vec3(x1,y1,z1), vec3a(x1,y1,z1);
ensure("1:operator== failed",(vec3 == vec3a));
vec3a.clearVec();
x1 = -.235f, y1 = -24.32f, z1 = .342f;
vec3.clearVec();
vec3a.clearVec();
vec3.setVec(x1,y1,z1);
vec3a.setVec(x1,y1,z1);
ensure("2:operator== failed ", (vec3 == vec3a));
}
template<> template<>
void v3math_object::test<19>()
{
F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 =112.f, y2 = 2.234f,z2 = 11.2f;;
LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2);
ensure("1:operator!= failed",(vec3a != vec3));
vec3.clearVec();
vec3.clearVec();
vec3a.setVec(vec3);
ensure("2:operator!= failed", ( FALSE == (vec3a != vec3)));
}
template<> template<>
void v3math_object::test<20>()
{
F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 =112.f, y2 = 2.2f,z2 = 11.2f;;
LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2);
vec3a += vec3;
F32 val1, val2, val3;
val1 = x1+x2;
val2 = y1+y2;
val3 = z1+z2;
ensure("1:operator+= failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY])&& (val3 == vec3a.mV[VZ]));
}
template<> template<>
void v3math_object::test<21>()
{
F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 =112.f, y2 = 2.2f,z2 = 11.2f;;
LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2);
vec3a -= vec3;
F32 val1, val2, val3;
val1 = x2-x1;
val2 = y2-y1;
val3 = z2-z1;
ensure("1:operator-= failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY])&& (val3 == vec3a.mV[VZ]));
}
template<> template<>
void v3math_object::test<22>()
{
F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f;
F32 val1,val2,val3;
LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2);
vec3a *= vec3;
val1 = x1*x2;
val2 = y1*y2;
val3 = z1*z2;
ensure("1:operator*= failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY])&& (val3 == vec3a.mV[VZ]));
F32 mulVal = 4.332f;
vec3 *=mulVal;
val1 = x1*mulVal;
val2 = y1*mulVal;
val3 = z1*mulVal;
ensure("2:operator*= failed ", is_approx_equal(val1, vec3.mV[VX]) && is_approx_equal(val2, vec3.mV[VY]) && is_approx_equal(val3, vec3.mV[VZ]));
}
template<> template<>
void v3math_object::test<23>()
{
F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f;
LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2),vec3b;
vec3b = vec3a % vec3;
vec3a %= vec3;
ensure_equals("1:operator%= failed",vec3a,vec3b);
}
template<> template<>
void v3math_object::test<24>()
{
F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, div = 3.2f;
F32 t = 1.f / div, val1, val2, val3;
LLVector3 vec3a(x1,y1,z1);
vec3a /= div;
val1 = x1 * t;
val2 = y1 * t;
val3 = z1 *t;
ensure("1:operator/= failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY]) && (val3 == vec3a.mV[VZ]));
}
template<> template<>
void v3math_object::test<25>()
{
F32 x1 =1.f, y1 = 2.f,z1 = 1.2f;
LLVector3 vec3(x1,y1,z1), vec3a;
vec3a = -vec3;
ensure("1:operator- failed",(-vec3a == vec3));
}
template<> template<>
void v3math_object::test<26>()
{
F32 x1 =1.f, y1 = 2.f,z1 = 1.2f;
std::ostringstream stream1, stream2;
LLVector3 vec3(x1,y1,z1), vec3a;
stream1 << vec3;
vec3a.setVec(x1,y1,z1);
stream2 << vec3a;
ensure("1:operator << failed",(stream1.str() == stream2.str()));
}
template<> template<>
void v3math_object::test<27>()
{
F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 1.11f, z2 = 1234.234f;
LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2);
ensure("1:operator< failed", (TRUE == vec3 < vec3a));
x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 2.f, z2 = 1234.234f;
vec3.setVec(x1,y1,z1);
vec3a.setVec(x2,y2,z2);
ensure("2:operator< failed ", (TRUE == vec3 < vec3a));
x1 =2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f,
vec3.setVec(x1,y1,z1);
vec3a.setVec(x2,y2,z2);
ensure("3:operator< failed ", (FALSE == vec3 < vec3a));
}
template<> template<>
void v3math_object::test<28>()
{
F32 x1 =1.23f, y1 = 2.f,z1 = 4.f;
std::string buf("1.23 2. 4");
LLVector3 vec3, vec3a(x1,y1,z1);
LLVector3::parseVector3(buf, &vec3);
ensure_equals("1:parseVector3 failed", vec3, vec3a);
}
template<> template<>
void v3math_object::test<29>()
{
F32 x1 =1.f, y1 = 2.f,z1 = 4.f;
LLVector3 vec3(x1,y1,z1),vec3a,vec3b;
vec3a.setVec(1,1,1);
vec3a.scaleVec(vec3);
ensure_equals("1:scaleVec failed", vec3, vec3a);
vec3a.clearVec();
vec3a.setVec(x1,y1,z1);
vec3a.scaleVec(vec3);
ensure("2:scaleVec failed", ((1.f ==vec3a.mV[VX])&& (4.f ==vec3a.mV[VY]) && (16.f ==vec3a.mV[VZ])));
}
template<> template<>
void v3math_object::test<30>()
{
F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 1.11f, z2 = 1234.234f;
F32 val = 2.3f,val1,val2,val3;
val1 = x1 + (x2 - x1)* val;
val2 = y1 + (y2 - y1)* val;
val3 = z1 + (z2 - z1)* val;
LLVector3 vec3(x1,y1,z1),vec3a(x2,y2,z2);
LLVector3 vec3b = lerp(vec3,vec3a,val);
ensure("1:lerp failed", ((val1 ==vec3b.mV[VX])&& (val2 ==vec3b.mV[VY]) && (val3 ==vec3b.mV[VZ])));
}
template<> template<>
void v3math_object::test<31>()
{
F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 1.f, z2 = 1.f;
F32 val1,val2;
LLVector3 vec3(x1,y1,z1),vec3a(x2,y2,z2);
val1 = dist_vec(vec3,vec3a);
val2 = fsqrtf((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2) + (z1 - z2)* (z1 -z2));
ensure_equals("1:dist_vec: Fail ",val2, val1);
val1 = dist_vec_squared(vec3,vec3a);
val2 =((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2) + (z1 - z2)* (z1 -z2));
ensure_equals("2:dist_vec_squared: Fail ",val2, val1);
val1 = dist_vec_squared2D(vec3, vec3a);
val2 =(x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2);
ensure_equals("3:dist_vec_squared2D: Fail ",val2, val1);
}
template<> template<>
void v3math_object::test<32>()
{
F32 x =12.3524f, y = -342.f,z = 4.126341f;
LLVector3 vec3(x,y,z);
F32 mag = vec3.normVec();
mag = 1.f/ mag;
F32 val1 = x* mag, val2 = y* mag, val3 = z* mag;
ensure("1:normVec: Fail ", is_approx_equal(val1, vec3.mV[VX]) && is_approx_equal(val2, vec3.mV[VY]) && is_approx_equal(val3, vec3.mV[VZ]));
x = 0.000000001f, y = 0.f, z = 0.f;
vec3.clearVec();
vec3.setVec(x,y,z);
mag = vec3.normVec();
val1 = x* mag, val2 = y* mag, val3 = z* mag;
ensure("2:normVec: Fail ", (mag == 0.) && (0. == vec3.mV[VX]) && (0. == vec3.mV[VY])&& (0. == vec3.mV[VZ]));
}
template<> template<>
void v3math_object::test<33>()
{
F32 x = -202.23412f, y = 123.2312f, z = -89.f;
LLVector3 vec(x,y,z);
vec.snap(2);
ensure("1:snap: Fail ", is_approx_equal(-202.23f, vec.mV[VX]) && is_approx_equal(123.23f, vec.mV[VY]) && is_approx_equal(-89.f, vec.mV[VZ]));
}
template<> template<>
void v3math_object::test<34>()
{
F32 x = 10.f, y = 20.f, z = -15.f;
F32 x1, y1, z1;
F32 lowerxy = 0.f, upperxy = 1.0f, lowerz = -1.0f, upperz = 1.f;
LLVector3 vec3(x,y,z);
vec3.quantize16(lowerxy,upperxy,lowerz,upperz);
x1 = U16_to_F32(F32_to_U16(x, lowerxy, upperxy), lowerxy, upperxy);
y1 = U16_to_F32(F32_to_U16(y, lowerxy, upperxy), lowerxy, upperxy);
z1 = U16_to_F32(F32_to_U16(z, lowerz, upperz), lowerz, upperz);
ensure("1:quantize16: Fail ", is_approx_equal(x1, vec3.mV[VX]) && is_approx_equal(y1, vec3.mV[VY]) && is_approx_equal(z1, vec3.mV[VZ]));
LLVector3 vec3a(x,y,z);
vec3a.quantize8(lowerxy,upperxy,lowerz,upperz);
x1 = U8_to_F32(F32_to_U8(x, lowerxy, upperxy), lowerxy, upperxy);
y1 = U8_to_F32(F32_to_U8(y, lowerxy, upperxy), lowerxy, upperxy);
z1 = U8_to_F32(F32_to_U8(z, lowerz, upperz), lowerz, upperz);
ensure("2:quantize8: Fail ", is_approx_equal(x1, vec3a.mV[VX]) && is_approx_equal(y1, vec3a.mV[VY]) && is_approx_equal(z1, vec3a.mV[VZ]));
}
}

365
indra/test/v4color_tut.cpp Normal file
View File

@@ -0,0 +1,365 @@
/**
* @file v4color_tut.cpp
* @author Adroit
* @date 2007-03
* @brief v4color test cases.
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "lltut.h"
#include "v4coloru.h"
#include "llsd.h"
#include "v3color.h"
#include "v4color.h"
namespace tut
{
struct v4color_data
{
};
typedef test_group<v4color_data> v4color_test;
typedef v4color_test::object v4color_object;
tut::v4color_test v4color_testcase("v4color");
template<> template<>
void v4color_object::test<1>()
{
LLColor4 llcolor4;
ensure("1:LLColor4:Fail to initialize ", ((0 == llcolor4.mV[VX]) && (0 == llcolor4.mV[VY]) && (0 == llcolor4.mV[VZ])&& (1.0f == llcolor4.mV[VW])));
F32 r = 0x20, g = 0xFFFF, b = 0xFF, a = 0xAF;
LLColor4 llcolor4a(r,g,b);
ensure("2:LLColor4:Fail to initialize ", ((r == llcolor4a.mV[VX]) && (g == llcolor4a.mV[VY]) && (b == llcolor4a.mV[VZ])&& (1.0f == llcolor4a.mV[VW])));
LLColor4 llcolor4b(r,g,b,a);
ensure("3:LLColor4:Fail to initialize ", ((r == llcolor4b.mV[VX]) && (g == llcolor4b.mV[VY]) && (b == llcolor4b.mV[VZ])&& (a == llcolor4b.mV[VW])));
const F32 vec[4] = {.112f ,23.2f, -4.2f, -.0001f};
LLColor4 llcolor4c(vec);
ensure("4:LLColor4:Fail to initialize ", ((vec[0] == llcolor4c.mV[VX]) && (vec[1] == llcolor4c.mV[VY]) && (vec[2] == llcolor4c.mV[VZ])&& (vec[3] == llcolor4c.mV[VW])));
LLColor3 llcolor3(-2.23f,1.01f,42.3f);
F32 val = -.1f;
LLColor4 llcolor4d(llcolor3,val);
ensure("5:LLColor4:Fail to initialize ", ((llcolor3.mV[VX] == llcolor4d.mV[VX]) && (llcolor3.mV[VY] == llcolor4d.mV[VY]) && (llcolor3.mV[VZ] == llcolor4d.mV[VZ])&& (val == llcolor4d.mV[VW])));
LLSD sd = llcolor4d.getValue();
LLColor4 llcolor4e(sd);
ensure_equals("6:LLColor4:(LLSD) failed ", llcolor4d, llcolor4e);
U8 r1 = 0xF2, g1 = 0xFA, b1 = 0xBF;
LLColor4U color4u(r1,g1,b1);
LLColor4 llcolor4g(color4u);
const F32 SCALE = 1.f/255.f;
F32 r2 = r1*SCALE, g2 = g1* SCALE, b2 = b1* SCALE;
ensure("7:LLColor4:Fail to initialize ", ((r2 == llcolor4g.mV[VX]) && (g2 == llcolor4g.mV[VY]) && (b2 == llcolor4g.mV[VZ])));
}
template<> template<>
void v4color_object::test<2>()
{
LLColor4 llcolor(1.0, 2.0, 3.0, 4.0);
LLSD llsd = llcolor.getValue();
LLColor4 llcolor4(llsd), llcolor4a;
llcolor4a.setValue(llsd);
ensure("setValue: failed", (llcolor4 == llcolor4a));
LLSD sd = llcolor4a.getValue();
LLColor4 llcolor4b(sd);
ensure("getValue: Failed ", (llcolor4b == llcolor4a));
}
template<> template<>
void v4color_object::test<3>()
{
F32 r = 0x20, g = 0xFFFF, b = 0xFF,a = 0xAF;
LLColor4 llcolor4(r,g,b,a);
llcolor4.setToBlack();
ensure("setToBlack:Fail to set the black ", ((0 == llcolor4.mV[VX]) && (0 == llcolor4.mV[VY]) && (0 == llcolor4.mV[VZ])&& (1.0f == llcolor4.mV[VW])));
llcolor4.setToWhite();
ensure("setToWhite:Fail to set the white ", ((1.f == llcolor4.mV[VX]) && (1.f == llcolor4.mV[VY]) && (1.f == llcolor4.mV[VZ])&& (1.0f == llcolor4.mV[VW])));
}
template<> template<>
void v4color_object::test<4>()
{
F32 r = 0x20, g = 0xFFFF, b = 0xFF, a = 0xAF;
LLColor4 llcolor4;
llcolor4.setVec(r,g,b);
ensure("1:setVec:Fail to set the values ", ((r == llcolor4.mV[VX]) && (g == llcolor4.mV[VY]) && (b == llcolor4.mV[VZ])&& (1.f == llcolor4.mV[VW])));
llcolor4.setVec(r,g,b,a);
ensure("2:setVec:Fail to set the values ", ((r == llcolor4.mV[VX]) && (g == llcolor4.mV[VY]) && (b == llcolor4.mV[VZ])&& (a == llcolor4.mV[VW])));
LLColor4 llcolor4a;
llcolor4a.setVec(llcolor4);
ensure_equals("3:setVec:Fail to set the values ", llcolor4a,llcolor4);
LLColor3 llcolor3(-2.23f,1.01f,42.3f);
llcolor4a.setVec(llcolor3);
ensure("4:setVec:Fail to set the values ", ((llcolor3.mV[VX] == llcolor4a.mV[VX]) && (llcolor3.mV[VY] == llcolor4a.mV[VY]) && (llcolor3.mV[VZ] == llcolor4a.mV[VZ])));
F32 val = -.33f;
llcolor4a.setVec(llcolor3,val);
ensure("4:setVec:Fail to set the values ", ((llcolor3.mV[VX] == llcolor4a.mV[VX]) && (llcolor3.mV[VY] == llcolor4a.mV[VY]) && (llcolor3.mV[VZ] == llcolor4a.mV[VZ]) && (val == llcolor4a.mV[VW])));
const F32 vec[4] = {.112f ,23.2f, -4.2f, -.0001f};
LLColor4 llcolor4c;
llcolor4c.setVec(vec);
ensure("5:setVec:Fail to initialize ", ((vec[0] == llcolor4c.mV[VX]) && (vec[1] == llcolor4c.mV[VY]) && (vec[2] == llcolor4c.mV[VZ])&& (vec[3] == llcolor4c.mV[VW])));
U8 r1 = 0xF2, g1 = 0xFA, b1= 0xBF;
LLColor4U color4u(r1,g1,b1);
llcolor4.setVec(color4u);
const F32 SCALE = 1.f/255.f;
F32 r2 = r1*SCALE, g2 = g1* SCALE, b2 = b1* SCALE;
ensure("6:setVec:Fail to initialize ", ((r2 == llcolor4.mV[VX]) && (g2 == llcolor4.mV[VY]) && (b2 == llcolor4.mV[VZ])));
}
template<> template<>
void v4color_object::test<5>()
{
F32 alpha = 0xAF;
LLColor4 llcolor4;
llcolor4.setAlpha(alpha);
ensure("setAlpha:Fail to initialize ", (alpha == llcolor4.mV[VW]));
}
template<> template<>
void v4color_object::test<6>()
{
F32 r = 0x20, g = 0xFFFF, b = 0xFF;
LLColor4 llcolor4(r,g,b);
ensure("magVecSquared:Fail ", is_approx_equal(llcolor4.magVecSquared(), (r*r + g*g + b*b)));
ensure("magVec:Fail ", is_approx_equal(llcolor4.magVec(), fsqrtf(r*r + g*g + b*b)));
}
template<> template<>
void v4color_object::test<7>()
{
F32 r = 0x20, g = 0xFFFF, b = 0xFF;
LLColor4 llcolor4(r,g,b);
F32 vecMag = llcolor4.normVec();
F32 mag = fsqrtf(r*r + g*g + b*b);
F32 oomag = 1.f / mag;
F32 val1 = r * oomag, val2 = g * oomag, val3 = b * oomag;
ensure("1:normVec failed ", (is_approx_equal(val1, llcolor4.mV[0]) && is_approx_equal(val2, llcolor4.mV[1]) && is_approx_equal(val3, llcolor4.mV[2]) && is_approx_equal(vecMag, mag)));
}
template<> template<>
void v4color_object::test<8>()
{
LLColor4 llcolor4;
ensure("1:isOpaque failed ",(1 == llcolor4.isOpaque()));
F32 r = 0x20, g = 0xFFFF, b = 0xFF,a = 1.f;
llcolor4.setVec(r,g,b,a);
ensure("2:isOpaque failed ",(1 == llcolor4.isOpaque()));
a = 2.f;
llcolor4.setVec(r,g,b,a);
ensure("3:isOpaque failed ",(0 == llcolor4.isOpaque()));
}
template<> template<>
void v4color_object::test<9>()
{
F32 r = 0x20, g = 0xFFFF, b = 0xFF;
LLColor4 llcolor4(r,g,b);
ensure("1:operator [] failed",( r == llcolor4[0]));
ensure("2:operator [] failed",( g == llcolor4[1]));
ensure("3:operator [] failed",( b == llcolor4[2]));
r = 0xA20, g = 0xFBFF, b = 0xFFF;
llcolor4.setVec(r,g,b);
F32 &ref1 = llcolor4[0];
ensure("4:operator [] failed",( ref1 == llcolor4[0]));
F32 &ref2 = llcolor4[1];
ensure("5:operator [] failed",( ref2 == llcolor4[1]));
F32 &ref3 = llcolor4[2];
ensure("6:operator [] failed",( ref3 == llcolor4[2]));
}
template<> template<>
void v4color_object::test<10>()
{
F32 r = 0x20, g = 0xFFFF, b = 0xFF;
LLColor3 llcolor3(r,g,b);
LLColor4 llcolor4a,llcolor4b;
llcolor4a = llcolor3;
ensure("Operator=:Fail to initialize ", ((llcolor3.mV[0] == llcolor4a.mV[VX]) && (llcolor3.mV[1] == llcolor4a.mV[VY]) && (llcolor3.mV[2] == llcolor4a.mV[VZ])));
LLSD sd = llcolor4a.getValue();
llcolor4b = sd;
ensure_equals("Operator= LLSD:Fail ", llcolor4a, llcolor4b);
}
template<> template<>
void v4color_object::test<11>()
{
F32 r = 0x20, g = 0xFFFF, b = 0xFF;
std::ostringstream stream1, stream2;
LLColor4 llcolor4a(r,g,b),llcolor4b;
stream1 << llcolor4a;
llcolor4b.setVec(r,g,b);
stream2 << llcolor4b;
ensure("operator << failed ", (stream1.str() == stream2.str()));
}
template<> template<>
void v4color_object::test<12>()
{
F32 r1 = 0x20, g1 = 0xFFFF, b1 = 0xFF;
F32 r2 = 0xABF, g2 = 0xFB, b2 = 0xFFF;
LLColor4 llcolor4a(r1,g1,b1),llcolor4b(r2,g2,b2),llcolor4c;
llcolor4c = llcolor4b + llcolor4a;
ensure("operator+:Fail to Add the values ", (is_approx_equal(r1+r2,llcolor4c.mV[VX]) && is_approx_equal(g1+g2,llcolor4c.mV[VY]) && is_approx_equal(b1+b2,llcolor4c.mV[VZ])));
llcolor4b += llcolor4a;
ensure("operator+=:Fail to Add the values ", (is_approx_equal(r1+r2,llcolor4b.mV[VX]) && is_approx_equal(g1+g2,llcolor4b.mV[VY]) && is_approx_equal(b1+b2,llcolor4b.mV[VZ])));
}
template<> template<>
void v4color_object::test<13>()
{
F32 r1 = 0x20, g1 = 0xFFFF, b1 = 0xFF;
F32 r2 = 0xABF, g2 = 0xFB, b2 = 0xFFF;
LLColor4 llcolor4a(r1,g1,b1),llcolor4b(r2,g2,b2),llcolor4c;
llcolor4c = llcolor4a - llcolor4b;
ensure("operator-:Fail to subtract the values ", (is_approx_equal(r1-r2,llcolor4c.mV[VX]) && is_approx_equal(g1-g2,llcolor4c.mV[VY]) && is_approx_equal(b1-b2,llcolor4c.mV[VZ])));
llcolor4a -= llcolor4b;
ensure("operator-=:Fail to subtract the values ", (is_approx_equal(r1-r2,llcolor4a.mV[VX]) && is_approx_equal(g1-g2,llcolor4a.mV[VY]) && is_approx_equal(b1-b2,llcolor4a.mV[VZ])));
}
template<> template<>
void v4color_object::test<14>()
{
F32 r1 = 0x20, g1 = 0xFFFF, b1 = 0xFF;
F32 r2 = 0xABF, g2 = 0xFB, b2 = 0xFFF;
LLColor4 llcolor4a(r1,g1,b1),llcolor4b(r2,g2,b2),llcolor4c;
llcolor4c = llcolor4a * llcolor4b;
ensure("1:operator*:Fail to multiply the values", (is_approx_equal(r1*r2,llcolor4c.mV[VX]) && is_approx_equal(g1*g2,llcolor4c.mV[VY]) && is_approx_equal(b1*b2,llcolor4c.mV[VZ])));
F32 mulVal = 3.33f;
llcolor4c = llcolor4a * mulVal;
ensure("2:operator*:Fail ", (is_approx_equal(r1*mulVal,llcolor4c.mV[VX]) && is_approx_equal(g1*mulVal,llcolor4c.mV[VY]) && is_approx_equal(b1*mulVal,llcolor4c.mV[VZ])));
llcolor4c = mulVal * llcolor4a;
ensure("3:operator*:Fail to multiply the values", (is_approx_equal(r1*mulVal,llcolor4c.mV[VX]) && is_approx_equal(g1*mulVal,llcolor4c.mV[VY]) && is_approx_equal(b1*mulVal,llcolor4c.mV[VZ])));
llcolor4a *= mulVal;
ensure("4:operator*=:Fail to multiply the values ", (is_approx_equal(r1*mulVal,llcolor4a.mV[VX]) && is_approx_equal(g1*mulVal,llcolor4a.mV[VY]) && is_approx_equal(b1*mulVal,llcolor4a.mV[VZ])));
LLColor4 llcolor4d(r1,g1,b1),llcolor4e(r2,g2,b2);
llcolor4e *= llcolor4d;
ensure("5:operator*=:Fail to multiply the values ", (is_approx_equal(r1*r2,llcolor4e.mV[VX]) && is_approx_equal(g1*g2,llcolor4e.mV[VY]) && is_approx_equal(b1*b2,llcolor4e.mV[VZ])));
}
template<> template<>
void v4color_object::test<15>()
{
F32 r = 0x20, g = 0xFFFF, b = 0xFF,a = 0x30;
F32 div = 12.345f;
LLColor4 llcolor4a(r,g,b,a),llcolor4b;
llcolor4b = llcolor4a % div;//chnage only alpha value nor r,g,b;
ensure("1operator%:Fail ", (is_approx_equal(r,llcolor4b.mV[VX]) && is_approx_equal(g,llcolor4b.mV[VY]) && is_approx_equal(b,llcolor4b.mV[VZ])&& is_approx_equal(div*a,llcolor4b.mV[VW])));
llcolor4b = div % llcolor4a;
ensure("2operator%:Fail ", (is_approx_equal(r,llcolor4b.mV[VX]) && is_approx_equal(g,llcolor4b.mV[VY]) && is_approx_equal(b,llcolor4b.mV[VZ])&& is_approx_equal(div*a,llcolor4b.mV[VW])));
llcolor4a %= div;
ensure("operator%=:Fail ", (is_approx_equal(a*div,llcolor4a.mV[VW])));
}
template<> template<>
void v4color_object::test<16>()
{
F32 r = 0x20, g = 0xFFFF, b = 0xFF,a = 0x30;
LLColor4 llcolor4a(r,g,b,a),llcolor4b;
llcolor4b = llcolor4a;
ensure("1:operator== failed to ensure the equality ", (llcolor4b == llcolor4a));
F32 r1 = 0x2, g1 = 0xFF, b1 = 0xFA;
LLColor3 llcolor3(r1,g1,b1);
llcolor4b = llcolor3;
ensure("2:operator== failed to ensure the equality ", (llcolor4b == llcolor3));
ensure("2:operator!= failed to ensure the equality ", (llcolor4a != llcolor3));
}
template<> template<>
void v4color_object::test<17>()
{
F32 r = 0x20, g = 0xFFFF, b = 0xFF;
LLColor4 llcolor4a(r,g,b),llcolor4b;
LLColor3 llcolor3 = vec4to3(llcolor4a);
ensure("vec4to3:Fail to convert vec4 to vec3 ", (is_approx_equal(llcolor3.mV[VX],llcolor4a.mV[VX]) && is_approx_equal(llcolor3.mV[VY],llcolor4a.mV[VY]) && is_approx_equal(llcolor3.mV[VZ],llcolor4a.mV[VZ])));
llcolor4b = vec3to4(llcolor3);
ensure_equals("vec3to4:Fail to convert vec3 to vec4 ", llcolor4b, llcolor4a);
}
template<> template<>
void v4color_object::test<18>()
{
F32 r1 = 0x20, g1 = 0xFFFF, b1 = 0xFF, val = 0x20;
F32 r2 = 0xABF, g2 = 0xFB, b2 = 0xFFF;
LLColor4 llcolor4a(r1,g1,b1),llcolor4b(r2,g2,b2),llcolor4c;
llcolor4c = lerp(llcolor4a,llcolor4b,val);
ensure("lerp:Fail ", (is_approx_equal(r1 + (r2 - r1)* val,llcolor4c.mV[VX]) && is_approx_equal(g1 + (g2 - g1)* val,llcolor4c.mV[VY]) && is_approx_equal(b1 + (b2 - b1)* val,llcolor4c.mV[VZ])));
}
template<> template<>
void v4color_object::test<19>()
{
F32 r = 12.0f, g = -2.3f, b = 1.32f, a = 5.0f;
LLColor4 llcolor4a(r,g,b,a),llcolor4b;
std::string color("red");
LLColor4::parseColor(color, &llcolor4b);
ensure_equals("1:parseColor() failed to parse the color value ", llcolor4b, LLColor4::red);
color = "12.0, -2.3, 1.32, 5.0";
LLColor4::parseColor(color, &llcolor4b);
llcolor4a = llcolor4a * (1.f / 255.f);
ensure_equals("2:parseColor() failed to parse the color value ", llcolor4a,llcolor4b);
color = "yellow5";
llcolor4a.setVec(r,g,b);
LLColor4::parseColor(color, &llcolor4a);
ensure_equals("3:parseColor() failed to parse the color value ", llcolor4a, LLColor4::yellow5);
}
template<> template<>
void v4color_object::test<20>()
{
F32 r = 12.0f, g = -2.3f, b = 1.32f, a = 5.0f;
LLColor4 llcolor4a(r,g,b,a),llcolor4b;
std::string color("12.0, -2.3, 1.32, 5.0");
LLColor4::parseColor4(color, &llcolor4b);
ensure_equals("parseColor4() failed to parse the color value ", llcolor4a, llcolor4b);
}
}

341
indra/test/v4coloru_tut.cpp Normal file
View File

@@ -0,0 +1,341 @@
/**
* @file v4coloru_tut.cpp
* @author Adroit
* @date 2007-03
* @brief v4coloru test cases.
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "lltut.h"
#include "llsd.h"
#include "v4coloru.h"
namespace tut
{
struct v4coloru_data
{
};
typedef test_group<v4coloru_data> v4coloru_test;
typedef v4coloru_test::object v4coloru_object;
tut::v4coloru_test v4coloru_testcase("v4coloru");
template<> template<>
void v4coloru_object::test<1>()
{
LLColor4U llcolor4u;
ensure("1:LLColor4u:Fail to initialize ", ((0 == llcolor4u.mV[VX]) && (0 == llcolor4u.mV[VY]) && (0 == llcolor4u.mV[VZ])&& (255 == llcolor4u.mV[VW])));
U8 r = 0x12, g = 0xFF, b = 0xAF, a = 0x23;
LLColor4U llcolor4u1(r,g,b);
ensure("2:LLColor4u:Fail to initialize ", ((r == llcolor4u1.mV[VX]) && (g == llcolor4u1.mV[VY]) && (b == llcolor4u1.mV[VZ])&& (255 == llcolor4u1.mV[VW])));
LLColor4U llcolor4u2(r,g,b,a);
ensure("3:LLColor4u:Fail to initialize ", ((r == llcolor4u2.mV[VX]) && (g == llcolor4u2.mV[VY]) && (b == llcolor4u2.mV[VZ])&& (a == llcolor4u2.mV[VW])));
const U8 vec[4] = {0x12,0xFF,0xAF,0x23};
LLColor4U llcolor4u3(vec);
ensure("4:LLColor4u:Fail to initialize ", ((vec[0] == llcolor4u3.mV[VX]) && (vec[1] == llcolor4u3.mV[VY]) && (vec[2] == llcolor4u3.mV[VZ])&& (vec[3] == llcolor4u3.mV[VW])));
LLSD sd = llcolor4u3.getValue();
LLColor4U llcolor4u4(sd);
ensure_equals("5:LLColor4u (LLSD) Failed ", llcolor4u4, llcolor4u3);
}
template<> template<>
void v4coloru_object::test<2>()
{
LLColor4U llcolor4ua(1, 2, 3, 4);
LLSD sd = llcolor4ua.getValue();
LLColor4U llcolor4u;
llcolor4u.setValue(sd);
ensure_equals("setValue(LLSD)/getValue Failed ", llcolor4u, llcolor4ua);
}
template<> template<>
void v4coloru_object::test<3>()
{
U8 r = 0x12, g = 0xFF, b = 0xAF, a = 0x23;
LLColor4U llcolor4u(r,g,b,a);
llcolor4u.setToBlack();
ensure("setToBlack:Fail to set black ", ((0 == llcolor4u.mV[VX]) && (0 == llcolor4u.mV[VY]) && (0 == llcolor4u.mV[VZ])&& (255 == llcolor4u.mV[VW])));
llcolor4u.setToWhite();
ensure("setToWhite:Fail to white ", ((255 == llcolor4u.mV[VX]) && (255 == llcolor4u.mV[VY]) && (255 == llcolor4u.mV[VZ])&& (255 == llcolor4u.mV[VW])));
}
template<> template<>
void v4coloru_object::test<4>()
{
U8 r = 0x12, g = 0xFF, b = 0xAF, a = 0x23;
LLColor4U llcolor4ua(r,g,b,a);
LLSD sd = llcolor4ua.getValue();
LLColor4U llcolor4u = sd;
ensure_equals("Operator=(LLSD) Failed ", llcolor4u, llcolor4ua);
}
template<> template<>
void v4coloru_object::test<5>()
{
U8 r = 0x12, g = 0xFF, b = 0xAF, a = 0x23;
LLColor4U llcolor4u;
llcolor4u.setVec(r,g,b,a);
ensure("1:setVec:Fail to set the values ", ((r == llcolor4u.mV[VX]) && (g == llcolor4u.mV[VY]) && (b == llcolor4u.mV[VZ])&& (a == llcolor4u.mV[VW])));
llcolor4u.setToBlack();
llcolor4u.setVec(r,g,b);
ensure("2:setVec:Fail to set the values ", ((r == llcolor4u.mV[VX]) && (g == llcolor4u.mV[VY]) && (b == llcolor4u.mV[VZ])&& (255 == llcolor4u.mV[VW])));
LLColor4U llcolor4u1;
llcolor4u1.setVec(llcolor4u);
ensure_equals("3:setVec:Fail to set the values ", llcolor4u1,llcolor4u);
const U8 vec[4] = {0x12,0xFF,0xAF,0x23};
LLColor4U llcolor4u2;
llcolor4u2.setVec(vec);
ensure("4:setVec:Fail to set the values ", ((vec[0] == llcolor4u2.mV[VX]) && (vec[1] == llcolor4u2.mV[VY]) && (vec[2] == llcolor4u2.mV[VZ])&& (vec[3] == llcolor4u2.mV[VW])));
}
template<> template<>
void v4coloru_object::test<6>()
{
U8 alpha = 0x12;
LLColor4U llcolor4u;
llcolor4u.setAlpha(alpha);
ensure("setAlpha:Fail to set alpha value ", (alpha == llcolor4u.mV[VW]));
}
template<> template<>
void v4coloru_object::test<7>()
{
U8 r = 0x12, g = 0xFF, b = 0xAF;
LLColor4U llcolor4u(r,g,b);
ensure("magVecSquared:Fail ", is_approx_equal(llcolor4u.magVecSquared(), (F32)(r*r + g*g + b*b)));
ensure("magVec:Fail ", is_approx_equal(llcolor4u.magVec(), fsqrtf(r*r + g*g + b*b)));
}
template<> template<>
void v4coloru_object::test<8>()
{
U8 r = 0x12, g = 0xFF, b = 0xAF;
std::ostringstream stream1, stream2;
LLColor4U llcolor4u1(r,g,b),llcolor4u2;
stream1 << llcolor4u1;
llcolor4u2.setVec(r,g,b);
stream2 << llcolor4u2;
ensure("operator << failed ", (stream1.str() == stream2.str()));
}
template<> template<>
void v4coloru_object::test<9>()
{
U8 r1 = 0x12, g1 = 0xFF, b1 = 0xAF;
U8 r2 = 0x1C, g2 = 0x9A, b2 = 0x1B;
LLColor4U llcolor4u1(r1,g1,b1), llcolor4u2(r2,g2,b2),llcolor4u3;
llcolor4u3 = llcolor4u1 + llcolor4u2;
ensure_equals(
"1a.operator+:Fail to Add the values ",
llcolor4u3.mV[VX],
(U8)(r1+r2));
ensure_equals(
"1b.operator+:Fail to Add the values ",
llcolor4u3.mV[VY],
(U8)(g1+g2));
ensure_equals(
"1c.operator+:Fail to Add the values ",
llcolor4u3.mV[VZ],
(U8)(b1+b2));
llcolor4u2 += llcolor4u1;
ensure_equals(
"2a.operator+=:Fail to Add the values ",
llcolor4u2.mV[VX],
(U8)(r1+r2));
ensure_equals(
"2b.operator+=:Fail to Add the values ",
llcolor4u2.mV[VY],
(U8)(g1+g2));
ensure_equals(
"2c.operator+=:Fail to Add the values ",
llcolor4u2.mV[VZ],
(U8)(b1+b2));
}
template<> template<>
void v4coloru_object::test<10>()
{
U8 r1 = 0x12, g1 = 0xFF, b1 = 0xAF;
U8 r2 = 0x1C, g2 = 0x9A, b2 = 0x1B;
LLColor4U llcolor4u1(r1,g1,b1), llcolor4u2(r2,g2,b2),llcolor4u3;
llcolor4u3 = llcolor4u1 - llcolor4u2;
ensure_equals(
"1a. operator-:Fail to Add the values ",
llcolor4u3.mV[VX],
(U8)(r1-r2));
ensure_equals(
"1b. operator-:Fail to Add the values ",
llcolor4u3.mV[VY],
(U8)(g1-g2));
ensure_equals(
"1c. operator-:Fail to Add the values ",
llcolor4u3.mV[VZ],
(U8)(b1-b2));
llcolor4u1 -= llcolor4u2;
ensure_equals(
"2a. operator-=:Fail to Add the values ",
llcolor4u1.mV[VX],
(U8)(r1-r2));
ensure_equals(
"2b. operator-=:Fail to Add the values ",
llcolor4u1.mV[VY],
(U8)(g1-g2));
ensure_equals(
"2c. operator-=:Fail to Add the values ",
llcolor4u1.mV[VZ],
(U8)(b1-b2));
}
template<> template<>
void v4coloru_object::test<11>()
{
U8 r1 = 0x12, g1 = 0xFF, b1 = 0xAF;
U8 r2 = 0x1C, g2 = 0x9A, b2 = 0x1B;
LLColor4U llcolor4u1(r1,g1,b1), llcolor4u2(r2,g2,b2),llcolor4u3;
llcolor4u3 = llcolor4u1 * llcolor4u2;
ensure_equals(
"1a. operator*:Fail to multiply the values",
llcolor4u3.mV[VX],
(U8)(r1*r2));
ensure_equals(
"1b. operator*:Fail to multiply the values",
llcolor4u3.mV[VY],
(U8)(g1*g2));
ensure_equals(
"1c. operator*:Fail to multiply the values",
llcolor4u3.mV[VZ],
(U8)(b1*b2));
U8 mulVal = 123;
llcolor4u1 *= mulVal;
ensure_equals(
"2a. operator*=:Fail to multiply the values",
llcolor4u1.mV[VX],
(U8)(r1*mulVal));
ensure_equals(
"2b. operator*=:Fail to multiply the values",
llcolor4u1.mV[VY],
(U8)(g1*mulVal));
ensure_equals(
"2c. operator*=:Fail to multiply the values",
llcolor4u1.mV[VZ],
(U8)(b1*mulVal));
}
template<> template<>
void v4coloru_object::test<12>()
{
U8 r = 0x12, g = 0xFF, b = 0xAF;
LLColor4U llcolor4u(r,g,b),llcolor4u1;
llcolor4u1 = llcolor4u;
ensure("operator== failed to ensure the equality ", (llcolor4u1 == llcolor4u));
llcolor4u1.setToBlack();
ensure("operator!= failed to ensure the equality ", (llcolor4u1 != llcolor4u));
}
template<> template<>
void v4coloru_object::test<13>()
{
U8 r = 0x12, g = 0xFF, b = 0xAF, a = 12;
LLColor4U llcolor4u(r,g,b,a);
U8 modVal = 45;
llcolor4u %= modVal;
ensure_equals("operator%=:Fail ", llcolor4u.mV[VW], (U8)(a * modVal));
}
template<> template<>
void v4coloru_object::test<14>()
{
U8 r = 0x12, g = 0xFF, b = 0xAF, a = 12;
LLColor4U llcolor4u1(r,g,b,a);
std::string color("12, 23, 132, 50");
LLColor4U::parseColor4U(color, &llcolor4u1);
ensure("parseColor4U() failed to parse the color value ", ((12 == llcolor4u1.mV[VX]) && (23 == llcolor4u1.mV[VY]) && (132 == llcolor4u1.mV[VZ])&& (50 == llcolor4u1.mV[VW])));
color = "12, 23, 132";
ensure("2:parseColor4U() failed to parse the color value ", (FALSE == LLColor4U::parseColor4U(color, &llcolor4u1)));
color = "12";
ensure("2:parseColor4U() failed to parse the color value ", (FALSE == LLColor4U::parseColor4U(color, &llcolor4u1)));
}
template<> template<>
void v4coloru_object::test<15>()
{
U8 r = 12, g = 123, b = 3, a = 2;
LLColor4U llcolor4u(r,g,b,a),llcolor4u1;
const F32 fVal = 3.f;
llcolor4u1 = llcolor4u.multAll(fVal);
ensure("multAll:Fail to multiply ", (((U8)llround(r * fVal) == llcolor4u1.mV[VX]) && (U8)llround(g * fVal) == llcolor4u1.mV[VY]
&& ((U8)llround(b * fVal) == llcolor4u1.mV[VZ])&& ((U8)llround(a * fVal) == llcolor4u1.mV[VW])));
}
template<> template<>
void v4coloru_object::test<16>()
{
U8 r1 = 12, g1 = 123, b1 = 3, a1 = 2;
U8 r2 = 23, g2 = 230, b2 = 124, a2 = 255;
LLColor4U llcolor4u(r1,g1,b1,a1),llcolor4u1(r2,g2,b2,a2);
llcolor4u1 = llcolor4u1.addClampMax(llcolor4u);
ensure("1:addClampMax():Fail to add the value ", ((r1+r2 == llcolor4u1.mV[VX]) && (255 == llcolor4u1.mV[VY]) && (b1+b2 == llcolor4u1.mV[VZ])&& (255 == llcolor4u1.mV[VW])));
r1 = 132, g1 = 3, b1 = 3, a1 = 2;
r2 = 123, g2 = 230, b2 = 154, a2 = 25;
LLColor4U llcolor4u2(r1,g1,b1,a1),llcolor4u3(r2,g2,b2,a2);
llcolor4u3 = llcolor4u3.addClampMax(llcolor4u2);
ensure("2:addClampMax():Fail to add the value ", ((255 == llcolor4u3.mV[VX]) && (g1+g2 == llcolor4u3.mV[VY]) && (b1+b2 == llcolor4u3.mV[VZ])&& (a1+a2 == llcolor4u3.mV[VW])));
}
template<> template<>
void v4coloru_object::test<17>()
{
F32 r = 23.f, g = 12.32f, b = -12.3f;
LLColor3 color3(r,g,b);
LLColor4U llcolor4u;
llcolor4u.setVecScaleClamp(color3);
const S32 MAX_COLOR = 255;
F32 color_scale_factor = MAX_COLOR/r;
S32 r2 = llround(r * color_scale_factor);
S32 g2 = llround(g * color_scale_factor);
ensure("setVecScaleClamp():Fail to add the value ", ((r2 == llcolor4u.mV[VX]) && (g2 == llcolor4u.mV[VY]) && (0 == llcolor4u.mV[VZ])&& (255 == llcolor4u.mV[VW])));
}
}

388
indra/test/v4math_tut.cpp Normal file
View File

@@ -0,0 +1,388 @@
/**
* @file v4math_tut.cpp
* @author Adroit
* @date 2007-03
* @brief v4math test cases.
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "lltut.h"
#include "llquaternion.h"
#include "llsd.h"
#include "m4math.h"
#include "v4math.h"
namespace tut
{
struct v4math_data
{
};
typedef test_group<v4math_data> v4math_test;
typedef v4math_test::object v4math_object;
tut::v4math_test v4math_testcase("v4math");
template<> template<>
void v4math_object::test<1>()
{
LLVector4 vec4;
ensure("1:LLVector4:Fail to initialize " ,((0 == vec4.mV[VX]) && (0 == vec4.mV[VY]) && (0 == vec4.mV[VZ])&& (1.0f == vec4.mV[VW])));
F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f;
LLVector4 vec4a(x,y,z);
ensure("2:LLVector4:Fail to initialize " ,((x == vec4a.mV[VX]) && (y == vec4a.mV[VY]) && (z == vec4a.mV[VZ])&& (1.0f == vec4a.mV[VW])));
LLVector4 vec4b(x,y,z,w);
ensure("3:LLVector4:Fail to initialize " ,((x == vec4b.mV[VX]) && (y == vec4b.mV[VY]) && (z == vec4b.mV[VZ])&& (w == vec4b.mV[VW])));
const F32 vec[4] = {.112f ,23.2f, -4.2f, -.0001f};
LLVector4 vec4c(vec);
ensure("4:LLVector4:Fail to initialize " ,((vec[0] == vec4c.mV[VX]) && (vec[1] == vec4c.mV[VY]) && (vec[2] == vec4c.mV[VZ])&& (vec[3] == vec4c.mV[VW])));
LLVector3 vec3(-2.23f,1.01f,42.3f);
LLVector4 vec4d(vec3);
ensure("5:LLVector4:Fail to initialize " ,((vec3.mV[VX] == vec4d.mV[VX]) && (vec3.mV[VY] == vec4d.mV[VY]) && (vec3.mV[VZ] == vec4d.mV[VZ])&& (1.f == vec4d.mV[VW])));
F32 w1 = -.234f;
LLVector4 vec4e(vec3,w1);
ensure("6:LLVector4:Fail to initialize " ,((vec3.mV[VX] == vec4e.mV[VX]) && (vec3.mV[VY] == vec4e.mV[VY]) && (vec3.mV[VZ] == vec4e.mV[VZ])&& (w1 == vec4e.mV[VW])));
}
template<> template<>
void v4math_object::test<2>()
{
F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f;
LLVector4 vec4;
vec4.setVec(x,y,z);
ensure("1:setVec:Fail to initialize " ,((x == vec4.mV[VX]) && (y == vec4.mV[VY]) && (z == vec4.mV[VZ])&& (1.0f == vec4.mV[VW])));
vec4.clearVec();
ensure("2:clearVec:Fail " ,((0 == vec4.mV[VX]) && (0 == vec4.mV[VY]) && (0 == vec4.mV[VZ])&& (1.0f == vec4.mV[VW])));
vec4.setVec(x,y,z,w);
ensure("3:setVec:Fail to initialize " ,((x == vec4.mV[VX]) && (y == vec4.mV[VY]) && (z == vec4.mV[VZ])&& (w == vec4.mV[VW])));
vec4.zeroVec();
ensure("4:zeroVec:Fail " ,((0 == vec4.mV[VX]) && (0 == vec4.mV[VY]) && (0 == vec4.mV[VZ])&& (0 == vec4.mV[VW])));
LLVector3 vec3(-2.23f,1.01f,42.3f);
vec4.clearVec();
vec4.setVec(vec3);
ensure("5:setVec:Fail to initialize " ,((vec3.mV[VX] == vec4.mV[VX]) && (vec3.mV[VY] == vec4.mV[VY]) && (vec3.mV[VZ] == vec4.mV[VZ])&& (1.f == vec4.mV[VW])));
F32 w1 = -.234f;
vec4.zeroVec();
vec4.setVec(vec3,w1);
ensure("6:setVec:Fail to initialize " ,((vec3.mV[VX] == vec4.mV[VX]) && (vec3.mV[VY] == vec4.mV[VY]) && (vec3.mV[VZ] == vec4.mV[VZ])&& (w1 == vec4.mV[VW])));
const F32 vec[4] = {.112f ,23.2f, -4.2f, -.0001f};
LLVector4 vec4a;
vec4a.setVec(vec);
ensure("7:setVec:Fail to initialize " ,((vec[0] == vec4a.mV[VX]) && (vec[1] == vec4a.mV[VY]) && (vec[2] == vec4a.mV[VZ])&& (vec[3] == vec4a.mV[VW])));
}
template<> template<>
void v4math_object::test<3>()
{
F32 x = 10.f, y = -2.3f, z = -.023f;
LLVector4 vec4(x,y,z);
ensure("magVec:Fail ", is_approx_equal(vec4.magVec(), fsqrtf(x*x + y*y + z*z)));
ensure("magVecSquared:Fail ", is_approx_equal(vec4.magVecSquared(), (x*x + y*y + z*z)));
}
template<> template<>
void v4math_object::test<4>()
{
F32 x = 10.f, y = -2.3f, z = -.023f;
LLVector4 vec4(x,y,z);
F32 mag = vec4.normVec();
mag = 1.f/ mag;
ensure("1:normVec: Fail " ,is_approx_equal(mag*x,vec4.mV[VX]) && is_approx_equal(mag*y, vec4.mV[VY])&& is_approx_equal(mag*z, vec4.mV[VZ]));
x = 0.000000001f, y = 0.000000001f, z = 0.000000001f;
vec4.clearVec();
vec4.setVec(x,y,z);
mag = vec4.normVec();
ensure("2:normVec: Fail " ,is_approx_equal(mag*x,vec4.mV[VX]) && is_approx_equal(mag*y, vec4.mV[VY])&& is_approx_equal(mag*z, vec4.mV[VZ]));
}
template<> template<>
void v4math_object::test<5>()
{
F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f;
LLVector4 vec4(x,y,z,w);
vec4.abs();
ensure("abs:Fail " ,((x == vec4.mV[VX]) && (-y == vec4.mV[VY]) && (-z == vec4.mV[VZ])&& (-w == vec4.mV[VW])));
vec4.clearVec();
ensure("isExactlyClear:Fail " ,(TRUE == vec4.isExactlyClear()));
vec4.zeroVec();
ensure("isExactlyZero:Fail " ,(TRUE == vec4.isExactlyZero()));
}
template<> template<>
void v4math_object::test<6>()
{
F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f;
LLVector4 vec4(x,y,z,w),vec4a;
vec4a = vec4.scaleVec(vec4);
ensure("scaleVec:Fail " ,(is_approx_equal(x*x, vec4a.mV[VX]) && is_approx_equal(y*y, vec4a.mV[VY]) && is_approx_equal(z*z, vec4a.mV[VZ])&& is_approx_equal(w*w, vec4a.mV[VW])));
}
template<> template<>
void v4math_object::test<7>()
{
F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f;
LLVector4 vec4(x,y,z,w);
ensure("1:operator [] failed " ,( x == vec4[0]));
ensure("2:operator [] failed " ,( y == vec4[1]));
ensure("3:operator [] failed " ,( z == vec4[2]));
ensure("4:operator [] failed " ,( w == vec4[3]));
x = 23.f, y = -.2361f, z = 3.25;
vec4.setVec(x,y,z);
F32 &ref1 = vec4[0];
ensure("5:operator [] failed " ,( ref1 == vec4[0]));
F32 &ref2 = vec4[1];
ensure("6:operator [] failed " ,( ref2 == vec4[1]));
F32 &ref3 = vec4[2];
ensure("7:operator [] failed " ,( ref3 == vec4[2]));
F32 &ref4 = vec4[3];
ensure("8:operator [] failed " ,( ref4 == vec4[3]));
}
template<> template<>
void v4math_object::test<8>()
{
F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f;
const F32 val[16] = {
1.f, 2.f, 3.f, 0.f,
.34f, .1f, -.5f, 0.f,
2.f, 1.23f, 1.234f, 0.f,
.89f, 0.f, 0.f, 0.f
};
LLMatrix4 mat(val);
LLVector4 vec4(x,y,z,w),vec4a;
vec4.rotVec(mat);
vec4a.setVec(x,y,z,w);
vec4a.rotVec(mat);
ensure_equals("1:rotVec: Fail " ,vec4a, vec4);
F32 a = 2.32f, b = -23.2f, c = -34.1112f, d = 1.010112f;
LLQuaternion q(a,b,c,d);
LLVector4 vec4b(a,b,c,d),vec4c;
vec4b.rotVec(q);
vec4c.setVec(a, b, c, d);
vec4c.rotVec(q);
ensure_equals("2:rotVec: Fail " ,vec4b, vec4c);
}
template<> template<>
void v4math_object::test<9>()
{
F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f;
LLVector4 vec4(x,y,z,w),vec4a;;
std::ostringstream stream1, stream2;
stream1 << vec4;
vec4a.setVec(x,y,z,w);
stream2 << vec4a;
ensure("operator << failed",(stream1.str() == stream2.str()));
}
template<> template<>
void v4math_object::test<10>()
{
F32 x1 = 1.f, y1 = 2.f, z1 = -1.1f, w1 = .23f;
F32 x2 = 1.2f, y2 = 2.5f, z2 = 1.f, w2 = 1.3f;
LLVector4 vec4(x1,y1,z1,w1),vec4a(x2,y2,z2,w2),vec4b;
vec4b = vec4a + vec4;
ensure("1:operator+:Fail to initialize " ,(is_approx_equal(x1+x2,vec4b.mV[VX]) && is_approx_equal(y1+y2,vec4b.mV[VY]) && is_approx_equal(z1+z2,vec4b.mV[VZ])));
x1 = -2.45f, y1 = 2.1f, z1 = 3.0f;
vec4.clearVec();
vec4a.clearVec();
vec4.setVec(x1,y1,z1);
vec4a +=vec4;
ensure_equals("2:operator+=: Fail to initialize", vec4a,vec4);
vec4a += vec4;
ensure("3:operator+=:Fail to initialize " ,(is_approx_equal(2*x1,vec4a.mV[VX]) && is_approx_equal(2*y1,vec4a.mV[VY]) && is_approx_equal(2*z1,vec4a.mV[VZ])));
}
template<> template<>
void v4math_object::test<11>()
{
F32 x1 = 1.f, y1 = 2.f, z1 = -1.1f, w1 = .23f;
F32 x2 = 1.2f, y2 = 2.5f, z2 = 1.f, w2 = 1.3f;
LLVector4 vec4(x1,y1,z1,w1),vec4a(x2,y2,z2,w2),vec4b;
vec4b = vec4a - vec4;
ensure("1:operator-:Fail to initialize " ,(is_approx_equal(x2-x1,vec4b.mV[VX]) && is_approx_equal(y2-y1,vec4b.mV[VY]) && is_approx_equal(z2-z1,vec4b.mV[VZ])));
x1 = -2.45f, y1 = 2.1f, z1 = 3.0f;
vec4.clearVec();
vec4a.clearVec();
vec4.setVec(x1,y1,z1);
vec4a -=vec4;
ensure_equals("2:operator-=: Fail to initialize" , vec4a,-vec4);
vec4a -=vec4;
ensure("3:operator-=:Fail to initialize " ,(is_approx_equal(-2*x1,vec4a.mV[VX]) && is_approx_equal(-2*y1,vec4a.mV[VY]) && is_approx_equal(-2*z1,vec4a.mV[VZ])));
}
template<> template<>
void v4math_object::test<12>()
{
F32 x1 = 1.f, y1 = 2.f, z1 = -1.1f;
F32 x2 = 1.2f, y2 = 2.5f, z2 = 1.f;
LLVector4 vec4(x1,y1,z1),vec4a(x2,y2,z2);
F32 res = vec4 * vec4a;
ensure("1:operator* failed " ,is_approx_equal(res, x1*x2 + y1*y2 + z1*z2));
vec4a.clearVec();
F32 mulVal = 4.2f;
vec4a = vec4 * mulVal;
ensure("2:operator* failed " ,is_approx_equal(x1*mulVal,vec4a.mV[VX]) && is_approx_equal(y1*mulVal, vec4a.mV[VY])&& is_approx_equal(z1*mulVal, vec4a.mV[VZ]));
vec4a.clearVec();
vec4a = mulVal * vec4 ;
ensure("3:operator* failed " ,is_approx_equal(x1*mulVal, vec4a.mV[VX]) && is_approx_equal(y1*mulVal, vec4a.mV[VY])&& is_approx_equal(z1*mulVal, vec4a.mV[VZ]));
vec4 *= mulVal;
ensure("4:operator*= failed " ,is_approx_equal(x1*mulVal, vec4.mV[VX]) && is_approx_equal(y1*mulVal, vec4.mV[VY])&& is_approx_equal(z1*mulVal, vec4.mV[VZ]));
}
template<> template<>
void v4math_object::test<13>()
{
F32 x1 = 1.f, y1 = 2.f, z1 = -1.1f;
F32 x2 = 1.2f, y2 = 2.5f, z2 = 1.f;
LLVector4 vec4(x1,y1,z1),vec4a(x2,y2,z2),vec4b;
vec4b = vec4 % vec4a;
ensure("1:operator% failed " ,is_approx_equal(y1*z2 - y2*z1, vec4b.mV[VX]) && is_approx_equal(z1*x2 -z2*x1, vec4b.mV[VY]) && is_approx_equal(x1*y2-x2*y1, vec4b.mV[VZ]));
vec4 %= vec4a;
ensure_equals("operator%= failed " ,vec4,vec4b);
}
template<> template<>
void v4math_object::test<14>()
{
F32 x = 1.f, y = 2.f, z = -1.1f,div = 4.2f;
F32 t = 1.f / div;
LLVector4 vec4(x,y,z), vec4a;
vec4a = vec4/div;
ensure("1:operator/ failed " ,is_approx_equal(x*t, vec4a.mV[VX]) && is_approx_equal(y*t, vec4a.mV[VY])&& is_approx_equal(z*t, vec4a.mV[VZ]));
x = 1.23f, y = 4.f, z = -2.32f;
vec4.clearVec();
vec4a.clearVec();
vec4.setVec(x,y,z);
vec4a = vec4/div;
ensure("2:operator/ failed " ,is_approx_equal(x*t, vec4a.mV[VX]) && is_approx_equal(y*t, vec4a.mV[VY])&& is_approx_equal(z*t, vec4a.mV[VZ]));
vec4 /= div;
ensure("3:operator/ failed " ,is_approx_equal(x*t, vec4.mV[VX]) && is_approx_equal(y*t, vec4.mV[VY])&& is_approx_equal(z*t, vec4.mV[VZ]));
}
template<> template<>
void v4math_object::test<15>()
{
F32 x = 1.f, y = 2.f, z = -1.1f;
LLVector4 vec4(x,y,z), vec4a;
ensure("operator!= failed " ,(vec4 != vec4a));
vec4a = vec4;
ensure("operator== failed " ,(vec4 ==vec4a));
}
template<> template<>
void v4math_object::test<16>()
{
F32 x = 1.f, y = 2.f, z = -1.1f;
LLVector4 vec4(x,y,z), vec4a;
vec4a = - vec4;
ensure("operator- failed " , (vec4 == - vec4a));
}
template<> template<>
void v4math_object::test<17>()
{
F32 x = 1.f, y = 2.f, z = -1.1f,epsilon = .23425f;
LLVector4 vec4(x,y,z), vec4a(x,y,z);
ensure("1:are_parallel: Fail " ,(TRUE == are_parallel(vec4a,vec4,epsilon)));
x = 21.f, y = 12.f, z = -123.1f;
vec4a.clearVec();
vec4a.setVec(x,y,z);
ensure("2:are_parallel: Fail " ,(FALSE == are_parallel(vec4a,vec4,epsilon)));
}
template<> template<>
void v4math_object::test<18>()
{
F32 x = 1.f, y = 2.f, z = -1.1f;
F32 angle1, angle2;
LLVector4 vec4(x,y,z), vec4a(x,y,z);
angle1 = angle_between(vec4, vec4a);
vec4.normVec();
vec4a.normVec();
angle2 = acos(vec4 * vec4a);
ensure_approximately_equals("1:angle_between: Fail " ,angle1,angle2,8);
F32 x1 = 21.f, y1 = 2.23f, z1 = -1.1f;
LLVector4 vec4b(x,y,z), vec4c(x1,y1,z1);
angle1 = angle_between(vec4b, vec4c);
vec4b.normVec();
vec4c.normVec();
angle2 = acos(vec4b * vec4c);
ensure_approximately_equals("2:angle_between: Fail " ,angle1,angle2,8);
}
template<> template<>
void v4math_object::test<19>()
{
F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 1.f, z2 = 1.f;
F32 val1,val2;
LLVector4 vec4(x1,y1,z1),vec4a(x2,y2,z2);
val1 = dist_vec(vec4,vec4a);
val2 = fsqrtf((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2) + (z1 - z2)* (z1 -z2));
ensure_equals("dist_vec: Fail ",val2, val1);
val1 = dist_vec_squared(vec4,vec4a);
val2 =((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2) + (z1 - z2)* (z1 -z2));
ensure_equals("dist_vec_squared: Fail ",val2, val1);
}
template<> template<>
void v4math_object::test<20>()
{
F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, w1 = -.23f, x2 = 1.3f, y2 = 1.f, z2 = 1.f,w2 = .12f;
F32 val = 2.3f,val1,val2,val3,val4;
LLVector4 vec4(x1,y1,z1,w1),vec4a(x2,y2,z2,w2);
val1 = x1 + (x2 - x1)* val;
val2 = y1 + (y2 - y1)* val;
val3 = z1 + (z2 - z1)* val;
val4 = w1 + (w2 - w1)* val;
LLVector4 vec4b = lerp(vec4,vec4a,val);
ensure("lerp failed", ((val1 ==vec4b.mV[VX])&& (val2 ==vec4b.mV[VY]) && (val3 ==vec4b.mV[VZ])&& (val4 ==vec4b.mV[VW])));
}
template<> template<>
void v4math_object::test<21>()
{
F32 x = 1.f, y = 2.f, z = -1.1f;
LLVector4 vec4(x,y,z);
LLVector3 vec3 = vec4to3(vec4);
ensure("vec4to3 failed", ((x == vec3.mV[VX])&& (y == vec3.mV[VY]) && (z == vec3.mV[VZ])));
LLVector4 vec4a = vec3to4(vec3);
ensure_equals("vec3to4 failed",vec4a,vec4);
}
template<> template<>
void v4math_object::test<22>()
{
F32 x = 1.f, y = 2.f, z = -1.1f;
LLVector4 vec4(x,y,z);
LLSD llsd = vec4.getValue();
LLVector3 vec3(llsd);
LLVector4 vec4a = vec3to4(vec3);
ensure_equals("getValue failed",vec4a,vec4);
}
}

251
indra/test/xform_tut.cpp Normal file
View File

@@ -0,0 +1,251 @@
/**
* @file xform_tut.cpp
* @author Adroit
* @date March 2007
* @brief Test cases for LLXform
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include <tut/tut.hpp>
#include "linden_common.h"
#include "lltut.h"
#include "xform.h"
namespace tut
{
struct xform_test
{
};
typedef test_group<xform_test> xform_test_t;
typedef xform_test_t::object xform_test_object_t;
tut::xform_test_t tut_xform_test("xform_test");
//test case for init(), getParent(), getRotation(), getPositionW(), getWorldRotation() fns.
template<> template<>
void xform_test_object_t::test<1>()
{
LLXform xform_obj;
LLVector3 emptyVec(0.f,0.f,0.f);
LLVector3 initialScaleVec(1.f,1.f,1.f);
ensure("LLXform empty constructor failed: ", !xform_obj.getParent() && !xform_obj.isChanged() &&
xform_obj.getPosition() == emptyVec &&
(xform_obj.getRotation()).isIdentity() &&
xform_obj.getScale() == initialScaleVec &&
xform_obj.getPositionW() == emptyVec &&
(xform_obj.getWorldRotation()).isIdentity() &&
!xform_obj.getScaleChildOffset());
}
// test cases for
// setScale(const LLVector3& scale)
// setScale(const F32 x, const F32 y, const F32 z)
// setRotation(const F32 x, const F32 y, const F32 z)
// setPosition(const F32 x, const F32 y, const F32 z)
// getLocalMat4(LLMatrix4 &mat)
template<> template<>
void xform_test_object_t::test<2>()
{
LLMatrix4 llmat4;
LLXform xform_obj;
F32 x = 3.6f;
F32 y = 5.5f;
F32 z = 4.2f;
F32 w = 0.f;
F32 posz = z + 2.122f;
LLVector3 vec(x, y, z);
xform_obj.setScale(x, y, z);
xform_obj.setPosition(x, y, posz);
ensure("setScale failed: ", xform_obj.getScale() == vec);
vec.setVec(x, y, posz);
ensure("getPosition failed: ", xform_obj.getPosition() == vec);
x = x * 2.f;
y = y + 2.3f;
z = posz * 4.f;
vec.setVec(x, y, z);
xform_obj.setPositionX(x);
xform_obj.setPositionY(y);
xform_obj.setPositionZ(z);
ensure("setPositionX/Y/Z failed: ", xform_obj.getPosition() == vec);
xform_obj.setScaleChildOffset(TRUE);
ensure("setScaleChildOffset failed: ", xform_obj.getScaleChildOffset());
vec.setVec(x, y, z);
xform_obj.addPosition(vec);
vec += vec;
ensure("addPosition failed: ", xform_obj.getPosition() == vec);
xform_obj.setScale(vec);
ensure("setScale vector failed: ", xform_obj.getScale() == vec);
LLQuaternion quat(x, y, z, w);
xform_obj.setRotation(quat);
ensure("setRotation quat failed: ", xform_obj.getRotation() == quat);
xform_obj.setRotation(x, y, z, w);
ensure("getRotation 2 failed: ", xform_obj.getRotation() == quat);
xform_obj.setRotation(x, y, z);
quat.setQuat(x,y,z);
ensure("setRotation xyz failed: ", xform_obj.getRotation() == quat);
// LLXform::setRotation(const F32 x, const F32 y, const F32 z)
// Does normalization
// LLXform::setRotation(const F32 x, const F32 y, const F32 z, const F32 s)
// Simply copies the individual values - does not do any normalization.
// Is that the expected behavior?
}
// test cases for inline BOOL setParent(LLXform *parent) and getParent() fn.
template<> template<>
void xform_test_object_t::test<3>()
{
LLXform xform_obj;
LLXform par;
LLXform grandpar;
xform_obj.setParent(&par);
par.setParent(&grandpar);
ensure("setParent/getParent failed: ", &par == xform_obj.getParent());
ensure("getRoot failed: ", &grandpar == xform_obj.getRoot());
ensure("isRoot failed: ", grandpar.isRoot() && !par.isRoot() && !xform_obj.isRoot());
ensure("isRootEdit failed: ", grandpar.isRootEdit() && !par.isRootEdit() && !xform_obj.isRootEdit());
}
template<> template<>
void xform_test_object_t::test<4>()
{
LLXform xform_obj;
xform_obj.setChanged(LLXform::TRANSLATED | LLXform::ROTATED | LLXform::SCALED);
ensure("setChanged/isChanged failed: ", xform_obj.isChanged());
xform_obj.clearChanged(LLXform::TRANSLATED | LLXform::ROTATED | LLXform::SCALED);
ensure("clearChanged failed: ", !xform_obj.isChanged());
LLVector3 llvect3(12.4f, -5.6f, 0.34f);
xform_obj.setScale(llvect3);
ensure("setScale did not set SCALED flag: ", xform_obj.isChanged(LLXform::SCALED));
xform_obj.setPosition(1.2f, 2.3f, 3.4f);
ensure("setScale did not set TRANSLATED flag: ", xform_obj.isChanged(LLXform::TRANSLATED));
ensure("TRANSLATED reset SCALED flag: ", xform_obj.isChanged(LLXform::TRANSLATED | LLXform::SCALED));
xform_obj.clearChanged(LLXform::SCALED);
ensure("reset SCALED failed: ", !xform_obj.isChanged(LLXform::SCALED));
xform_obj.setRotation(1, 2, 3, 4);
ensure("ROTATION flag not set ", xform_obj.isChanged(LLXform::TRANSLATED | LLXform::ROTATED));
xform_obj.setScale(llvect3);
ensure("ROTATION flag not set ", xform_obj.isChanged(LLXform::MOVED));
}
//to test init() and getWorldMatrix() fns.
template<> template<>
void xform_test_object_t::test<5>()
{
LLXformMatrix formMatrix_obj;
formMatrix_obj.init();
LLMatrix4 mat4_obj;
ensure("1. The value is not NULL", 1.f == formMatrix_obj.getWorldMatrix().mMatrix[0][0]);
ensure("2. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[0][1]);
ensure("3. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[0][2]);
ensure("4. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[0][3]);
ensure("5. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[1][0]);
ensure("6. The value is not NULL", 1.f == formMatrix_obj.getWorldMatrix().mMatrix[1][1]);
ensure("7. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[1][2]);
ensure("8. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[1][3]);
ensure("9. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[2][0]);
ensure("10. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[2][1]);
ensure("11. The value is not NULL", 1.f == formMatrix_obj.getWorldMatrix().mMatrix[2][2]);
ensure("12. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[2][3]);
ensure("13. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[3][0]);
ensure("14. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[3][1]);
ensure("15. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[3][2]);
ensure("16. The value is not NULL", 1.f == formMatrix_obj.getWorldMatrix().mMatrix[3][3]);
}
//to test mMin.clearVec() and mMax.clearVec() fns
template<> template<>
void xform_test_object_t::test<6>()
{
LLXformMatrix formMatrix_obj;
formMatrix_obj.init();
LLVector3 llmin_vec3;
LLVector3 llmax_vec3;
formMatrix_obj.getMinMax(llmin_vec3, llmax_vec3);
ensure("1. The value is not NULL", 0.f == llmin_vec3.mV[0]);
ensure("2. The value is not NULL", 0.f == llmin_vec3.mV[1]);
ensure("3. The value is not NULL", 0.f == llmin_vec3.mV[2]);
ensure("4. The value is not NULL", 0.f == llmin_vec3.mV[0]);
ensure("5. The value is not NULL", 0.f == llmin_vec3.mV[1]);
ensure("6. The value is not NULL", 0.f == llmin_vec3.mV[2]);
}
//test case of update() fn.
template<> template<>
void xform_test_object_t::test<7>()
{
LLXformMatrix formMatrix_obj;
LLXformMatrix parent;
LLVector3 llvecpos(1.0, 2.0, 3.0);
LLVector3 llvecpospar(10.0, 20.0, 30.0);
formMatrix_obj.setPosition(llvecpos);
parent.setPosition(llvecpospar);
LLVector3 llvecparentscale(1.0, 2.0, 0);
parent.setScaleChildOffset(TRUE);
parent.setScale(llvecparentscale);
LLQuaternion quat(1, 2, 3, 4);
LLQuaternion quatparent(5, 6, 7, 8);
formMatrix_obj.setRotation(quat);
parent.setRotation(quatparent);
formMatrix_obj.setParent(&parent);
parent.update();
formMatrix_obj.update();
LLVector3 worldPos = llvecpos;
worldPos.scaleVec(llvecparentscale);
worldPos *= quatparent;
worldPos += llvecpospar;
LLQuaternion worldRot = quat * quatparent;
ensure("getWorldPosition failed: ", formMatrix_obj.getWorldPosition() == worldPos);
ensure("getWorldRotation failed: ", formMatrix_obj.getWorldRotation() == worldRot);
ensure("getWorldPosition for parent failed: ", parent.getWorldPosition() == llvecpospar);
ensure("getWorldRotation for parent failed: ", parent.getWorldRotation() == quatparent);
}
}