/* +----------------------------------------------------------------------+ | 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 #include #include #include #include #include #define VERIFY_DUMP(map, exp) \ if (!(exp)) { \ printf("%s:%d: [" #exp "] is false\n", __FILE__, __LINE__); \ map.dump(); \ return Count(false); \ } \ /////////////////////////////////////////////////////////////////////////////// TestUtil::TestUtil() { } /////////////////////////////////////////////////////////////////////////////// bool TestUtil::RunTests(const std::string &which) { bool ret = true; //RUN_TEST(TestLFUTable); RUN_TEST(TestSharedString); RUN_TEST(TestCanonicalize); RUN_TEST(TestHDF); return ret; } /////////////////////////////////////////////////////////////////////////////// // data types struct testhash { size_t operator()(CStrRef s) const { return hash_string(s.data(), s.size()); } }; struct testeqstr { bool operator()(CStrRef s1, CStrRef s2) const { return string_strcmp(s1.data(), s1.size(), s2.data(), s2.size()) == 0; } }; struct IHash { size_t operator()(int i) const { return i; } }; struct IEq { bool operator()(int i, int j) const { return i == j; } }; typedef LFUTable TestMap; bool TestUtil::TestLFUTable() { { TestMap table(1, 5, 2); table.insert(1,1); int r = 0; VERIFY(table.lookup(1, r) && r == 1); VERIFY(table.lookup(1, r) && r == 1); VERIFY(table.lookup(1, r) && r == 1); } { TestMap table(100, 5, 2); for (int i = 0; i < 10; i++) { table.insert(i,i); } VERIFY(table.check()); int r = 0; VERIFY(!table.lookup(0, r)); VERIFY(!table.lookup(1, r)); VERIFY(!table.lookup(2, r)); VERIFY(!table.lookup(3, r)); VERIFY(!table.lookup(4, r)); VERIFY(table.lookup(5, r) && r == 5); VERIFY(table.lookup(6, r) && r == 6); VERIFY(table.lookup(7, r) && r == 7); VERIFY(table.lookup(8, r) && r == 8); VERIFY(table.lookup(9, r) && r == 9); VERIFY(table.check()); } { TestMap table(1, 5, 2); for (int i = 0; i < 5; i++) { table.insert(i,i); } sleep(1); for (int i = 5; i < 10; i++) { table.insert(i,i); } VERIFY(table.check()); int r = 0; VERIFY(!table.lookup(0, r)); VERIFY(!table.lookup(1, r)); VERIFY(!table.lookup(2, r)); VERIFY(!table.lookup(3, r)); VERIFY(!table.lookup(4, r)); VERIFY(table.lookup(5, r) && r == 5); VERIFY(table.lookup(6, r) && r == 6); VERIFY(table.lookup(7, r) && r == 7); VERIFY(table.lookup(8, r) && r == 8); VERIFY(table.lookup(9, r) && r == 9); VERIFY(table.check()); } { TestMap table(1, 5, 2); for (int i = 0; i < 5; i++) { table.insert(i,i); } int r = 0; VERIFY(table.lookup(0, r) && r == 0); VERIFY(table.lookup(0, r) && r == 0); VERIFY(table.lookup(3, r) && r == 3); sleep(1); for (int i = 5; i < 8; i++) { table.insert(i,i); } VERIFY(table.lookup(0, r) && r == 0); VERIFY(!table.lookup(1, r)); VERIFY(!table.lookup(2, r)); VERIFY(table.lookup(3, r) && r == 3); VERIFY(!table.lookup(4, r)); VERIFY(table.lookup(5, r) && r == 5); VERIFY(table.lookup(6, r) && r == 6); VERIFY(table.lookup(7, r) && r == 7); int ct = 0; for (TestMap::const_iterator it = table.begin(); it != table.end(); ++it) { ct++; VERIFY(it.first() == it.second()); } VERIFY(ct == 5); } { TestMap table(1, 5, 2); for (int i = 0; i < 5; i++) { table[i] = i; } int r = 0; VERIFY(table[0] == 0); VERIFY(table[0] == 0); VERIFY(table[3] == 3); sleep(1); for (int i = 5; i < 8; i++) { table[i] = i; } VERIFY(table.check()); VERIFY(table.lookup(0, r) && r == 0); VERIFY(!table.lookup(1, r)); VERIFY(!table.lookup(2, r)); VERIFY(table.lookup(3, r) && r == 3); VERIFY(!table.lookup(4, r)); VERIFY(table.lookup(5, r) && r == 5); VERIFY(table.lookup(6, r) && r == 6); VERIFY(table.lookup(7, r) && r == 7); VERIFY(table.check()); int ct = 0; for (TestMap::const_iterator it = table.begin(); it != table.end(); ++it) { ct++; VERIFY(it.first() == it.second()); } VERIFY(ct == 5); } { class Reader : public TestMap::AtomicReader { public: void read(int const &k, int const &v) { } }; class Updater : public TestMap::AtomicUpdater { public: bool update(int const &k, int &v, bool newly) { v = k; return false; } }; Reader r; Updater u; TestMap table(1, 5, 2); for (int i = 0; i < 5; i++) { table.atomicUpdate(i, u, true); } for (int i = 0; i < 5; i++) { VERIFY(table.atomicRead(i, r)); } } return Count(true); } bool TestUtil::TestSharedString() { { SharedString foo = "foo"; SharedString bah("bah"); VERIFY(bah->getString() == "bah"); { SharedString bah2 = bah; VERIFY(bah2->getString() == "bah"); VERIFY(bah.get() == bah2.get()); SharedString bah3 = "bah"; VERIFY(bah.get() == bah3.get()); } VERIFY(bah->getString() == "bah"); VERIFY(foo->getString() == "foo"); } { hphp_shared_string_map map; for (int i = 0; i < 100; i++) { string k("key"); k += i; map[k] = i; } for (int i = 0; i < 100; i++) { string k("key"); k += i; hphp_shared_string_map::const_iterator it = map.find(k); VERIFY(it != map.end()); VERIFY(it->second == i); } } return Count(true); } bool TestUtil::TestCanonicalize() { VERIFY(Util::canonicalize("foo") == "foo"); VERIFY(Util::canonicalize("/foo") == "/foo"); VERIFY(Util::canonicalize("./foo") == "foo"); VERIFY(Util::canonicalize("foo/bar") == "foo/bar"); VERIFY(Util::canonicalize("foo/////bar") == "foo/bar"); VERIFY(Util::canonicalize("foo/bar/") == "foo/bar/"); VERIFY(Util::canonicalize("foo/../bar") == "bar"); VERIFY(Util::canonicalize("./foo/../bar") == "bar"); VERIFY(Util::canonicalize(".////foo/xyz////..////../bar") == "bar"); VERIFY(Util::canonicalize("a/foo../bar") == "a/foo../bar"); VERIFY(Util::canonicalize("a./foo/./bar") == "a./foo/bar"); VERIFY(Util::canonicalize("////a/foo") == "/a/foo"); VERIFY(Util::canonicalize("../foo") == "../foo"); VERIFY(Util::canonicalize("foo/../../bar") == "../bar"); VERIFY(Util::canonicalize("./../../") == "../../"); return Count(true); } bool TestUtil::TestHDF() { // This was causing a crash { Hdf doc, node; node = doc["Node"]; } { Hdf doc; doc.fromString( "node.* {\n" " name = value\n" "}"); VS(doc["node"][0]["name"].getString(), "value"); } return Count(true); }