1
0
Fork 0

forward ported node corrections from 3.4 (#9700)

* forward ported node corrections from 3.4
* tests fixed
This commit is contained in:
Kaveh Vahedipour 2019-08-15 15:48:49 +02:00 committed by Max Neunhöffer
parent 563deebbee
commit e91cc66b9e
11 changed files with 339 additions and 256 deletions

View File

@ -18,13 +18,13 @@ devel
* Updated TOKENS function to deal with primitive types and arrays. * Updated TOKENS function to deal with primitive types and arrays.
* Fixed agency nodes to not create bogus keys on delete / observe / unobserve
v3.5.0-rc.7 (2019-08-01) v3.5.0-rc.7 (2019-08-01)
------------------------ ------------------------
* Upgraded arangodb starter version to 0.14.12. * Upgraded arangodb starter version to 0.14.12.
v3.5.0-rc.6 (2019-07-29) v3.5.0-rc.6 (2019-07-29)
------------------------ ------------------------

View File

@ -1,24 +1 @@
1s/^\(.*\)$/\.TH \1/
s/^ //
/NAME/s/^\(.*\)$/\.SH \1/
/SYNOPSIS/s/^\(.*\)$/\.SH \1/
/DESCRIPTION/s/^\(.*\)$/\.SH \1/
/OPTIONS/s/^\(.*\)$/\.SH \1/
/EXAMPLES/s/^\(.*\)$/\.SH \1/
/FILES/s/^\(.*\)$/\.SH \1/
/AUTHOR/s/^\(.*\)$/\.SH AUTHOR\
Copyright ArangoDB GmbH, Cologne, Germany\
/
/SEE ALSO/s/^\(.*\)$/\.SH \1/
s/\<OPTION\>/\.IP/g
s/\<ENDOPTION\>//g
s/\<EXAMPLE\> \(.*\)/\.nf\
shell> \1\
\.fi\
/g
s/\<ENDEXAMPLE\>/\
/g
/SEE ALSO/,/AUTHOR/{
/^[a-z]/s/^\(.*\)$/\.BR \1/
s/(\([1-9]\))/ "(\1), "/g
}

View File

@ -43,13 +43,38 @@ using namespace arangodb::basics;
const Node::Children Node::dummyChildren = Node::Children(); const Node::Children Node::dummyChildren = Node::Children();
const Node Node::_dummyNode = Node("dumm-di-dumm"); const Node Node::_dummyNode = Node("dumm-di-dumm");
static std::string const SLASH("/");
static std::regex const reg("/+");
std::string Node::normalize(std::string const& path) {
if (path.empty()) {
return SLASH;
}
std::string key = std::regex_replace(path, reg, SLASH);
// Must specify absolute path
if (key.front() != SLASH.front()) {
key = SLASH + key;
}
// Remove trailing slash
if (key.size() > 2 && key.back() == SLASH.front()) {
key.pop_back();
}
return key;
}
/// @brief Split strings by separator /// @brief Split strings by separator
inline static std::vector<std::string> split(const std::string& str, char separator) { inline static std::vector<std::string> split(const std::string& str, char separator) {
std::vector<std::string> result; std::vector<std::string> result;
if (str.empty()) { if (str.empty()) {
return result; return result;
} }
std::regex reg("/+");
std::string key = std::regex_replace(str, reg, "/"); std::string key = std::regex_replace(str, reg, "/");
if (!key.empty() && key.front() == '/') { if (!key.empty() && key.front() == '/') {
@ -180,7 +205,7 @@ Node::Node(Node const& other)
/// 1. remove any existing time to live entry /// 1. remove any existing time to live entry
/// 2. clear children map /// 2. clear children map
/// 3. copy from rhs buffer to my buffer /// 3. copy from rhs buffer to my buffer
/// @brief Must not copy _parent, _ttl, _observers /// @brief Must not copy _parent, _store, _ttl
Node& Node::operator=(VPackSlice const& slice) { Node& Node::operator=(VPackSlice const& slice) {
removeTimeToLive(); removeTimeToLive();
_children.clear(); _children.clear();
@ -207,7 +232,7 @@ Node& Node::operator=(Node&& rhs) {
// 1. remove any existing time to live entry // 1. remove any existing time to live entry
// 2. move children map over // 2. move children map over
// 3. move value over // 3. move value over
// Must not move over rhs's _parent, _store, _observers // Must not move over rhs's _parent, _store
_nodeName = std::move(rhs._nodeName); _nodeName = std::move(rhs._nodeName);
_children = std::move(rhs._children); _children = std::move(rhs._children);
// The _children map has been moved here, therefore we must // The _children map has been moved here, therefore we must
@ -229,7 +254,7 @@ Node& Node::operator=(Node const& rhs) {
// 1. remove any existing time to live entry // 1. remove any existing time to live entry
// 2. clear children map // 2. clear children map
// 3. move from rhs to buffer pointer // 3. move from rhs to buffer pointer
// Must not move rhs's _parent, _store, _observers // Must not move rhs's _parent, _store
removeTimeToLive(); removeTimeToLive();
_nodeName = rhs._nodeName; _nodeName = rhs._nodeName;
_children.clear(); _children.clear();
@ -424,22 +449,18 @@ bool Node::removeTimeToLive() {
return true; return true;
} }
inline bool Node::observedBy(std::string const& url) const {
auto ret = store().observerTable().equal_range(url);
for (auto it = ret.first; it != ret.second; ++it) {
if (it->second == uri()) {
return true;
}
}
return false;
}
namespace arangodb { namespace arangodb {
namespace consensus { namespace consensus {
/// Set value /// Set value
template <> template <>
bool Node::handle<SET>(VPackSlice const& slice) { bool Node::handle<SET>(VPackSlice const& slice) {
if (!slice.hasKey("new")) {
LOG_TOPIC("ad662", WARN, Logger::AGENCY)
<< "Operator set without new value: " << slice.toJson();
return false;
}
Slice val = slice.get("new"); Slice val = slice.get("new");
if (val.isObject()) { if (val.isObject()) {
@ -676,50 +697,6 @@ bool Node::handle<SHIFT>(VPackSlice const& slice) {
return true; return true;
} }
/// Add observer for this node
template <>
bool Node::handle<OBSERVE>(VPackSlice const& slice) {
if (!slice.hasKey("url")) return false;
if (!slice.get("url").isString()) return false;
std::string url(slice.get("url").copyString()), uri(this->uri());
// check if such entry exists
if (!observedBy(url)) {
store().observerTable().emplace(std::pair<std::string, std::string>(url, uri));
store().observedTable().emplace(std::pair<std::string, std::string>(uri, url));
return true;
}
return false;
}
/// Remove observer for this node
template <>
bool Node::handle<UNOBSERVE>(VPackSlice const& slice) {
if (!slice.hasKey("url")) return false;
if (!slice.get("url").isString()) return false;
std::string url(slice.get("url").copyString()), uri(this->uri());
// delete in both cases a single entry (ensured above)
// breaking the iterators is fine then
auto ret = store().observerTable().equal_range(url);
for (auto it = ret.first; it != ret.second; ++it) {
if (it->second == uri) {
store().observerTable().erase(it);
break;
}
}
ret = store().observedTable().equal_range(uri);
for (auto it = ret.first; it != ret.second; ++it) {
if (it->second == url) {
store().observedTable().erase(it);
return true;
}
}
return false;
}
} // namespace consensus } // namespace consensus
} // namespace arangodb } // namespace arangodb
@ -749,20 +726,6 @@ bool Node::applieOp(VPackSlice const& slice) {
return handle<PREPEND>(slice); return handle<PREPEND>(slice);
} else if (oper == "shift") { // "op":"shift" } else if (oper == "shift") { // "op":"shift"
return handle<SHIFT>(slice); return handle<SHIFT>(slice);
} else if (oper == "observe") { // "op":"observe"
return handle<OBSERVE>(slice);
} else if (oper == "unobserve") { // "op":"unobserve"
handle<UNOBSERVE>(slice);
if (_children.empty() && _value.empty()) {
if (_parent == nullptr) { // root node
_children.clear();
_value.clear();
return true;
} else {
return _parent->removeChild(_nodeName);
}
}
return true;
} else if (oper == "erase") { // "op":"erase" } else if (oper == "erase") { // "op":"erase"
return handle<ERASE>(slice); return handle<ERASE>(slice);
} else if (oper == "replace") { // "op":"replace" } else if (oper == "replace") { // "op":"replace"

View File

@ -180,21 +180,15 @@ class Node {
/// @brief Get value type /// @brief Get value type
ValueType valueType() const; ValueType valueType() const;
/// @brief Add observer for this node
bool addObserver(std::string const&);
/// @brief Add observer for this node
void notifyObservers(std::string const& origin) const;
/// @brief Is this node being observed by url
bool observedBy(std::string const& url) const;
/// @brief Get our container /// @brief Get our container
Store& store(); Store& store();
/// @brief Get our container /// @brief Get our container
Store const& store() const; Store const& store() const;
/// brief Normalize node URIs
static std::string normalize(std::string const& key);
private: private:
/// @brief Get store if it exists: /// @brief Get store if it exists:

View File

@ -1,4 +1,3 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER /// DISCLAIMER
/// ///
@ -690,7 +689,51 @@ bool Store::applies(arangodb::velocypack::Slice const& transaction) {
Slice value = transaction.get(key); Slice value = transaction.get(key);
if (value.isObject() && value.hasKey("op")) { if (value.isObject() && value.hasKey("op")) {
_node.hasAsWritableNode(abskeys.at(i)).first.applieOp(value); if (value.get("op").isEqualString("delete") ||
value.get("op").isEqualString("replace") ||
value.get("op").isEqualString("erase")) {
if (!_node.has(abskeys.at(i))) {
continue;
}
}
auto uri = Node::normalize(abskeys.at(i));
if (value.get("op").isEqualString("observe")) {
bool found = false;
if (value.hasKey("url") && value.get("url").isString()) {
auto url = value.get("url").copyString();
auto ret = _observerTable.equal_range(url);
for (auto it = ret.first; it != ret.second; ++it) {
if (it->second == uri) {
found = true;
break;
}
}
if (!found) {
_observerTable.emplace(std::pair<std::string, std::string>(url, uri));
_observedTable.emplace(std::pair<std::string, std::string>(uri, url));
}
}
} else if (value.get("op").isEqualString("unobserve")) {
if (value.hasKey("url") && value.get("url").isString()) {
auto url = value.get("url").copyString();
auto ret = _observerTable.equal_range(url);
for (auto it = ret.first; it != ret.second; ++it) {
if (it->second == uri) {
_observerTable.erase(it);
break;
}
}
ret = _observedTable.equal_range(uri);
for (auto it = ret.first; it != ret.second; ++it) {
if (it->second == url) {
_observedTable.erase(it);
break;
}
}
}
} else {
_node.hasAsWritableNode(abskeys.at(i)).first.applieOp(value);
}
} else { } else {
_node.hasAsWritableNode(abskeys.at(i)).first.applies(value); _node.hasAsWritableNode(abskeys.at(i)).first.applies(value);
} }

View File

@ -248,12 +248,16 @@ TEST_F(ClusterInfoTest, test_drop_database) {
auto viewCreateJson = arangodb::velocypack::Parser::fromJson( auto viewCreateJson = arangodb::velocypack::Parser::fromJson(
"{ \"name\": \"testView\", \"type\": \"testViewType\" }"); "{ \"name\": \"testView\", \"type\": \"testViewType\" }");
TRI_vocbase_t* vocbase; // will be owned by DatabaseFeature TRI_vocbase_t* vocbase; // will be owned by DatabaseFeature
// create database
ASSERT_TRUE((TRI_ERROR_NO_ERROR == ASSERT_TRUE((TRI_ERROR_NO_ERROR ==
database->createDatabase(1, "testDatabase", vocbase))); database->createDatabase(1, "testDatabase", vocbase)));
ASSERT_TRUE((nullptr != vocbase)); ASSERT_TRUE((nullptr != vocbase));
ASSERT_TRUE((ci->createDatabaseCoordinator(vocbase->name(),
arangodb::velocypack::Slice::emptyObjectSlice(), 0.0) // simulate heartbeat thread
.ok())); ASSERT_TRUE(arangodb::AgencyComm().setValue("Current/Databases/testDatabase", arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
ASSERT_TRUE(ci->createDatabaseCoordinator(
vocbase->name(),
arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).ok());
// initial view creation // initial view creation
{ {
@ -262,12 +266,11 @@ TEST_F(ClusterInfoTest, test_drop_database) {
(viewFactory.create(logicalView, *vocbase, viewCreateJson->slice()).ok())); (viewFactory.create(logicalView, *vocbase, viewCreateJson->slice()).ok()));
ASSERT_TRUE((false == !logicalView)); ASSERT_TRUE((false == !logicalView));
} }
EXPECT_TRUE((ci->dropDatabaseCoordinator(vocbase->name(), 0.0).ok())); EXPECT_TRUE((ci->dropDatabaseCoordinator(vocbase->name(), 0.0).ok()));
EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), ASSERT_TRUE(arangodb::AgencyComm().setValue("Current/Databases/testDatabase", arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
arangodb::velocypack::Slice::emptyObjectSlice(), 0.0) EXPECT_TRUE((ci->createDatabaseCoordinator(
.ok())); vocbase->name(),
arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).ok()));
arangodb::LogicalView::ptr logicalView; arangodb::LogicalView::ptr logicalView;
EXPECT_TRUE( EXPECT_TRUE(
(viewFactory.create(logicalView, *vocbase, viewCreateJson->slice()).ok())); (viewFactory.create(logicalView, *vocbase, viewCreateJson->slice()).ok()));

View File

@ -458,6 +458,7 @@ TEST_F(IResearchFeatureTest, test_upgrade0_1) {
TRI_vocbase_t* vocbase; // will be owned by DatabaseFeature TRI_vocbase_t* vocbase; // will be owned by DatabaseFeature
ASSERT_TRUE((TRI_ERROR_NO_ERROR == database->createDatabase(1, "testDatabase", vocbase))); ASSERT_TRUE((TRI_ERROR_NO_ERROR == database->createDatabase(1, "testDatabase", vocbase)));
ASSERT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
ASSERT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).ok())); ASSERT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).ok()));
ASSERT_TRUE((ci->createCollectionCoordinator(vocbase->name(), collectionId, 0, 1, 1, false, collectionJson->slice(), 0.0).ok())); ASSERT_TRUE((ci->createCollectionCoordinator(vocbase->name(), collectionId, 0, 1, 1, false, collectionJson->slice(), 0.0).ok()));
auto logicalCollection = ci->getCollection(vocbase->name(), collectionId); auto logicalCollection = ci->getCollection(vocbase->name(), collectionId);

View File

@ -280,6 +280,7 @@ TEST_F(IResearchLinkCoordinatorTest, test_create_drop) {
EXPECT_TRUE(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR == vocbase->type()); EXPECT_TRUE(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR == vocbase->type());
EXPECT_TRUE(1 == vocbase->id()); EXPECT_TRUE(1 == vocbase->id());
EXPECT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0) EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0)
.ok())); .ok()));
} }

View File

@ -316,6 +316,7 @@ TEST_F(IResearchViewCoordinatorTest, visit_collections) {
ASSERT_TRUE((nullptr != database)); ASSERT_TRUE((nullptr != database));
ASSERT_TRUE((TRI_ERROR_NO_ERROR == database->createDatabase(1, "testVocbase", vocbase))); ASSERT_TRUE((TRI_ERROR_NO_ERROR == database->createDatabase(1, "testVocbase", vocbase)));
ASSERT_TRUE((nullptr != vocbase)); ASSERT_TRUE((nullptr != vocbase));
ASSERT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
ASSERT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), ASSERT_TRUE((ci->createDatabaseCoordinator(vocbase->name(),
arangodb::velocypack::Slice::emptyObjectSlice(), 0.0) arangodb::velocypack::Slice::emptyObjectSlice(), 0.0)
.ok())); .ok()));
@ -400,6 +401,7 @@ TEST_F(IResearchViewCoordinatorTest, test_defaults) {
EXPECT_TRUE((TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR == vocbase->type())); EXPECT_TRUE((TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR == vocbase->type()));
EXPECT_TRUE((1 == vocbase->id())); EXPECT_TRUE((1 == vocbase->id()));
EXPECT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0) EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0)
.ok())); .ok()));
} }
@ -692,7 +694,7 @@ TEST_F(IResearchViewCoordinatorTest, test_create_drop_view) {
EXPECT_TRUE("testDatabase" == vocbase->name()); EXPECT_TRUE("testDatabase" == vocbase->name());
EXPECT_TRUE(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR == vocbase->type()); EXPECT_TRUE(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR == vocbase->type());
EXPECT_TRUE(1 == vocbase->id()); EXPECT_TRUE(1 == vocbase->id());
EXPECT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0) EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0)
.ok())); .ok()));
} }
@ -841,6 +843,7 @@ TEST_F(IResearchViewCoordinatorTest, test_create_link_in_background) {
ASSERT_EQ(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR, vocbase->type()); ASSERT_EQ(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR, vocbase->type());
ASSERT_EQ(1, vocbase->id()); ASSERT_EQ(1, vocbase->id());
ASSERT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
ASSERT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0) ASSERT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0)
.ok())); .ok()));
} }
@ -958,6 +961,7 @@ TEST_F(IResearchViewCoordinatorTest, test_drop_with_link) {
EXPECT_TRUE((TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR == vocbase->type())); EXPECT_TRUE((TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR == vocbase->type()));
EXPECT_TRUE((1 == vocbase->id())); EXPECT_TRUE((1 == vocbase->id()));
EXPECT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0) EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0)
.ok())); .ok()));
} }
@ -1086,7 +1090,7 @@ TEST_F(IResearchViewCoordinatorTest, test_update_properties) {
EXPECT_TRUE("testDatabase" == vocbase->name()); EXPECT_TRUE("testDatabase" == vocbase->name());
EXPECT_TRUE(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR == vocbase->type()); EXPECT_TRUE(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR == vocbase->type());
EXPECT_TRUE(1 == vocbase->id()); EXPECT_TRUE(1 == vocbase->id());
EXPECT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0) EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0)
.ok())); .ok()));
} }
@ -1257,7 +1261,7 @@ TEST_F(IResearchViewCoordinatorTest, test_overwrite_immutable_properties) {
EXPECT_EQ("testDatabase", vocbase->name()); EXPECT_EQ("testDatabase", vocbase->name());
EXPECT_EQ(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR, vocbase->type()); EXPECT_EQ(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR, vocbase->type());
EXPECT_EQ(1, vocbase->id()); EXPECT_EQ(1, vocbase->id());
EXPECT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
EXPECT_TRUE(ci->createDatabaseCoordinator(vocbase->name(), EXPECT_TRUE(ci->createDatabaseCoordinator(vocbase->name(),
VPackSlice::emptyObjectSlice(), 0.0) VPackSlice::emptyObjectSlice(), 0.0)
.ok()); .ok());
@ -1457,7 +1461,7 @@ TEST_F(IResearchViewCoordinatorTest, test_update_links_partial_remove) {
EXPECT_TRUE("testDatabase" == vocbase->name()); EXPECT_TRUE("testDatabase" == vocbase->name());
EXPECT_TRUE(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR == vocbase->type()); EXPECT_TRUE(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR == vocbase->type());
EXPECT_TRUE(1 == vocbase->id()); EXPECT_TRUE(1 == vocbase->id());
EXPECT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0) EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0)
.ok())); .ok()));
} }
@ -2049,7 +2053,7 @@ TEST_F(IResearchViewCoordinatorTest, test_update_links_partial_add) {
EXPECT_TRUE("testDatabase" == vocbase->name()); EXPECT_TRUE("testDatabase" == vocbase->name());
EXPECT_TRUE(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR == vocbase->type()); EXPECT_TRUE(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR == vocbase->type());
EXPECT_TRUE(1 == vocbase->id()); EXPECT_TRUE(1 == vocbase->id());
EXPECT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0) EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0)
.ok())); .ok()));
} }
@ -2692,7 +2696,7 @@ TEST_F(IResearchViewCoordinatorTest, test_update_links_replace) {
EXPECT_TRUE("testDatabase" == vocbase->name()); EXPECT_TRUE("testDatabase" == vocbase->name());
EXPECT_TRUE(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR == vocbase->type()); EXPECT_TRUE(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR == vocbase->type());
EXPECT_TRUE(1 == vocbase->id()); EXPECT_TRUE(1 == vocbase->id());
EXPECT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0) EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0)
.ok())); .ok()));
} }
@ -3293,7 +3297,7 @@ TEST_F(IResearchViewCoordinatorTest, test_update_links_clear) {
EXPECT_TRUE("testDatabase" == vocbase->name()); EXPECT_TRUE("testDatabase" == vocbase->name());
EXPECT_TRUE(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR == vocbase->type()); EXPECT_TRUE(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR == vocbase->type());
EXPECT_TRUE(1 == vocbase->id()); EXPECT_TRUE(1 == vocbase->id());
EXPECT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0) EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0)
.ok())); .ok()));
} }
@ -3758,7 +3762,7 @@ TEST_F(IResearchViewCoordinatorTest, test_drop_link) {
EXPECT_TRUE("testDatabase" == vocbase->name()); EXPECT_TRUE("testDatabase" == vocbase->name());
EXPECT_TRUE(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR == vocbase->type()); EXPECT_TRUE(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR == vocbase->type());
EXPECT_TRUE(1 == vocbase->id()); EXPECT_TRUE(1 == vocbase->id());
EXPECT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0) EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0)
.ok())); .ok()));
} }
@ -4067,7 +4071,7 @@ TEST_F(IResearchViewCoordinatorTest, test_update_overwrite) {
EXPECT_TRUE(("testDatabase" == vocbase->name())); EXPECT_TRUE(("testDatabase" == vocbase->name()));
EXPECT_TRUE((TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR == vocbase->type())); EXPECT_TRUE((TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR == vocbase->type()));
EXPECT_TRUE((1 == vocbase->id())); EXPECT_TRUE((1 == vocbase->id()));
EXPECT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0) EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0)
.ok())); .ok()));
} }
@ -4832,7 +4836,7 @@ TEST_F(IResearchViewCoordinatorTest, test_update_partial) {
EXPECT_TRUE(("testDatabase" == vocbase->name())); EXPECT_TRUE(("testDatabase" == vocbase->name()));
EXPECT_TRUE((TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR == vocbase->type())); EXPECT_TRUE((TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR == vocbase->type()));
EXPECT_TRUE((1 == vocbase->id())); EXPECT_TRUE((1 == vocbase->id()));
EXPECT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0) EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0)
.ok())); .ok()));
} }
@ -5603,7 +5607,7 @@ TEST_F(IResearchViewCoordinatorTest, IResearchViewNode_createBlock) {
EXPECT_TRUE("testDatabase" == vocbase->name()); EXPECT_TRUE("testDatabase" == vocbase->name());
EXPECT_TRUE(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR == vocbase->type()); EXPECT_TRUE(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_COORDINATOR == vocbase->type());
EXPECT_TRUE(1 == vocbase->id()); EXPECT_TRUE(1 == vocbase->id());
EXPECT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0) EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0)
.ok())); .ok()));
} }

