Arquivos
hhvm/hphp/test/test_cpp_base.cpp
T
Edwin Smith 494733bd31 Remove Array::operator[](litstr)
Refactor the remaining uses of litstr-indexed Array, and
get rid of the operator overload.
2013-05-10 10:54:37 -07:00

996 linhas
25 KiB
C++

/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010- Facebook, Inc. (http://www.facebook.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#include <test/test_cpp_base.h>
#include <runtime/base/base_includes.h>
#include <util/logger.h>
#include <runtime/base/memory/memory_manager.h>
#include <runtime/base/builtin_functions.h>
#include <runtime/ext/ext_variable.h>
#include <runtime/ext/ext_apc.h>
#include <runtime/ext/ext_mysql.h>
#include <runtime/ext/ext_curl.h>
#include <runtime/base/shared/shared_store_base.h>
#include <runtime/base/runtime_option.h>
#include <runtime/base/server/ip_block_map.h>
#include <hphp/test/test_mysql_info.h>
#include <system/lib/systemlib.h>
///////////////////////////////////////////////////////////////////////////////
TestCppBase::TestCppBase() {
}
///////////////////////////////////////////////////////////////////////////////
bool TestCppBase::RunTests(const std::string &which) {
bool ret = true;
RUN_TEST(TestSmartAllocator);
RUN_TEST(TestString);
RUN_TEST(TestArray);
RUN_TEST(TestObject);
RUN_TEST(TestVariant);
RUN_TEST(TestIpBlockMap);
RUN_TEST(TestEqualAsStr);
return ret;
}
///////////////////////////////////////////////////////////////////////////////
// building blocks
class Timer {
public:
explicit Timer(const char *name = nullptr) {
if (name) m_name = name;
gettimeofday(&m_start, 0);
}
int64_t getMicroSeconds() {
struct timeval end;
gettimeofday(&end, 0);
return (end.tv_sec - m_start.tv_sec) * 1000000 +
(end.tv_usec - m_start.tv_usec);
}
private:
std::string m_name;
struct timeval m_start;
};
class SomeClass {
public:
SomeClass() : m_data(0) {}
void sweep() {}
void dump() { printf("data: %d\n", m_data);}
int m_data;
};
static StaticString s_TestResource("TestResource");
class TestResource : public ResourceData {
public:
// overriding ResourceData
CStrRef o_getClassNameHook() const { return s_TestResource; }
};
typedef SmartAllocator<SomeClass>
SomeClassAlloc;
bool TestCppBase::TestSmartAllocator() {
int iMax = 1000000;
int64_t time1, time2;
{
static IMPLEMENT_THREAD_LOCAL(SomeClassAlloc, allocator);
Timer t;
for (int i = 0; i < iMax; i++) {
SomeClass *obj = new (allocator.get()) SomeClass();
allocator.get()->dealloc(obj);
}
time1 = t.getMicroSeconds();
if (!Test::s_quiet) {
printf("SmartAlloctor: %" PRId64 " us\n", time1);
}
}
{
Timer t;
for (int i = 0; i < iMax; i++) {
SomeClass *obj = new SomeClass();
delete obj;
}
time2 = t.getMicroSeconds();
if (!Test::s_quiet) {
printf("malloc/free: %" PRId64 " us\n", time2);
}
}
return Count(true);
}
///////////////////////////////////////////////////////////////////////////////
// data types
bool TestCppBase::TestString() {
// constructors
{
VS(String(15).c_str(), "15");
VS(String(-15).c_str(), "-15");
VS(String(int64_t(12345678912345678LL)).c_str(), "12345678912345678");
VS(String(int64_t(-12345678912345678LL)).c_str(), "-12345678912345678");
VS(String(5.603).c_str(), "5.603");
VS(String("test").c_str(), "test");
VS(String(String("test")).c_str(), "test");
}
// informational
{
VERIFY(String().isNull());
VERIFY(!String("").isNull());
VERIFY(String().empty());
VERIFY(String("").empty());
VERIFY(!String("test").empty());
VERIFY(String().size() == 0);
VERIFY(String().length() == 0);
VERIFY(String("").size() == 0);
VERIFY(String("").length() == 0);
VERIFY(String("test").size() == 4);
VERIFY(String("test").length() == 4);
VERIFY(!String("2test").isNumeric());
VERIFY(!String("2test").isInteger());
VERIFY(!String("2test").isValidVariableName());
VERIFY(!String("test").isNumeric());
VERIFY(!String("test").isInteger());
VERIFY(String("test").isValidVariableName());
VERIFY(String("23").isNumeric());
VERIFY(String("23").isInteger());
VERIFY(String("23.3").isNumeric());
VERIFY(!String("23.3").isInteger());
}
// operators
{
String s;
s = "test1"; VS(s.c_str(), "test1");
s = String("test2"); VS(s.c_str(), "test2");
s = Variant("test3"); VS(s.c_str(), "test3");
s = String("a") + "b"; VS(s.c_str(), "ab");
s = String("c") + String("d"); VS(s.c_str(), "cd");
s += "efg"; VS(s.c_str(), "cdefg");
s += String("hij"); VS(s.c_str(), "cdefghij");
s = String("\x50\x51") | "\x51\x51"; VS(s.c_str(), "\x51\x51");
s = String("\x50\x51") & "\x51\x51"; VS(s.c_str(), "\x50\x51");
s = String("\x50\x51") ^ "\x51\x51"; VS(s.c_str(), "\x01");
s = "\x50\x51"; s |= "\x51\x51"; VS(s.c_str(), "\x51\x51");
s = "\x50\x51"; s &= "\x51\x51"; VS(s.c_str(), "\x50\x51");
s = "\x50\x51"; s ^= "\x51\x51"; VS(s.c_str(), "\x01");
s = "\x50\x51"; s = ~s; VS(s.c_str(), "\xAF\xAE");
}
// manipulations
{
String s = StringUtil::ToLower("Test");
VS(s.c_str(), "test");
}
// conversions
{
VERIFY(!String().toBoolean());
VERIFY(String("123").toBoolean());
VERIFY(String("123").toByte() == 123);
VERIFY(String("32767").toInt16() == 32767);
VERIFY(String("1234567890").toInt32() == 1234567890);
VERIFY(String("123456789012345678").toInt64() == 123456789012345678LL);
VERIFY(String("123.45").toDouble() == 123.45);
}
// offset
{
VS(String("test").rvalAt(2).c_str(), "s");
String s = "test";
s.lvalAt(2) = "";
VS(s, String("te\0t", 4, AttachLiteral));
s.lvalAt(2) = "zz";
VS(s, "tezt");
s.lvalAt(5) = "q";
VS(s, "tezt q");
String s2 = s; // test copy-on-write
s.lvalAt(1) = "3";
VS(s, "t3zt q");
VS(s2, "tezt q");
}
return Count(true);
}
static const StaticString s_n0("n0");
static const StaticString s_n1("n1");
static const StaticString s_n2("n2");
static const StaticString s_A("A");
static const StaticString s_name("name");
static const StaticString s_1("1");
bool TestCppBase::TestArray() {
// Array::Create(), Array constructors and informational
{
Array arr;
VERIFY(arr.empty()); VERIFY(arr.size() == 0); VERIFY(arr.length() == 0);
VERIFY(arr.isNull());
arr = Array::Create();
VERIFY(arr.empty()); VERIFY(arr.size() == 0); VERIFY(arr.length() == 0);
VERIFY(!arr.isNull());
arr = Array::Create(0);
VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1);
VERIFY(!arr.isNull());
VERIFY((int)arr[0] == 0);
VS(arr, Array(ArrayInit(1).set(0).create()));
arr = Array::Create("test");
VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1);
VERIFY(!arr.isNull());
VERIFY(arr[0] == "test");
VS(arr, Array(ArrayInit(1).set("test").create()));
Array arrCopy = arr;
arr = Array::Create(arr);
VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1);
VERIFY(!arr.isNull());
VERIFY(arr[0].toArray().size() == 1);
VS(arr[0], arrCopy);
VS(arr, Array(ArrayInit(1).set(arrCopy).create()));
arr = Array::Create("name", 1);
VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1);
VERIFY(!arr.isNull());
VERIFY((int)arr[s_name] == 1);
VS(arr, Array(ArrayInit(1).set(s_name, 1).create()));
arr = Array::Create(s_name, "test");
VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1);
VERIFY(!arr.isNull());
VERIFY(arr[s_name] == "test");
VS(arr, Array(ArrayInit(1).set(s_name, "test").create()));
arrCopy = arr;
arr = Array::Create(s_name, arr);
VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1);
VERIFY(!arr.isNull());
VS(arr[s_name], arrCopy);
VERIFY(arr[s_name].toArray().size() == 1);
VS(arr, Array(ArrayInit(1).set(s_name, arrCopy).create()));
}
// iteration
{
Array arr = CREATE_MAP2("n1", "v1", "n2", "v2");
int i = 0;
for (ArrayIter iter = arr.begin(); iter; ++iter, ++i) {
if (i == 0) {
VERIFY(iter.first() == "n1");
VERIFY(iter.second() == "v1");
} else {
VERIFY(iter.first() == "n2");
VERIFY(iter.second() == "v2");
}
}
VERIFY(i == 2);
}
/* TODO: fix this
{
Variant arr = CREATE_MAP2("n1", "v1", "n2", "v2");
arr.escalate();
for (ArrayIterPtr iter = arr.begin(arr, true); !iter->end(); iter->next()){
unset(arr.lvalAt(iter->first()));
}
VS(arr, Array::Create());
}
*/
// conversions
{
Array arr0;
VERIFY(arr0.toBoolean() == false);
VERIFY(arr0.toByte() == 0);
VERIFY(arr0.toInt16() == 0);
VERIFY(arr0.toInt32() == 0);
VERIFY(arr0.toInt64() == 0);
VERIFY(arr0.toDouble() == 0.0);
VERIFY(arr0.toString() == "");
Array arr1 = Array::Create("test");
VERIFY(arr1.toBoolean() == true);
VERIFY(arr1.toByte() == 1);
VERIFY(arr1.toInt16() == 1);
VERIFY(arr1.toInt32() == 1);
VERIFY(arr1.toInt64() == 1);
VERIFY(arr1.toDouble() == 1.0);
VERIFY(arr1.toString() == "Array");
}
// offset
{
Array arr;
arr.set(0, "v1");
arr.set(1, "v2");
VS(arr, CREATE_VECTOR2("v1", "v2"));
}
{
Array arr;
arr.set(s_n1, "v1");
arr.set(s_n2, "v2");
VS(arr, CREATE_MAP2("n1", "v1", "n2", "v2"));
}
{
Array arr;
arr.lvalAt(0) = "v1";
arr.lvalAt(1) = "v2";
VS(arr, CREATE_VECTOR2("v1", "v2"));
}
{
Array arr;
arr.lvalAt(s_n1) = "v1";
arr.lvalAt(s_n2) = "v2";
VS(arr, CREATE_MAP2("n1", "v1", "n2", "v2"));
}
{
Array arr;
Variant name = "name";
arr.lvalAt(name) = "value";
VS(arr, CREATE_MAP1("name", "value"));
}
{
Array arr;
arr.lvalAt(s_A) = 10;
arr.lvalAt(s_A)++;
VS(arr[s_A], 11);
}
{
Array arr;
arr.lvalAt(1) = 10;
VS(arr[1], 10);
VS(arr[1.5], 10);
VS(arr[Variant(1.5)], 10);
VS(arr[s_1], 10);
VS(arr[Variant("1")], 10);
}
{
Array arr;
arr.lvalAt(Variant(1.5)) = 10;
VS(arr[1], 10);
VS(arr[1.5], 10);
VS(arr[Variant(1.5)], 10);
VS(arr[s_1], 10);
VS(arr[Variant("1")], 10);
}
{
Array arr;
arr.lvalAt(s_1) = 10;
VS(arr[1], 10);
VS(arr[1.5], 10);
VS(arr[Variant(1.5)], 10);
VS(arr[s_1], 10);
VS(arr[Variant("1")], 10);
}
{
Array arr;
arr.lvalAt(Variant("1")) = 10;
VS(arr[1], 10);
VS(arr[1.5], 10);
VS(arr[Variant(1.5)], 10);
VS(arr[s_1], 10);
VS(arr[Variant("1")], 10);
}
// membership
{
Array arr;
arr.lvalAt(0) = "v1";
arr.lvalAt(1) = "v2";
VERIFY(arr.exists(0));
arr.remove(0);
VERIFY(!arr.exists(0));
VS(arr, Array::Create(1, "v2"));
arr.append("v3");
VS(arr, CREATE_MAP2(1, "v2", 2, "v3"));
}
{
static const StaticString s_0("0");
Array arr;
arr.lvalAt(0) = "v1";
VERIFY(arr.exists(0));
arr.remove(String(s_0));
VERIFY(!arr.exists(0));
}
{
Array arr;
arr.lvalAt(0) = "v1";
VERIFY(arr.exists(0));
arr.remove(Variant("0"));
VERIFY(!arr.exists(0));
}
{
Array arr;
arr.lvalAt(0) = "v1";
VERIFY(arr.exists(0));
arr.remove(Variant(Variant("0")));
VERIFY(!arr.exists(0));
}
{
Array arr;
arr.lvalAt(0) = "v1";
VERIFY(arr.exists(0));
arr.remove(Variant(Variant(0.5)));
VERIFY(!arr.exists(0));
}
{
Array arr;
arr.lvalAt(Variant()) = 123;
VERIFY(arr.exists(empty_string));
arr.remove(Variant());
VERIFY(!arr.exists(empty_string));
}
{
Array arr;
arr.lvalAt(s_n1) = "v1";
arr.lvalAt(s_n2) = "v2";
VERIFY(arr.exists(s_n1));
arr.remove(s_n1);
VERIFY(!arr.exists(s_n1));
VS(arr, Array::Create(s_n2, "v2"));
arr.append("v3");
VS(arr, CREATE_MAP2("n2", "v2", 0, "v3"));
}
{
Array arr;
arr.lvalAt() = "test";
VS(arr, CREATE_VECTOR1("test"));
}
{
Array arr;
arr.lvalAt(s_name) = "value";
VERIFY(arr.exists(s_name));
}
{
Array arr;
arr.lvalAt(1) = "value";
VERIFY(arr.exists(1));
VERIFY(arr.exists(1.5));
VERIFY(arr.exists(s_1));
VERIFY(arr.exists(Variant("1")));
VERIFY(arr.exists(Variant(1)));
VERIFY(arr.exists(Variant(1.5)));
}
{
Array arr;
arr.lvalAt(s_1) = "value";
VERIFY(arr.exists(1));
VERIFY(arr.exists(1.5));
VERIFY(arr.exists(s_1));
VERIFY(arr.exists(Variant("1")));
VERIFY(arr.exists(Variant(1)));
VERIFY(arr.exists(Variant(1.5)));
}
{
Array arr;
arr.lvalAt(1.5) = "value";
VERIFY(arr.exists(1));
VERIFY(arr.exists(1.5));
VERIFY(arr.exists(s_1));
VERIFY(arr.exists(Variant("1")));
VERIFY(arr.exists(Variant(1)));
VERIFY(arr.exists(Variant(1.5)));
}
{
Array arr;
arr.lvalAt(Variant(1.5)) = "value";
VERIFY(arr.exists(1));
VERIFY(arr.exists(1.5));
VERIFY(arr.exists(s_1));
VERIFY(arr.exists(Variant("1")));
VERIFY(arr.exists(Variant(1)));
VERIFY(arr.exists(Variant(1.5)));
}
{
Array arr;
arr.lvalAt(Variant("1")) = "value";
VERIFY(arr.exists(1));
VERIFY(arr.exists(1.5));
VERIFY(arr.exists(s_1));
VERIFY(arr.exists(Variant("1")));
VERIFY(arr.exists(Variant(1)));
VERIFY(arr.exists(Variant(1.5)));
}
// merge
{
Array arr = Array::Create(0) + Array::Create(1);
VS(arr, Array::Create(0));
arr += CREATE_VECTOR2(0, 1);
VS(arr, CREATE_VECTOR2(0, 1));
arr = Array::Create(0).merge(Array::Create(1));
VS(arr, CREATE_VECTOR2(0, 1));
arr = arr.merge(CREATE_VECTOR2(0, 1));
VS(arr, CREATE_VECTOR4(0, 1, 0, 1));
arr = Array::Create("s0").merge(Array::Create("s1"));
VS(arr, CREATE_VECTOR2("s0", "s1"));
arr = Array::Create("n0", "s0") + Array::Create("n1", "s1");
VS(arr, CREATE_MAP2("n0", "s0", "n1", "s1"));
arr += CREATE_MAP2("n0", "s0", "n1", "s1");
VS(arr, CREATE_MAP2("n0", "s0", "n1", "s1"));
arr = Array::Create("n0", "s0").merge(Array::Create("n1", "s1"));
VS(arr, CREATE_MAP2("n0", "s0", "n1", "s1"));
Array arrX = CREATE_MAP2("n0", "s2", "n1", "s3");
arr = arr.merge(arrX);
VS(arr, CREATE_MAP2("n0", "s2", "n1", "s3"));
}
// slice
{
Array arr = CREATE_VECTOR2("test1", "test2");
Array sub = arr.slice(1, 1, true);
VS(sub, CREATE_MAP1(1, "test2"));
}
{
Array arr = CREATE_VECTOR2("test1", "test2");
Array sub = arr.slice(1, 1, false);
VS(sub, CREATE_VECTOR1("test2"));
}
{
Array arr = CREATE_MAP2("n1", "test1", "n2", "test2");
Array sub = arr.slice(1, 1, true);
VS(sub, CREATE_MAP1("n2", "test2"));
}
{
Array arr = CREATE_MAP2("n1", "test1", "n2", "test2");
Array sub = arr.slice(1, 1, false);
VS(sub, CREATE_MAP1("n2", "test2"));
}
// escalation
{
Array arr;
lval(arr.lvalAt(0)).lvalAt(0) = 1.2;
VS(arr, CREATE_VECTOR1(CREATE_VECTOR1(1.2)));
}
{
Array arr;
lval(arr.lvalAt(s_name)).lvalAt(0) = 1.2;
VS(arr, CREATE_MAP1(s_name, CREATE_VECTOR1(1.2)));
}
{
Array arr = Array::Create();
lval(arr.lvalAt(0)).lvalAt(0) = 1.2;
VS(arr, CREATE_VECTOR1(CREATE_VECTOR1(1.2)));
}
{
Array arr = Array::Create();
lval(arr.lvalAt(s_name)).lvalAt(0) = 1.2;
VS(arr, CREATE_MAP1(s_name, CREATE_VECTOR1(1.2)));
}
{
Array arr = Array::Create("test");
arr.lvalAt(0) = CREATE_VECTOR1(1.2);
VS(arr, CREATE_VECTOR1(CREATE_VECTOR1(1.2)));
}
{
Array arr = Array::Create("test");
lval(arr.lvalAt(s_name)).lvalAt(0) = 1.2;
VS(arr, CREATE_MAP2(0, "test", s_name, CREATE_VECTOR1(1.2)));
}
{
Array arr = Array::Create();
arr.append("apple");
arr.set(2, "pear");
VS(arr[2], "pear");
}
{
Array arr = CREATE_MAP2(0, "a", 1, "b");
VERIFY(arr->isVectorData());
}
{
Array arr = CREATE_MAP2(1, "a", 0, "b");
VERIFY(!arr->isVectorData());
}
{
Array arr = CREATE_MAP2(1, "a", 2, "b");
VERIFY(!arr->isVectorData());
}
{
Array arr = CREATE_MAP1(1, "a");
arr.set(0, "b");
VERIFY(!arr->isVectorData());
}
return Count(true);
}
bool TestCppBase::TestObject() {
{
String s = "O:1:\"B\":1:{s:3:\"obj\";O:1:\"A\":1:{s:1:\"a\";i:10;}}";
VS(f_serialize(unserialize_from_string(s)), "O:22:\"__PHP_Incomplete_Class\":2:{s:27:\"__PHP_Incomplete_Class_Name\";s:1:\"B\";s:3:\"obj\";O:22:\"__PHP_Incomplete_Class\":2:{s:27:\"__PHP_Incomplete_Class_Name\";s:1:\"A\";s:1:\"a\";i:10;}}");
}
VERIFY(!equal(Object(new TestResource()), Object(new TestResource()) ));
return Count(true);
}
bool TestCppBase::TestVariant() {
// operators
{
Variant v(15);
v += 20;
VERIFY(v.isNumeric());
VERIFY(v.is(KindOfInt64));
VERIFY(v == Variant(35));
}
// conversions
{
Variant v("123");
VERIFY(v.toInt32() == 123);
}
// offset
{
Variant v = "test";
VS(v.rvalAt(0), "t");
}
{
Variant v;
v.lvalAt(0) = "v0";
v.lvalAt(1) = "v1";
VERIFY(v[0] == "v0");
VERIFY(v[1] == "v1");
}
{
Variant v;
v.lvalAt() = "test";
VS(v, CREATE_VECTOR1("test"));
}
{
Variant v;
v.lvalAt(1) = "test";
VS(v[1], "test");
VS(v[1.5], "test");
VS(v[Variant(1.5)], "test");
VS(v["1"], "test");
VS(v[Variant("1")], "test");
}
{
Variant v;
v.lvalAt(Variant(1.5)) = "test";
VS(v[1], "test");
VS(v[1.5], "test");
VS(v[Variant(1.5)], "test");
VS(v["1"], "test");
VS(v[Variant("1")], "test");
}
{
Variant v;
v.lvalAt(s_1) = "test";
VS(v[1], "test");
VS(v[1.5], "test");
VS(v[Variant(1.5)], "test");
VS(v["1"], "test");
VS(v[Variant("1")], "test");
}
{
Variant v;
v.lvalAt(Variant("1")) = "test";
VS(v[1], "test");
VS(v[1.5], "test");
VS(v[Variant(1.5)], "test");
VS(v["1"], "test");
VS(v[Variant("1")], "test");
}
// membership
{
Variant v;
v.lvalAt(s_n0) = "v0";
v.lvalAt(s_n1) = "v1";
v.remove(s_n1);
VS(v, CREATE_MAP1(s_n0, "v0"));
v.append("v2");
VS(v, CREATE_MAP2(s_n0, "v0", 0, "v2"));
}
{
Variant v;
v.lvalAt(s_n0) = "v0";
v.lvalAt(1) = "v1";
v.remove(Variant(1.5));
VS(v, CREATE_MAP1("n0", "v0"));
}
{
Variant v;
v.lvalAt(s_n0) = "v0";
v.lvalAt(1) = "v1";
v.remove(Variant("1"));
VS(v, CREATE_MAP1("n0", "v0"));
}
{
Variant v;
v.lvalAt(s_n0) = "v0";
v.lvalAt(1) = "v1";
v.remove("1");
VS(v, CREATE_MAP1("n0", "v0"));
}
{
Variant v;
v.lvalAt(s_n0) = "v0";
v.lvalAt(empty_string) = "v1";
v.remove(Variant());
VS(v, CREATE_MAP1("n0", "v0"));
}
// references
{
Variant v1("original");
Variant v2 = v1;
v2 = "changed";
VERIFY(v1 == "original");
}
{
Variant v1("original");
Variant v2 = strongBind(v1);
v2 = "changed";
VERIFY(v1 == "changed");
}
{
Variant v1 = 10;
Variant v2 = Array(ArrayInit(1).setRef(v1).create());
v1 = 20;
VS(v2[0], 20);
}
{
Variant v1 = 10;
Variant v2;
v2.lvalAt() = ref(v1);
v1 = 20;
VS(v2[0], 20);
}
{
Variant v1 = 10;
Variant v2 = CREATE_VECTOR1(5);
v2.lvalAt() = ref(v1);
v1 = 20;
VS(v2[1], 20);
}
{
Variant v1 = 10;
Variant v2 = strongBind(v1);
v2++;
VS(v2, 11);
VS(v1, 11);
}
{
Variant arr = CREATE_VECTOR2(1, 2);
Variant v;
for (MutableArrayIter iter = arr.begin(nullptr, v); iter.advance();) {
v++;
}
VS(arr, CREATE_VECTOR2(2, 3));
}
// array escalation
{
Variant arr;
lval(arr.lvalAt(0)).lvalAt(0) = 1.2;
VS(arr, CREATE_VECTOR1(CREATE_VECTOR1(1.2)));
}
{
Variant arr;
lval(arr.lvalAt(s_name)).lvalAt(0) = 1.2;
VS(arr, CREATE_MAP1(s_name, CREATE_VECTOR1(1.2)));
}
{
Variant arr = Array::Create();
lval(arr.lvalAt(0)).lvalAt(0) = 1.2;
VS(arr, CREATE_VECTOR1(CREATE_VECTOR1(1.2)));
}
{
Variant arr = Array::Create();
lval(arr.lvalAt(s_name)).lvalAt(0) = 1.2;
VS(arr, CREATE_MAP1(s_name, CREATE_VECTOR1(1.2)));
}
{
Variant arr = Array::Create("test");
arr.lvalAt(0) = CREATE_VECTOR1(1.2);
VS(arr, CREATE_VECTOR1(CREATE_VECTOR1(1.2)));
}
{
Variant arr = Array::Create("test");
lval(arr.lvalAt(s_name)).lvalAt(0) = 1.2;
VS(arr, CREATE_MAP2(0, "test", s_name, CREATE_VECTOR1(1.2)));
}
return Count(true);
}
///////////////////////////////////////////////////////////////////////////////
class TestGlobals {
public:
TestGlobals() {
String a = "apple";
m_string = a + "orange"; // so mallocing m_data internally
m_array = CREATE_MAP2("a", "apple", "b", "orange");
}
Variant m_string;
Array m_array;
Variant m_string2;
Array m_array2;
Variant m_conn;
Variant m_curlconn;
Variant m_curlMultiConn;
String key;
String value;
DECLARE_SMART_ALLOCATION(TestGlobals);
void dump() {}
};
IMPLEMENT_SMART_ALLOCATION(TestGlobals);
/* Pull 32bit Big Endian words from an in6_addr */
static inline long in6addrWord(struct in6_addr addr, char wordNo) {
return ((addr.s6_addr[(wordNo*4)+0] << 24) |
(addr.s6_addr[(wordNo*4)+1] << 16) |
(addr.s6_addr[(wordNo*4)+2] << 8) |
(addr.s6_addr[(wordNo*4)+3] << 0)) & 0xFFFFFFFF;
}
bool TestCppBase::TestIpBlockMap() {
struct in6_addr addr;
int bits;
VERIFY(IpBlockMap::ReadIPv6Address("204.15.21.0/22", &addr, bits));
VS(bits, 118);
VS(in6addrWord(addr, 0), 0x00000000L);
VS(in6addrWord(addr, 1), 0x00000000L);
VS(in6addrWord(addr, 2), 0x0000FFFFL);
VS(in6addrWord(addr, 3), 0xCC0F1500L);
VERIFY(IpBlockMap::ReadIPv6Address("127.0.0.1", &addr, bits));
VS(bits, 128);
VS(in6addrWord(addr, 0), 0x00000000L);
VS(in6addrWord(addr, 1), 0x00000000L);
VS(in6addrWord(addr, 2), 0x0000FFFFL);
VS(in6addrWord(addr, 3), 0x7F000001L);
VERIFY(IpBlockMap::ReadIPv6Address(
"1111:2222:3333:4444:5555:6666:789a:bcde", &addr, bits));
VS(bits, 128);
VS(in6addrWord(addr, 0), 0x11112222L);
VS(in6addrWord(addr, 1), 0x33334444L);
VS(in6addrWord(addr, 2), 0x55556666L);
VS(in6addrWord(addr, 3), 0x789abcdeL);
VERIFY(IpBlockMap::ReadIPv6Address(
"1111:2222:3333:4444:5555:6666:789a:bcde/68", &addr, bits));
VS(bits, 68);
VS(in6addrWord(addr, 0), 0x11112222L);
VS(in6addrWord(addr, 1), 0x33334444L);
VS(in6addrWord(addr, 2), 0x55556666L);
VS(in6addrWord(addr, 3), 0x789abcdeL);
IpBlockMap::BinaryPrefixTrie root(true);
unsigned char value[16];
// Default value with no additional nodes
memset(value, 0, 16);
VERIFY(root.isAllowed(value, 1));
value[0] = 0x80;
VERIFY(root.isAllowed(value));
// Inheritance of parent allow value through multiple levels of new nodes
IpBlockMap::BinaryPrefixTrie::InsertNewPrefix(&root, value, 1, false);
value[0] = 0xf0;
IpBlockMap::BinaryPrefixTrie::InsertNewPrefix(&root, value, 4, true);
VERIFY(root.isAllowed(value));
value[0] = 0xe0;
VERIFY(!root.isAllowed(value));
value[0] = 0xc0;
VERIFY(!root.isAllowed(value));
value[0] = 0x80;
VERIFY(!root.isAllowed(value));
value[0] = 0;
VERIFY(root.isAllowed(value));
// > 1 byte in address
value[2] = 0xff;
IpBlockMap::BinaryPrefixTrie::InsertNewPrefix(&root, value, 24, false);
VERIFY(!root.isAllowed(value));
value[3] = 0xff;
VERIFY(!root.isAllowed(value));
value[2] = 0xfe;
VERIFY(root.isAllowed(value));
// Exact address match
value[2] = 0xff;
value[15] = 1;
IpBlockMap::BinaryPrefixTrie::InsertNewPrefix(&root, value, 128, true);
VERIFY(root.isAllowed(value));
Hdf hdf;
hdf.fromString(
" 0 {\n"
" Location = /test\n"
" AllowFirst = true\n"
" Ip {\n"
" Allow {\n"
" * = 127.0.0.1\n"
" }\n"
" Deny {\n"
" * = 8.32.0.0/24\n"
" * = aaaa:bbbb:cccc:dddd:eeee:ffff:1111::/80\n"
" }\n"
" }\n"
" }\n"
);
IpBlockMap ibm(hdf);
VERIFY(!ibm.isBlocking("test/blah.php", "127.0.0.1"));
VERIFY(ibm.isBlocking("test/blah.php", "8.32.0.104"));
VERIFY(ibm.isBlocking("test/blah.php",
"aaaa:bbbb:cccc:dddd:eeee:9999:8888:7777"));
VERIFY(!ibm.isBlocking("test/blah.php",
"aaaa:bbbb:cccc:dddd:eee3:4444:3333:2222"));
return Count(true);
}
bool TestCppBase::TestEqualAsStr() {
const int arr_len = 18;
Variant var_array[arr_len];
var_array[0] = false;
var_array[1] = true;
var_array[2] = 0;
var_array[3] = 1;
var_array[4] = 42;
var_array[5] = 0.0;
var_array[6] = 1.0;
var_array[7] = 42.2;
var_array[8] = "0";
var_array[9] = "1";
var_array[10] = "42";
var_array[11] = "x";
var_array[12] = Array::Create();
Variant v1("original");
var_array[13] = v1;
Variant v2("changed");
var_array[14] = v2;
var_array[15] = "";
var_array[16] = "Array";
var_array[17] = "ARRAY";
for (int i = 0; i < arr_len; i++) {
for (int j = 0; j < arr_len; j++) {
bool eqAsStr = equalAsStr(var_array[i], var_array[j]);
bool sm = same(toString(var_array[i]), toString(var_array[j]));
VERIFY(eqAsStr == sm);
}
}
return Count(true);
}