View File

@ -243,7 +243,7 @@ TEST_F(IResearchViewDBServerTest, test_drop) {
EXPECT_TRUE("testDatabase" == vocbase->name()); EXPECT_TRUE("testDatabase" == vocbase->name());
EXPECT_TRUE(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL == vocbase->type()); EXPECT_TRUE(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL == vocbase->type());
EXPECT_TRUE(1 == vocbase->id()); EXPECT_TRUE(1 == vocbase->id());
EXPECT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0) EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0)
.ok())); .ok()));
} }
@ -360,7 +360,7 @@ TEST_F(IResearchViewDBServerTest, test_drop_cid) {
EXPECT_TRUE("testDatabase" == vocbase->name()); EXPECT_TRUE("testDatabase" == vocbase->name());
EXPECT_TRUE(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL == vocbase->type()); EXPECT_TRUE(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL == vocbase->type());
EXPECT_TRUE(1 == vocbase->id()); EXPECT_TRUE(1 == vocbase->id());
EXPECT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0) EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0)
.ok())); .ok()));
} }
@ -425,6 +425,7 @@ TEST_F(IResearchViewDBServerTest, test_drop_database) {
ASSERT_TRUE((TRI_ERROR_NO_ERROR == ASSERT_TRUE((TRI_ERROR_NO_ERROR ==
databaseFeature->createDatabase(0, "testDatabase" TOSTRING(__LINE__), vocbase))); databaseFeature->createDatabase(0, "testDatabase" TOSTRING(__LINE__), vocbase)));
ASSERT_TRUE((nullptr != vocbase)); ASSERT_TRUE((nullptr != vocbase));
ASSERT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
ASSERT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), ASSERT_TRUE((ci->createDatabaseCoordinator(vocbase->name(),
arangodb::velocypack::Slice::emptyObjectSlice(), 0.) arangodb::velocypack::Slice::emptyObjectSlice(), 0.)
.ok())); .ok()));
@ -463,7 +464,7 @@ TEST_F(IResearchViewDBServerTest, test_ensure) {
EXPECT_TRUE("testDatabase" == vocbase->name()); EXPECT_TRUE("testDatabase" == vocbase->name());
EXPECT_TRUE(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL == vocbase->type()); EXPECT_TRUE(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL == vocbase->type());
EXPECT_TRUE(1 == vocbase->id()); EXPECT_TRUE(1 == vocbase->id());
EXPECT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0) EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0)
.ok())); .ok()));
} }
@ -621,6 +622,7 @@ TEST_F(IResearchViewDBServerTest, test_query) {
TRI_vocbase_t* vocbase; // will be owned by DatabaseFeature TRI_vocbase_t* vocbase; // will be owned by DatabaseFeature
ASSERT_TRUE((TRI_ERROR_NO_ERROR == ASSERT_TRUE((TRI_ERROR_NO_ERROR ==
database->createDatabase(1, "testDatabase0", vocbase))); database->createDatabase(1, "testDatabase0", vocbase)));
EXPECT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0) EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0)
.ok())); .ok()));
auto logicalCollection = vocbase->createCollection(collectionJson->slice()); auto logicalCollection = vocbase->createCollection(collectionJson->slice());
@ -664,6 +666,7 @@ TEST_F(IResearchViewDBServerTest, test_query) {
TRI_vocbase_t* vocbase; // will be owned by DatabaseFeature TRI_vocbase_t* vocbase; // will be owned by DatabaseFeature
ASSERT_TRUE((TRI_ERROR_NO_ERROR == ASSERT_TRUE((TRI_ERROR_NO_ERROR ==
database->createDatabase(1, "testDatabase1", vocbase))); database->createDatabase(1, "testDatabase1", vocbase)));
EXPECT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0) EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0)
.ok())); .ok()));
auto logicalCollection = vocbase->createCollection(collectionJson->slice()); auto logicalCollection = vocbase->createCollection(collectionJson->slice());
@ -731,6 +734,7 @@ TEST_F(IResearchViewDBServerTest, test_query) {
ASSERT_TRUE((TRI_ERROR_NO_ERROR == ASSERT_TRUE((TRI_ERROR_NO_ERROR ==
databaseFeature->createDatabase(0, "testDatabase" TOSTRING(__LINE__), vocbase))); databaseFeature->createDatabase(0, "testDatabase" TOSTRING(__LINE__), vocbase)));
ASSERT_TRUE((nullptr != vocbase)); ASSERT_TRUE((nullptr != vocbase));
ASSERT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
ASSERT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), ASSERT_TRUE((ci->createDatabaseCoordinator(vocbase->name(),
arangodb::velocypack::Slice::emptyObjectSlice(), 0.) arangodb::velocypack::Slice::emptyObjectSlice(), 0.)
.ok())); .ok()));
@ -831,9 +835,10 @@ TEST_F(IResearchViewDBServerTest, test_query) {
ASSERT_TRUE((TRI_ERROR_NO_ERROR == ASSERT_TRUE((TRI_ERROR_NO_ERROR ==
databaseFeature->createDatabase(0, "testDatabase" TOSTRING(__LINE__), vocbase))); databaseFeature->createDatabase(0, "testDatabase" TOSTRING(__LINE__), vocbase)));
ASSERT_TRUE((nullptr != vocbase)); ASSERT_TRUE((nullptr != vocbase));
ASSERT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), ASSERT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
arangodb::velocypack::Slice::emptyObjectSlice(), 0.) EXPECT_TRUE((ci->createDatabaseCoordinator(
.ok())); vocbase->name(),
arangodb::velocypack::Slice::emptyObjectSlice(), 0.).ok()));
auto logicalCollection = vocbase->createCollection(collectionJson->slice()); auto logicalCollection = vocbase->createCollection(collectionJson->slice());
EXPECT_TRUE( EXPECT_TRUE(
(ci->createViewCoordinator(vocbase->name(), "42", createJson->slice()).ok())); (ci->createViewCoordinator(vocbase->name(), "42", createJson->slice()).ok()));
@ -1122,7 +1127,7 @@ TEST_F(IResearchViewDBServerTest, test_transaction_snapshot) {
EXPECT_TRUE("testDatabase" == vocbase->name()); EXPECT_TRUE("testDatabase" == vocbase->name());
EXPECT_TRUE(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL == vocbase->type()); EXPECT_TRUE(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL == vocbase->type());
EXPECT_TRUE(1 == vocbase->id()); EXPECT_TRUE(1 == vocbase->id());
EXPECT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0) EXPECT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), VPackSlice::emptyObjectSlice(), 0.0)
.ok())); .ok()));
} }
@ -1265,6 +1270,7 @@ TEST_F(IResearchViewDBServerTest, test_updateProperties) {
ASSERT_TRUE((TRI_ERROR_NO_ERROR == ASSERT_TRUE((TRI_ERROR_NO_ERROR ==
databaseFeature->createDatabase(0, "testDatabase" TOSTRING(__LINE__), vocbase))); databaseFeature->createDatabase(0, "testDatabase" TOSTRING(__LINE__), vocbase)));
ASSERT_TRUE((nullptr != vocbase)); ASSERT_TRUE((nullptr != vocbase));
ASSERT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
ASSERT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), ASSERT_TRUE((ci->createDatabaseCoordinator(vocbase->name(),
arangodb::velocypack::Slice::emptyObjectSlice(), 0.) arangodb::velocypack::Slice::emptyObjectSlice(), 0.)
.ok())); .ok()));
@ -1390,6 +1396,7 @@ TEST_F(IResearchViewDBServerTest, test_updateProperties) {
ASSERT_TRUE((TRI_ERROR_NO_ERROR == ASSERT_TRUE((TRI_ERROR_NO_ERROR ==
databaseFeature->createDatabase(0, "testDatabase" TOSTRING(__LINE__), vocbase))); databaseFeature->createDatabase(0, "testDatabase" TOSTRING(__LINE__), vocbase)));
ASSERT_TRUE((nullptr != vocbase)); ASSERT_TRUE((nullptr != vocbase));
ASSERT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
ASSERT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), ASSERT_TRUE((ci->createDatabaseCoordinator(vocbase->name(),
arangodb::velocypack::Slice::emptyObjectSlice(), 0.) arangodb::velocypack::Slice::emptyObjectSlice(), 0.)
.ok())); .ok()));
@ -1518,6 +1525,7 @@ TEST_F(IResearchViewDBServerTest, test_updateProperties) {
ASSERT_TRUE((TRI_ERROR_NO_ERROR == ASSERT_TRUE((TRI_ERROR_NO_ERROR ==
databaseFeature->createDatabase(0, "testDatabase" TOSTRING(__LINE__), vocbase))); databaseFeature->createDatabase(0, "testDatabase" TOSTRING(__LINE__), vocbase)));
ASSERT_TRUE((nullptr != vocbase)); ASSERT_TRUE((nullptr != vocbase));
ASSERT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
ASSERT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), ASSERT_TRUE((ci->createDatabaseCoordinator(vocbase->name(),
arangodb::velocypack::Slice::emptyObjectSlice(), 0.) arangodb::velocypack::Slice::emptyObjectSlice(), 0.)
.ok())); .ok()));
@ -1651,6 +1659,7 @@ TEST_F(IResearchViewDBServerTest, test_updateProperties) {
ASSERT_TRUE((TRI_ERROR_NO_ERROR == ASSERT_TRUE((TRI_ERROR_NO_ERROR ==
databaseFeature->createDatabase(0, "testDatabase" TOSTRING(__LINE__), vocbase))); databaseFeature->createDatabase(0, "testDatabase" TOSTRING(__LINE__), vocbase)));
ASSERT_TRUE((nullptr != vocbase)); ASSERT_TRUE((nullptr != vocbase));
ASSERT_TRUE(arangodb::AgencyComm().setValue(std::string("Current/Databases/") + vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), 0.0).successful());
ASSERT_TRUE((ci->createDatabaseCoordinator(vocbase->name(), ASSERT_TRUE((ci->createDatabaseCoordinator(vocbase->name(),
arangodb::velocypack::Slice::emptyObjectSlice(), 0.) arangodb::velocypack::Slice::emptyObjectSlice(), 0.)
.ok())); .ok()));

View File

@ -72,35 +72,40 @@ function agencyTestSuite () {
var agencyServers = instanceInfo.arangods.map(arangod => { var agencyServers = instanceInfo.arangods.map(arangod => {
return arangod.url; return arangod.url;
}); });
var agencyLeader = agencyServers[0]; var agencyLeader = agencyServers[0];
var request = require("@arangodb/request"); var request = require("@arangodb/request");
function findAgencyCompactionIntervals() { function agencyConfig() {
for (let count = 0; count < 60; ++count) { for (let count = 0; count < 60; ++count) {
let res = request({url: agencyLeader + "/_api/agency/config", let res = request({url: agencyLeader + "/_api/agency/config",
method: "GET", followRedirect: true}); method: "GET", followRedirect: true});
if (res.statusCode === 200) { if (res.statusCode === 200) {
try { res.bodyParsed = JSON.parse(res.body);
res.bodyParsed = JSON.parse(res.body); if (res.bodyParsed.leaderId !== "") {
} catch(e) { return res.bodyParsed;
require("console").error("Exception in body parse of '" + agencyLeader + "/_api/agency/config' : ", res.body, JSON.stringify(e), JSON.stringify(res));
throw e;
} }
return { require('console').topic("agency=warn", "No leadership ...");
compactionStepSize: res.bodyParsed.configuration["compaction step size"], } else {
compactionKeepSize: res.bodyParsed.configuration["compaction keep size"] require('console').topic("agency=warn", "Got status " + res.statusCode +
}; " from agency.");
} }
require('console').topic("agency=warn", "Got status " + res.statusCode +
" from agency.");
require("internal").wait(1.0); // give the server another second require("internal").wait(1.0); // give the server another second
} }
require('console').topic("agency=error", require('console').topic("agency=error",
"Giving up, agency did not boot successfully."); "Giving up, agency did not boot successfully.");
assertEqual("apple", "orange"); assertEqual("apple", "orange");
// all is lost because agency did not get up and running in time // all is lost because agency did not get up and running in time
} }
function findAgencyCompactionIntervals() {
var c = agencyConfig();
return {
compactionStepSize: c.configuration["compaction step size"],
compactionKeepSize: c.configuration["compaction keep size"]
};
}
var compactionConfig = findAgencyCompactionIntervals(); var compactionConfig = findAgencyCompactionIntervals();
require("console").topic("agency=info", "Agency compaction configuration: ", compactionConfig); require("console").topic("agency=info", "Agency compaction configuration: ", compactionConfig);
@ -118,29 +123,8 @@ function agencyTestSuite () {
timeout: 240 timeout: 240
}; };
let compactionReply = request(compaction); ret.push({compactions: JSON.parse(request(compaction).body),
let stateReply = request(state); state: JSON.parse(request(state).body), url: url});
let compactionParsed;
let stateParsed;
try {
compactionParsed = JSON.parse(compactionReply.body);
}
catch (e) {
require("console").error("Exception in body parse of '" + url + "/_api/cursor' : ", compactionReply.body, JSON.stringify(e), JSON.stringify(compactionReply));
throw e;
}
try {
stateParsed = JSON.parse(stateReply.body);
}
catch (e) {
require("console").error("Exception in body parse of '" + url + "/_api/agency/state' : ", stateReply.body, JSON.stringify(e), JSON.stringify(stateReply));
throw e;
}
ret.push({
compactions: compactionParsed,
state: stateParsed,
url: url
});
}); });
return ret; return ret;
} }
@ -149,7 +133,6 @@ function agencyTestSuite () {
// We simply try all agency servers in turn until one gives us an HTTP // We simply try all agency servers in turn until one gives us an HTTP
// response: // response:
var res; var res;
let requestUrl;
var inquire = false; var inquire = false;
var clientIds = []; var clientIds = [];
@ -163,16 +146,14 @@ function agencyTestSuite () {
while (true) { while (true) {
if (!inquire) { if (!inquire) {
requestUrl = agencyLeader + "/_api/agency/" + api; res = request({url: agencyLeader + "/_api/agency/" + api,
res = request({url: requestUrl,
method: "POST", followRedirect: false, method: "POST", followRedirect: false,
body: JSON.stringify(list), body: JSON.stringify(list),
headers: {"Content-Type": "application/json"}, headers: {"Content-Type": "application/json"},
timeout: timeout /* essentially for the huge trx package timeout: timeout /* essentially for the huge trx package
running under ASAN in the CI */ }); running under ASAN in the CI */ });
} else { // inquire. Remove successful commits. For later retries } else { // inquire. Remove successful commits. For later retries
requestUrl = agencyLeader + "/_api/agency/inquire"; res = request({url: agencyLeader + "/_api/agency/inquire",
res = request({url: requestUrl,
method: "POST", followRedirect: false, method: "POST", followRedirect: false,
body: JSON.stringify(clientIds), body: JSON.stringify(clientIds),
headers: {"Content-Type": "application/json"}, headers: {"Content-Type": "application/json"},
@ -184,7 +165,7 @@ function agencyTestSuite () {
agencyLeader = res.headers.location; agencyLeader = res.headers.location;
var l = 0; var l = 0;
for (var i = 0; i < 3; ++i) { for (var i = 0; i < 3; ++i) {
l = agencyLeader.indexOf('/', l + 1); l = agencyLeader.indexOf('/', l+1);
} }
agencyLeader = agencyLeader.substring(0,l); agencyLeader = agencyLeader.substring(0,l);
if (clientIds.length > 0 && api === 'write') { if (clientIds.length > 0 && api === 'write') {
@ -205,12 +186,7 @@ function agencyTestSuite () {
} }
// In case of inquiry, we probably have done some of the transactions: // In case of inquiry, we probably have done some of the transactions:
var done = 0; var done = 0;
try { res.bodyParsed = JSON.parse(res.body);
res.bodyParsed = JSON.parse(res.body);
} catch(e) {
require("console").error("Exception in body parse of '" + requestUrl + "' : ", res.body, JSON.stringify(e), api, list, JSON.stringify(res));
throw e;
}
res.bodyParsed.results.forEach(function (index) { res.bodyParsed.results.forEach(function (index) {
if (index > 0) { if (index > 0) {
done++; done++;
@ -226,7 +202,7 @@ function agencyTestSuite () {
try { try {
res.bodyParsed = JSON.parse(res.body); res.bodyParsed = JSON.parse(res.body);
} catch(e) { } catch(e) {
require("console").error("Exception in body parse of '" + requestUrl + "' : ", res.body, JSON.stringify(e), api, list, JSON.stringify(res)); require("console").error("Exception in body parse:", res.body, JSON.stringify(e), api, list, JSON.stringify(res));
} }
return res; return res;
} }
@ -271,10 +247,10 @@ function agencyTestSuite () {
res = accessAgency("read", trxs); res = accessAgency("read", trxs);
assertEqual(200, res.statusCode); assertEqual(200, res.statusCode);
for (i = 0; i < start + count; ++i) { for (i = 0; i < start + count; ++i) {
let key = "key" + i; let key = "key"+i;
let correct = {}; let correct = {};
correct[key] = "value" + i; correct[key] = "value" + i;
assertEqual(correct, res.bodyParsed[i], JSON.stringify(res.bodyParsed)); assertEqual(correct, res.bodyParsed[i]);
} }
} }
@ -287,8 +263,8 @@ function agencyTestSuite () {
var agents = getCompactions(servers), i, old; var agents = getCompactions(servers), i, old;
var ready = true; var ready = true;
for (i = 1; i < agents.length; ++i) { for (i = 1; i < agents.length; ++i) {
if (agents[0].state.log[agents[0].state.log.length - 1].index !== if (agents[0].state.log[agents[0].state.log.length-1].index !==
agents[i].state.log[agents[i].state.log.length - 1].index) { agents[i].state.log[agents[i].state.log.length-1].index) {
ready = false; ready = false;
break; break;
} }
@ -299,9 +275,9 @@ function agencyTestSuite () {
agents.forEach( function (agent) { agents.forEach( function (agent) {
var results = agent.compactions.result; // All compactions var results = agent.compactions.result; // All compactions
var llog = agent.state.log[agent.state.log.length - 1]; // Last log entry var llog = agent.state.log[agent.state.log.length-1]; // Last log entry
llogi = llog.index; // Last log index llogi = llog.index; // Last log index
var lcomp = results[results.length - 1]; // Last compaction entry var lcomp = results[results.length-1]; // Last compaction entry
var lcompi = parseInt(lcomp._key); // Last compaction index var lcompi = parseInt(lcomp._key); // Last compaction index
var stepsize = compactionConfig.compactionStepSize; var stepsize = compactionConfig.compactionStepSize;
@ -780,12 +756,7 @@ function agencyTestSuite () {
let res = request({url: agencyLeader + "/_api/agency/stores", let res = request({url: agencyLeader + "/_api/agency/stores",
method: "GET", followRedirect: true}); method: "GET", followRedirect: true});
if (res.statusCode === 200) { if (res.statusCode === 200) {
try { res.bodyParsed = JSON.parse(res.body);
res.bodyParsed = JSON.parse(res.body);
} catch(e) {
require("console").error("Exception in body parse of " + agencyLeader + "/_api/agency/stores' : ", res.body, JSON.stringify(e), JSON.stringify(res));
throw e;
}
if (res.bodyParsed.read_db[0].a !== undefined) { if (res.bodyParsed.read_db[0].a !== undefined) {
assertTrue(res.bodyParsed.read_db[1]["/a/u"] >= 0); assertTrue(res.bodyParsed.read_db[1]["/a/u"] >= 0);
} else { } else {
@ -807,12 +778,7 @@ function agencyTestSuite () {
// only, if agency is still led by same guy/girl // only, if agency is still led by same guy/girl
if (agencyLeader === tmp) { if (agencyLeader === tmp) {
if (res.statusCode === 200) { if (res.statusCode === 200) {
try { res.bodyParsed = JSON.parse(res.body);
res.bodyParsed = JSON.parse(res.body);
} catch(e) {
require("console").error("Exception in body parse of '" + agencyLeader + "/_api/agency/stores' : ", res.body, JSON.stringify(e), JSON.stringify(res));
throw e;
}
console.warn(res.bodyParsed.read_db[0]); console.warn(res.bodyParsed.read_db[0]);
if (res.bodyParsed.read_db[0].a !== undefined) { if (res.bodyParsed.read_db[0].a !== undefined) {
assertTrue(res.bodyParsed.read_db[1]["/a/u"] === undefined); assertTrue(res.bodyParsed.read_db[1]["/a/u"] === undefined);
@ -1100,6 +1066,129 @@ function agencyTestSuite () {
assertEqual(readAndCheck([["/"]]), [{}]); assertEqual(readAndCheck([["/"]]), [{}]);
}, },
////////////////////////////////////////////////////////////////////////////////
/// @brief Test observe / unobserve
////////////////////////////////////////////////////////////////////////////////
testObserve : function () {
var res, before, after, clean;
var trx = [{"/a":"a"}, {"a":{"oldEmpty":true}}];
// In the beginning
res = request({url:agencyLeader+"/_api/agency/stores", method:"GET"});
assertEqual(200, res.statusCode);
clean = JSON.parse(res.body);
// Don't create empty object for observation
writeAndCheck([[{"/a":{"op":"observe", "url":"https://google.com"}}]]);
assertEqual(readAndCheck([["/"]]), [{}]);
res = accessAgency("write",[trx]);
assertEqual(res.statusCode, 200);
res = accessAgency("write",[trx]);
assertEqual(res.statusCode, 412);
writeAndCheck([[{"/":{"op":"delete"}}]]);
var c = agencyConfig().term;
// No duplicate entries in
res = request({url:agencyLeader+"/_api/agency/stores", method:"GET"});
assertEqual(200, res.statusCode);
before = JSON.parse(res.body);
writeAndCheck([[{"/a":{"op":"observe", "url":"https://google.com"}}]]);
res = request({url:agencyLeader+"/_api/agency/stores", method:"GET"});
assertEqual(200, res.statusCode);
after = JSON.parse(res.body);
if (!_.isEqual(before, after)) {
if (agencyConfig().term === c) {
assertEqual(before, after); //peng
} else {
require("console").warn("skipping remaining callback tests this time around");
return; //
}
}
// Normalization
res = request({url:agencyLeader+"/_api/agency/stores", method:"GET"});
assertEqual(200, res.statusCode);
before = JSON.parse(res.body);
writeAndCheck([[{"//////a////":{"op":"observe", "url":"https://google.com"}}]]);
writeAndCheck([[{"a":{"op":"observe", "url":"https://google.com"}}]]);
writeAndCheck([[{"a/":{"op":"observe", "url":"https://google.com"}}]]);
writeAndCheck([[{"/a/":{"op":"observe", "url":"https://google.com"}}]]);
res = request({url:agencyLeader+"/_api/agency/stores", method:"GET"});
assertEqual(200, res.statusCode);
after = JSON.parse(res.body);
if (!_.isEqual(before, after)) {
if (agencyConfig().term === c) {
assertEqual(before, after); //peng
} else {
require("console").warn("skipping remaining callback tests this time around");
return; //
}
}
// Unobserve
res = request({url:agencyLeader+"/_api/agency/stores", method:"GET"});
assertEqual(200, res.statusCode);
before = JSON.parse(res.body);
writeAndCheck([[{"//////a":{"op":"unobserve", "url":"https://google.com"}}]]);
res = request({url:agencyLeader+"/_api/agency/stores", method:"GET"});
assertEqual(200, res.statusCode);
after = JSON.parse(res.body);
assertEqual(clean, after);
if (!_.isEqual(clean, after)) {
if (agencyConfig().term === c) {
assertEqual(clean, after); //peng
} else {
require("console").warn("skipping remaining callback tests this time around");
return; //
}
}
writeAndCheck([[{"/":{"op":"delete"}}]]);
assertEqual(readAndCheck([["/"]]), [{}]);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief Test delete / replace / erase should not create new stuff in agency
////////////////////////////////////////////////////////////////////////////////
testNotCreate : function () {
var trx = [{"/a":"a"}, {"a":{"oldEmpty":true}}], res;
// Don't create empty object for observation
writeAndCheck([[{"a":{"op":"delete"}}]]);
assertEqual(readAndCheck([["/"]]), [{}]);
res = accessAgency("write",[trx]);
assertEqual(res.statusCode, 200);
res = accessAgency("write",[trx]);
assertEqual(res.statusCode, 412);
writeAndCheck([[{"/":{"op":"delete"}}]]);
assertEqual(readAndCheck([["/"]]), [{}]);
// Don't create empty object for observation
writeAndCheck([[{"a":{"op":"replace", "val":1, "new":2}}]]);
assertEqual(readAndCheck([["/"]]), [{}]);
res = accessAgency("write",[trx]);
assertEqual(res.statusCode, 200);
res = accessAgency("write",[trx]);
assertEqual(res.statusCode, 412);
writeAndCheck([[{"/":{"op":"delete"}}]]);
assertEqual(readAndCheck([["/"]]), [{}]);
// Don't create empty object for observation
writeAndCheck([[{"a":{"op":"erase", "val":1}}]]);
assertEqual(readAndCheck([["/"]]), [{}]);
res = accessAgency("write",[trx]);
assertEqual(res.statusCode, 200);
res = accessAgency("write",[trx]);
assertEqual(res.statusCode, 412);
writeAndCheck([[{"/":{"op":"delete"}}]]);
assertEqual(readAndCheck([["/"]]), [{}]);
},
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief Test that order should not matter /// @brief Test that order should not matter
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -1341,4 +1430,3 @@ function agencyTestSuite () {
jsunity.run(agencyTestSuite); jsunity.run(agencyTestSuite);
return jsunity.done(); return jsunity.done();