mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'foxx-pathes' of github.com:triAGENS/ArangoDB into foxx-pathes
This commit is contained in:
commit
bd2a698ab6
|
@ -7,6 +7,10 @@ v2.5.0 (XXXX-XX-XX)
|
|||
v2.4.1 (XXXX-XX-XX)
|
||||
-------------------
|
||||
|
||||
* better diagnostics for arangoimp
|
||||
|
||||
* fixed invalid result of HTTP REST API method `/_admin/foxx/rescan`
|
||||
|
||||
* fixed possible segmentation fault when passing a Buffer object into a V8 function
|
||||
as a parameter
|
||||
|
||||
|
|
|
@ -86,16 +86,16 @@ collection in the default database (*_system*). To specify a different database,
|
|||
use the *--server.database* option when invoking _arangoimp_.
|
||||
|
||||
An _arangoimp_ import run will print out the final results on the command line.
|
||||
By default, it shows the number of documents created, the number of errors that
|
||||
By default, it shows the number of documents created, the number of warnings or errors that
|
||||
occurred on the server side, and the total number of input file lines/documents
|
||||
that it processed. Additionally, _arangoimp_ will print out details about errors
|
||||
that it processed. Additionally, _arangoimp_ will print out details about warnings and errors
|
||||
that happened on the server-side (if any).
|
||||
|
||||
*Examples*
|
||||
|
||||
```js
|
||||
created: 2
|
||||
errors: 0
|
||||
warnings/errors: 0
|
||||
total: 2
|
||||
```
|
||||
|
||||
|
|
|
@ -447,6 +447,7 @@ SHELL_COMMON = \
|
|||
@top_srcdir@/js/common/tests/shell-index.js \
|
||||
@top_srcdir@/js/common/tests/shell-index-geo.js \
|
||||
@top_srcdir@/js/common/tests/shell-cap-constraint.js \
|
||||
@top_srcdir@/js/common/tests/shell-cap-constraint-timecritical.js \
|
||||
@top_srcdir@/js/common/tests/shell-unique-constraint.js \
|
||||
@top_srcdir@/js/common/tests/shell-hash-index.js \
|
||||
@top_srcdir@/js/common/tests/shell-fulltext.js \
|
||||
|
|
|
@ -3,3 +3,4 @@
|
|||
{"id": 3, "_from": "UnitTestsImportVertex/v9", "_to": "UnitTestsImportVertex/v4", "what": "v9->v4", "extra": "foo"}
|
||||
|
||||
{"id": 4, "_from": "UnitTestsImportVertex/v12", "_to": "UnitTestsImportVertex/what"}
|
||||
{"id": 5}
|
||||
|
|
|
@ -153,8 +153,25 @@ void RestImportHandler::registerError (RestImportResult& result,
|
|||
++result._numErrors;
|
||||
|
||||
result._errors.push_back(errorMsg);
|
||||
}
|
||||
|
||||
LOG_WARNING("%s", errorMsg.c_str());
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief construct an error message
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string RestImportHandler::buildParseError (size_t i,
|
||||
char const* lineStart) {
|
||||
if (lineStart != nullptr) {
|
||||
string part(lineStart);
|
||||
if (part.size() > 255) {
|
||||
// UTF-8 chars in string will be escaped so we can truncate it at any point
|
||||
part = part.substr(0, 255) + "...";
|
||||
}
|
||||
|
||||
return positionise(i) + "invalid JSON type (expecting object, probably parse error), offending context: " + part;
|
||||
}
|
||||
|
||||
return positionise(i) + "invalid JSON type (expecting object, probably parse error)";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -162,13 +179,25 @@ void RestImportHandler::registerError (RestImportResult& result,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int RestImportHandler::handleSingleDocument (RestImportTransaction& trx,
|
||||
char const* lineStart,
|
||||
TRI_json_t const* json,
|
||||
string& errorMsg,
|
||||
bool isEdgeCollection,
|
||||
bool waitForSync,
|
||||
size_t i) {
|
||||
if (! TRI_IsObjectJson(json)) {
|
||||
errorMsg = positionise(i) + "invalid JSON type (expecting array)";
|
||||
if (json != nullptr) {
|
||||
string part = JsonHelper::toString(json);
|
||||
if (part.size() > 255) {
|
||||
// UTF-8 chars in string will be escaped so we can truncate it at any point
|
||||
part = part.substr(0, 255) + "...";
|
||||
}
|
||||
|
||||
errorMsg = positionise(i) + "invalid JSON type (expecting object), offending document: " + part;
|
||||
}
|
||||
else {
|
||||
errorMsg = buildParseError(i, lineStart);
|
||||
}
|
||||
|
||||
return TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID;
|
||||
}
|
||||
|
@ -182,7 +211,13 @@ int RestImportHandler::handleSingleDocument (RestImportTransaction& trx,
|
|||
char const* to = extractJsonStringValue(json, TRI_VOC_ATTRIBUTE_TO);
|
||||
|
||||
if (from == nullptr || to == nullptr) {
|
||||
errorMsg = positionise(i) + "missing '_from' or '_to' attribute";
|
||||
string part = JsonHelper::toString(json);
|
||||
if (part.size() > 255) {
|
||||
// UTF-8 chars in string will be escaped so we can truncate it at any point
|
||||
part = part.substr(0, 255) + "...";
|
||||
}
|
||||
|
||||
errorMsg = positionise(i) + "missing '_from' or '_to' attribute, offending document: " + part;
|
||||
|
||||
return TRI_ERROR_ARANGO_INVALID_EDGE_ATTRIBUTE;
|
||||
}
|
||||
|
@ -600,7 +635,7 @@ bool RestImportHandler::createFromJson (string const& type) {
|
|||
|
||||
while (ptr < end) {
|
||||
char const c = *ptr;
|
||||
if (c == '\r' || c == '\n' || c == '\t' || c == ' ') {
|
||||
if (c == '\r' || c == '\n' || c == '\t' || c == '\b' || c == '\f' || c == ' ') {
|
||||
ptr++;
|
||||
continue;
|
||||
}
|
||||
|
@ -657,7 +692,7 @@ bool RestImportHandler::createFromJson (string const& type) {
|
|||
|
||||
// trim whitespace at start of line
|
||||
while (ptr < end &&
|
||||
(*ptr == ' ' || *ptr == '\t' || *ptr == '\r')) {
|
||||
(*ptr == ' ' || *ptr == '\t' || *ptr == '\r' || *ptr == '\b' || *ptr == '\f')) {
|
||||
++ptr;
|
||||
}
|
||||
|
||||
|
@ -667,6 +702,7 @@ bool RestImportHandler::createFromJson (string const& type) {
|
|||
|
||||
// now find end of line
|
||||
char const* pos = strchr(ptr, '\n');
|
||||
char const* oldPtr = nullptr;
|
||||
|
||||
TRI_json_t* json = nullptr;
|
||||
|
||||
|
@ -680,18 +716,20 @@ bool RestImportHandler::createFromJson (string const& type) {
|
|||
// non-empty line
|
||||
*(const_cast<char*>(pos)) = '\0';
|
||||
TRI_ASSERT(ptr != nullptr);
|
||||
json = parseJsonLine(ptr);
|
||||
oldPtr = ptr;
|
||||
json = parseJsonLine(ptr, pos);
|
||||
ptr = pos + 1;
|
||||
}
|
||||
else {
|
||||
// last-line, non-empty
|
||||
TRI_ASSERT(pos == nullptr);
|
||||
TRI_ASSERT(ptr != nullptr);
|
||||
oldPtr = ptr;
|
||||
json = parseJsonLine(ptr);
|
||||
ptr = end;
|
||||
}
|
||||
|
||||
res = handleSingleDocument(trx, json, errorMsg, isEdgeCollection, waitForSync, i);
|
||||
res = handleSingleDocument(trx, oldPtr, json, errorMsg, isEdgeCollection, waitForSync, i);
|
||||
|
||||
if (json != nullptr) {
|
||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
|
||||
|
@ -734,7 +772,7 @@ bool RestImportHandler::createFromJson (string const& type) {
|
|||
for (size_t i = 0; i < n; ++i) {
|
||||
TRI_json_t const* json = static_cast<TRI_json_t const*>(TRI_AtVector(&documents->_value._objects, i));
|
||||
|
||||
res = handleSingleDocument(trx, json, errorMsg, isEdgeCollection, waitForSync, i + 1);
|
||||
res = handleSingleDocument(trx, nullptr, json, errorMsg, isEdgeCollection, waitForSync, i + 1);
|
||||
|
||||
if (res == TRI_ERROR_NO_ERROR) {
|
||||
++result._numCreated;
|
||||
|
@ -1071,12 +1109,12 @@ bool RestImportHandler::createFromKeyValueList () {
|
|||
|
||||
// trim line
|
||||
while (lineStart < bodyEnd &&
|
||||
(*lineStart == ' ' || *lineStart == '\t' || *lineStart == '\r' || *lineStart == '\n')) {
|
||||
(*lineStart == ' ' || *lineStart == '\t' || *lineStart == '\r' || *lineStart == '\n' || *lineStart == '\b' || *lineStart == '\f')) {
|
||||
++lineStart;
|
||||
}
|
||||
|
||||
while (lineEnd > lineStart &&
|
||||
(*(lineEnd - 1) == ' ' || *(lineEnd - 1) == '\t' || *(lineEnd - 1) == '\r' || *(lineEnd - 1) == '\n')) {
|
||||
(*(lineEnd - 1) == ' ' || *(lineEnd - 1) == '\t' || *(lineEnd - 1) == '\r' || *(lineEnd - 1) == '\n' || *(lineEnd - 1) == '\b' || *(lineEnd - 1) == '\f')) {
|
||||
--lineEnd;
|
||||
}
|
||||
|
||||
|
@ -1084,7 +1122,6 @@ bool RestImportHandler::createFromKeyValueList () {
|
|||
TRI_json_t* keys = parseJsonLine(lineStart, lineEnd);
|
||||
|
||||
if (! checkKeys(keys)) {
|
||||
LOG_WARNING("no JSON string array found in first line");
|
||||
generateError(HttpResponse::BAD,
|
||||
TRI_ERROR_HTTP_BAD_PARAMETER,
|
||||
"no JSON string array found in first line");
|
||||
|
@ -1146,12 +1183,12 @@ bool RestImportHandler::createFromKeyValueList () {
|
|||
|
||||
// trim line
|
||||
while (lineStart < bodyEnd &&
|
||||
(*lineStart == ' ' || *lineStart == '\t' || *lineStart == '\r' || *lineStart == '\n')) {
|
||||
(*lineStart == ' ' || *lineStart == '\t' || *lineStart == '\r' || *lineStart == '\n' || *lineStart == '\b' || *lineStart == '\f')) {
|
||||
++lineStart;
|
||||
}
|
||||
|
||||
while (lineEnd > lineStart &&
|
||||
(*(lineEnd - 1) == ' ' || *(lineEnd - 1) == '\t' || *(lineEnd - 1) == '\r' || *(lineEnd - 1) == '\n')) {
|
||||
(*(lineEnd - 1) == ' ' || *(lineEnd - 1) == '\t' || *(lineEnd - 1) == '\r' || *(lineEnd - 1) == '\n' || *(lineEnd - 1) == '\b' || *(lineEnd - 1) == '\f')) {
|
||||
--lineEnd;
|
||||
}
|
||||
|
||||
|
@ -1170,7 +1207,7 @@ bool RestImportHandler::createFromKeyValueList () {
|
|||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, values);
|
||||
|
||||
if (json != nullptr) {
|
||||
res = handleSingleDocument(trx, json, errorMsg, isEdgeCollection, waitForSync, i);
|
||||
res = handleSingleDocument(trx, lineStart, json, errorMsg, isEdgeCollection, waitForSync, i);
|
||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
|
||||
}
|
||||
else {
|
||||
|
@ -1194,7 +1231,7 @@ bool RestImportHandler::createFromKeyValueList () {
|
|||
}
|
||||
}
|
||||
else {
|
||||
string errorMsg = positionise(i) + "no valid JSON data";
|
||||
string errorMsg = buildParseError(i, lineStart);
|
||||
registerError(result, errorMsg);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -128,11 +128,19 @@ namespace triagens {
|
|||
void registerError (RestImportResult&,
|
||||
std::string const&);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief construct an error message
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string buildParseError (size_t,
|
||||
char const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief process a single JSON document
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int handleSingleDocument (RestImportTransaction&,
|
||||
char const*,
|
||||
TRI_json_t const*,
|
||||
std::string&,
|
||||
bool,
|
||||
|
|
|
@ -708,10 +708,8 @@ namespace triagens {
|
|||
}
|
||||
}
|
||||
|
||||
TRI_json_t const* importResult;
|
||||
|
||||
// look up the "created" flag. This returns a pointer, not a copy
|
||||
importResult = TRI_LookupObjectJson(json, "created");
|
||||
TRI_json_t const* importResult = TRI_LookupObjectJson(json, "created");
|
||||
|
||||
if (TRI_IsNumberJson(importResult)) {
|
||||
_numberOk += (size_t) importResult->_value._number;
|
||||
|
|
|
@ -411,7 +411,7 @@ int main (int argc, char* argv[]) {
|
|||
// give information about import
|
||||
if (ok) {
|
||||
cout << "created: " << ih.getImportedLines() << endl;
|
||||
cout << "errors: " << ih.getErrorLines() << endl;
|
||||
cout << "warnings/errors: " << ih.getErrorLines() << endl;
|
||||
cout << "total: " << ih.getReadLines() << endl;
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -44,124 +44,7 @@ var easyPostCallback = actions.easyPostCallback;
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief fetches a FOXX application
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_admin/foxx/fetch",
|
||||
prefix : false,
|
||||
|
||||
callback : function (req, res) {
|
||||
'use strict';
|
||||
|
||||
var safe = /^[0-9a-zA-Z_\-\.]+$/;
|
||||
|
||||
if (req.suffix.length !== 0) {
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
return;
|
||||
}
|
||||
|
||||
var json = actions.getJsonBody(req, res, actions.HTTP_BAD);
|
||||
|
||||
if (json === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
var serverFile = json.filename;
|
||||
var realFile = fs.join(fs.getTempPath(), serverFile);
|
||||
|
||||
if (! fs.isFile(realFile)) {
|
||||
actions.resultNotFound(req, res, arangodb.errors.ERROR_FILE_NOT_FOUND.code);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
var name = json.name;
|
||||
var version = json.version;
|
||||
|
||||
if (! safe.test(name)) {
|
||||
fs.remove(realFile);
|
||||
throw "rejecting unsafe name '" + name + "'";
|
||||
}
|
||||
|
||||
if (! safe.test(version)) {
|
||||
fs.remove(realFile);
|
||||
throw "rejecting unsafe version '" + version + "'";
|
||||
}
|
||||
|
||||
var appPath = module.appPath();
|
||||
|
||||
if (typeof appPath === "undefined") {
|
||||
fs.remove(realFile);
|
||||
throw "javascript.app-path not set, rejecting app loading";
|
||||
}
|
||||
|
||||
var path = fs.join(appPath, name + "-" + version);
|
||||
|
||||
if (!fs.exists(path)) {
|
||||
fs.makeDirectoryRecursive(path);
|
||||
fs.unzipFile(realFile, path, false, true);
|
||||
|
||||
foxxManager.scanAppDirectory();
|
||||
}
|
||||
fs.remove(realFile);
|
||||
|
||||
var found = arangodb.db._collection("_aal").firstExample({
|
||||
type: "app",
|
||||
path: name + "-" + version
|
||||
});
|
||||
|
||||
if (found !== null) {
|
||||
found = found.app;
|
||||
}
|
||||
|
||||
actions.resultOk(req, res, actions.HTTP_OK, { path: path, app: found });
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief mounts a FOXX application
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_admin/foxx/mount",
|
||||
prefix : false,
|
||||
|
||||
callback: easyPostCallback({
|
||||
body: true,
|
||||
callback: function (body) {
|
||||
var appId = body.appId;
|
||||
var mount = body.mount;
|
||||
var options = body.options || {};
|
||||
|
||||
return foxxManager.mount(appId, mount, options);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief rescans the FOXX application directory
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_admin/foxx/rescan",
|
||||
prefix : false,
|
||||
|
||||
callback: easyPostCallback({
|
||||
body: true,
|
||||
callback: function () {
|
||||
foxxManager.scanAppDirectory();
|
||||
return true;
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief sets up a FOXX application
|
||||
/// @brief sets up a Foxx application
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
|
@ -179,7 +62,7 @@ actions.defineHttp({
|
|||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief tears down a FOXX application
|
||||
/// @brief tears down a Foxx application
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
|
@ -197,11 +80,31 @@ actions.defineHttp({
|
|||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief unmounts a FOXX application
|
||||
/// @brief installs a Foxx application
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_admin/foxx/unmount",
|
||||
url : "_admin/foxx/install",
|
||||
prefix : false,
|
||||
|
||||
callback: easyPostCallback({
|
||||
body: true,
|
||||
callback: function (body) {
|
||||
var appInfo = body.appInfo;
|
||||
var mount = body.mount;
|
||||
var options = body.options;
|
||||
|
||||
return foxxManager.install(appInfo, mount, options);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief uninstalls a Foxx application
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_admin/foxx/uninstall",
|
||||
prefix : false,
|
||||
|
||||
callback: easyPostCallback({
|
||||
|
@ -209,85 +112,51 @@ actions.defineHttp({
|
|||
callback: function (body) {
|
||||
var mount = body.mount;
|
||||
|
||||
return foxxManager.unmount(mount);
|
||||
return foxxManager.uninstall(mount);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief sets up a FOXX dev application
|
||||
/// @brief replaces a Foxx application
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_admin/foxx/dev-setup",
|
||||
url : "_admin/foxx/replace",
|
||||
prefix : false,
|
||||
|
||||
callback: easyPostCallback({
|
||||
body: true,
|
||||
callback: function (body) {
|
||||
var name = body.name;
|
||||
var appInfo = body.appInfo;
|
||||
var mount = body.mount;
|
||||
var options = body.options;
|
||||
|
||||
return foxxManager.devSetup(name);
|
||||
return foxxManager.replace(appInfo, mount, options);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief tears down a FOXX dev application
|
||||
/// @brief upgrades a Foxx application
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_admin/foxx/dev-teardown",
|
||||
url : "_admin/foxx/upgrade",
|
||||
prefix : false,
|
||||
|
||||
callback: easyPostCallback({
|
||||
body: true,
|
||||
callback: function (body) {
|
||||
var name = body.name;
|
||||
var appInfo = body.appInfo;
|
||||
var mount = body.mount;
|
||||
var options = body.options;
|
||||
|
||||
return foxxManager.devTeardown(name);
|
||||
return foxxManager.upgrade(appInfo, mount, options);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief purges a FOXX application
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_admin/foxx/purge",
|
||||
prefix : false,
|
||||
|
||||
callback: easyPostCallback({
|
||||
body: true,
|
||||
callback: function (body) {
|
||||
var name = body.name;
|
||||
|
||||
return foxxManager.purge(name);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns directory information
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_admin/foxx/config",
|
||||
prefix : false,
|
||||
|
||||
callback : function (req, res) {
|
||||
var result = {
|
||||
appPath: module.appPath(),
|
||||
devAppPath: internal.developmentMode ? module.devAppPath() : null,
|
||||
logFilePath: internal.logfilePath,
|
||||
startupPath: module.startupPath()
|
||||
};
|
||||
|
||||
actions.resultOk(req, res, actions.HTTP_OK, { result: result });
|
||||
}
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
ArangoError = require('org/arangodb').ArangoError,
|
||||
<%= repository %> = require('<%= repositoryPath %>').Repository,
|
||||
<%= model %> = require('<%= modelPath %>').Model,
|
||||
joi = require('joi'),
|
||||
_ = require('underscore'),
|
||||
controller,
|
||||
<%= repositoryInstance %>;
|
||||
|
@ -34,6 +35,18 @@
|
|||
res.json(<%= repositoryInstance %>.save(<%= modelInstance %>).forClient());
|
||||
}).bodyParam('<%= modelInstance %>', 'The <%= model %> you want to create', <%= model %>);
|
||||
|
||||
/** Reads a <%= model %>
|
||||
*
|
||||
* Reads a <%= model %>-Item.
|
||||
*/
|
||||
controller.get('/<%= basePath %>/:id', function (req, res) {
|
||||
var id = req.params('id');
|
||||
res.json(<%= repositoryInstance %>.byId(id).forClient());
|
||||
}).pathParam('id', {
|
||||
description: 'The id of the <%= model %>-Item',
|
||||
type: 'string'
|
||||
});
|
||||
|
||||
/** Updates a <%= model %>
|
||||
*
|
||||
* Changes a <%= model %>-Item. The information has to be in the
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1367,16 +1367,9 @@ function require (path) {
|
|||
/// @brief createApp
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Module.prototype.createApp = function (description, options) {
|
||||
Module.prototype.createApp = function (config) {
|
||||
'use strict';
|
||||
|
||||
return new ArangoApp(
|
||||
description.id,
|
||||
description.manifest,
|
||||
description.root,
|
||||
description.path,
|
||||
options
|
||||
);
|
||||
return new ArangoApp(config);
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -1391,16 +1384,18 @@ function require (path) {
|
|||
/// @brief ArangoApp constructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoApp = function (id, manifest, root, path, options) {
|
||||
ArangoApp = function (config) {
|
||||
'use strict';
|
||||
|
||||
this._id = id;
|
||||
this._manifest = manifest;
|
||||
this._name = manifest.name;
|
||||
this._version = manifest.version;
|
||||
this._root = root;
|
||||
this._path = path;
|
||||
this._options = options;
|
||||
this._id = config.id; // ???
|
||||
this._manifest = config.manifest;
|
||||
this._name = config.manifest.name;
|
||||
this._version = config.manifest.version;
|
||||
this._root = config.root;
|
||||
this._path = config.path;
|
||||
this._options = config.options;
|
||||
this._mount = config.mount;
|
||||
this._isSystem = config.isSystem || false;
|
||||
this._isDevelopment = config.isDevelopment || false;
|
||||
this._exports = {};
|
||||
};
|
||||
|
||||
|
@ -1428,6 +1423,35 @@ function require (path) {
|
|||
// --SECTION-- public methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief creates a Json representation of itself to be persisted
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoApp.prototype.toJSON = function () {
|
||||
var json = {
|
||||
id: this._id,
|
||||
manifest: this._manifest,
|
||||
name: this._name,
|
||||
version: this._version,
|
||||
root: this._root,
|
||||
path: this._path,
|
||||
options: this._options,
|
||||
mount: this._mount,
|
||||
isSystem: this._isSystem,
|
||||
isDevelopment: this._isDevelopment
|
||||
};
|
||||
if (this._manifest.hasOwnProperty("author")) {
|
||||
json.author = this._manifest.author;
|
||||
}
|
||||
if (this._manifest.hasOwnProperty("description")) {
|
||||
json.description = this._manifest.description;
|
||||
}
|
||||
if (this._manifest.hasOwnProperty("thumbnail")) {
|
||||
json.thumbnail = this._manifest.thumbnail;
|
||||
}
|
||||
|
||||
return json;
|
||||
};
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief createAppModule
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -39,6 +39,31 @@ var throwDownloadError = arangodb.throwDownloadError;
|
|||
var errors = arangodb.errors;
|
||||
var ArangoError = arangodb.ArangoError;
|
||||
|
||||
// TODO Only temporary
|
||||
var tmp_getStorage = function() {
|
||||
var c = db._tmp_aal;
|
||||
if (c === undefined) {
|
||||
c = db._create("_tmp_aal", {isSystem: true});
|
||||
c.ensureUniqueConstraint("mount");
|
||||
}
|
||||
return c;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief comparator for mount points
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var compareMounts = function(l, r) {
|
||||
var left = l.mount.toLowerCase();
|
||||
var right = r.mount.toLowerCase();
|
||||
|
||||
if (left < right) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief builds a github repository URL
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -248,31 +273,34 @@ function getStorage () {
|
|||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns all installed FOXX applications
|
||||
/// @brief returns all running Foxx applications
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function listJson (showPrefix) {
|
||||
function listJson (showPrefix, onlyDevelopment) {
|
||||
'use strict';
|
||||
|
||||
var aal = getStorage();
|
||||
var cursor = aal.byExample({ type: "mount" });
|
||||
var mounts = tmp_getStorage();
|
||||
var cursor;
|
||||
if (onlyDevelopment) {
|
||||
cursor = mounts.byExample({isDevelopment: true});
|
||||
} else {
|
||||
cursor = mounts.all();
|
||||
}
|
||||
var result = [];
|
||||
var doc, res;
|
||||
|
||||
while (cursor.hasNext()) {
|
||||
var doc = cursor.next();
|
||||
doc = cursor.next();
|
||||
|
||||
var version = doc.app.replace(/^.+:(\d+(\.\d+)*)$/g, "$1");
|
||||
|
||||
var res = {
|
||||
res = {
|
||||
mountId: doc._key,
|
||||
mount: doc.mount,
|
||||
appId: doc.app,
|
||||
name: doc.name,
|
||||
description: doc.description,
|
||||
author: doc.author,
|
||||
description: doc.manifest.description,
|
||||
author: doc.manifest.author,
|
||||
system: doc.isSystem ? "yes" : "no",
|
||||
active: doc.active ? "yes" : "no",
|
||||
version: version
|
||||
development: doc.isDevelopment ? "yes" : "no",
|
||||
version: doc.version
|
||||
};
|
||||
|
||||
if (showPrefix) {
|
||||
|
@ -285,6 +313,52 @@ function listJson (showPrefix) {
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief prints all running Foxx applications
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function list(onlyDevelopment) {
|
||||
var apps = listJson(undefined, onlyDevelopment);
|
||||
|
||||
arangodb.printTable(
|
||||
apps.sort(compareMounts),
|
||||
[ "mount", "name", "author", "description", "version", "development" ],
|
||||
{
|
||||
prettyStrings: true,
|
||||
totalString: "%s application(s) found",
|
||||
emptyString: "no applications found",
|
||||
rename: {
|
||||
"mount": "Mount",
|
||||
"name" : "Name",
|
||||
"author" : "Author",
|
||||
"description" : "Description",
|
||||
"version" : "Version",
|
||||
"development" : "Development"
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns all running Foxx applications in development mode
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function listDevelopmentJson (showPrefix) {
|
||||
'use strict';
|
||||
return listJson(showPrefix, true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief prints all running Foxx applications
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function listDevelopment() {
|
||||
'use strict';
|
||||
return list(true);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief validate an app name and fail if it is invalid
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -302,19 +376,28 @@ function validateAppName (name) {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
function mountedApp (mount) {
|
||||
"use strict";
|
||||
return tmp_getStorage().firstExample({mount: mount});
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Exports
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
exports.mountedApp = mountedApp;
|
||||
exports.list = list;
|
||||
exports.listJson = listJson;
|
||||
exports.listDevelopment = listDevelopment;
|
||||
exports.listDevelopmentJson = listDevelopmentJson;
|
||||
exports.buildGithubUrl = buildGithubUrl;
|
||||
exports.repackZipFile = repackZipFile;
|
||||
exports.processDirectory = processDirectory;
|
||||
exports.processGithubRepository = processGithubRepository;
|
||||
exports.validateAppName = validateAppName;
|
||||
|
||||
exports.tmp_getStorage = tmp_getStorage;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -70,7 +70,7 @@ exports.Helper = {
|
|||
else if (iterations === 400) {
|
||||
require("console").log("waited very long for unload of collection " + collection.name());
|
||||
}
|
||||
else if (iterations === 800) {
|
||||
else if (iterations === 1600) {
|
||||
throw "waited too long for unload of collection " + collection.name();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,192 @@
|
|||
/*global require, db, assertEqual, assertTrue, ArangoCollection */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test the cap constraint
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler, Lucas Dohmen
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var jsunity = require("jsunity");
|
||||
var internal = require("internal");
|
||||
var testHelper = require("org/arangodb/test-helper").Helper;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- basic methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test suite: Creation
|
||||
/// these tests seem to fail when run in cluster or with valgrind from arangosh
|
||||
/// (while they succeed when run on the frontend)
|
||||
/// test-helper.js:Helper.waitUnload expects timeley behaviour
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function CapConstraintTimecriticalSuite() {
|
||||
var ERRORS = internal.errors;
|
||||
var cn = "UnitTestsCollectionCap";
|
||||
var collection = null;
|
||||
|
||||
var nsort = function (l, r) {
|
||||
if (l !== r) {
|
||||
return (l < r) ? -1 : 1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
var assertBadParameter = function (err) {
|
||||
assertTrue(err.errorNum === ERRORS.ERROR_BAD_PARAMETER.code ||
|
||||
err.errorNum === ERRORS.ERROR_HTTP_BAD_PARAMETER.code);
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief set up
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
setUp : function () {
|
||||
internal.db._drop(cn);
|
||||
collection = internal.db._create(cn);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief tear down
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
tearDown : function () {
|
||||
if (collection !== null) {
|
||||
internal.wait(0);
|
||||
collection.unload();
|
||||
collection.drop();
|
||||
collection = null;
|
||||
}
|
||||
internal.wait(0.0);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test: reload
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testReload : function () {
|
||||
var idx = collection.ensureCapConstraint(5);
|
||||
var fun = function(d) { return d.n; };
|
||||
|
||||
assertEqual("cap", idx.type);
|
||||
assertEqual(true, idx.isNewlyCreated);
|
||||
assertEqual(5, idx.size);
|
||||
assertEqual(0, idx.byteSize);
|
||||
|
||||
assertEqual(0, collection.count());
|
||||
|
||||
for (var i = 0; i < 10; ++i) {
|
||||
collection.save({ n : i });
|
||||
}
|
||||
|
||||
assertEqual(5, collection.count());
|
||||
assertEqual([5, 6, 7, 8, 9], collection.toArray().map(fun).sort(nsort));
|
||||
|
||||
testHelper.waitUnload(collection, true);
|
||||
|
||||
assertEqual(5, collection.count());
|
||||
assertEqual([5, 6, 7, 8, 9], collection.toArray().map(fun).sort(nsort));
|
||||
|
||||
collection.save({ n : 10 });
|
||||
assertEqual(5, collection.count());
|
||||
assertEqual([6, 7, 8, 9, 10], collection.toArray().map(fun).sort(nsort));
|
||||
|
||||
collection.save({ n : 11 });
|
||||
assertEqual(5, collection.count());
|
||||
assertEqual([7, 8, 9, 10, 11], collection.toArray().map(fun).sort(nsort));
|
||||
|
||||
testHelper.waitUnload(collection, true);
|
||||
|
||||
assertEqual(5, collection.count());
|
||||
assertEqual([7, 8, 9, 10, 11], collection.toArray().map(fun).sort(nsort));
|
||||
|
||||
for (var i = 15; i < 20; ++i) {
|
||||
collection.save({ n : i });
|
||||
}
|
||||
|
||||
assertEqual(5, collection.count());
|
||||
assertEqual([15, 16, 17, 18, 19], collection.toArray().map(fun).sort(nsort));
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test: reload
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testReloadMulti : function () {
|
||||
var idx = collection.ensureCapConstraint(5);
|
||||
var fun = function(d) { return d.n; };
|
||||
|
||||
assertEqual("cap", idx.type);
|
||||
assertEqual(true, idx.isNewlyCreated);
|
||||
assertEqual(5, idx.size);
|
||||
assertEqual(0, idx.byteSize);
|
||||
|
||||
assertEqual(0, collection.count());
|
||||
|
||||
testHelper.waitUnload(collection, true);
|
||||
|
||||
assertEqual(0, collection.count());
|
||||
|
||||
for (var i = 0; i < 10; ++i) {
|
||||
collection.save({ n : i });
|
||||
}
|
||||
|
||||
testHelper.waitUnload(collection, true);
|
||||
|
||||
assertEqual(5, collection.count());
|
||||
assertEqual([5, 6, 7, 8, 9], collection.toArray().map(fun).sort(nsort));
|
||||
|
||||
collection.save({ n : 10 });
|
||||
|
||||
testHelper.waitUnload(collection, true);
|
||||
|
||||
assertEqual(5, collection.count());
|
||||
assertEqual([6, 7, 8, 9, 10], collection.toArray().map(fun).sort(nsort));
|
||||
|
||||
collection.save({ n: 0 });
|
||||
assertEqual([0, 7, 8, 9, 10], collection.toArray().map(fun).sort(nsort));
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- main
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief executes the test suites
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
jsunity.run(CapConstraintTimecriticalSuite);
|
||||
|
||||
return jsunity.done();
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
// End:
|
|
@ -398,93 +398,6 @@ function CapConstraintSuite() {
|
|||
assertEqual([ "abc", "def", "ghi" ], collection.toArray().map(fun).sort());
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test: reload
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testReload : function () {
|
||||
var idx = collection.ensureCapConstraint(5);
|
||||
var fun = function(d) { return d.n; };
|
||||
|
||||
assertEqual("cap", idx.type);
|
||||
assertEqual(true, idx.isNewlyCreated);
|
||||
assertEqual(5, idx.size);
|
||||
assertEqual(0, idx.byteSize);
|
||||
|
||||
assertEqual(0, collection.count());
|
||||
|
||||
for (var i = 0; i < 10; ++i) {
|
||||
collection.save({ n : i });
|
||||
}
|
||||
|
||||
assertEqual(5, collection.count());
|
||||
assertEqual([5, 6, 7, 8, 9], collection.toArray().map(fun).sort(nsort));
|
||||
|
||||
testHelper.waitUnload(collection, true);
|
||||
|
||||
assertEqual(5, collection.count());
|
||||
assertEqual([5, 6, 7, 8, 9], collection.toArray().map(fun).sort(nsort));
|
||||
|
||||
collection.save({ n : 10 });
|
||||
assertEqual(5, collection.count());
|
||||
assertEqual([6, 7, 8, 9, 10], collection.toArray().map(fun).sort(nsort));
|
||||
|
||||
collection.save({ n : 11 });
|
||||
assertEqual(5, collection.count());
|
||||
assertEqual([7, 8, 9, 10, 11], collection.toArray().map(fun).sort(nsort));
|
||||
|
||||
testHelper.waitUnload(collection, true);
|
||||
|
||||
assertEqual(5, collection.count());
|
||||
assertEqual([7, 8, 9, 10, 11], collection.toArray().map(fun).sort(nsort));
|
||||
|
||||
for (var i = 15; i < 20; ++i) {
|
||||
collection.save({ n : i });
|
||||
}
|
||||
|
||||
assertEqual(5, collection.count());
|
||||
assertEqual([15, 16, 17, 18, 19], collection.toArray().map(fun).sort(nsort));
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test: reload
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testReloadMulti : function () {
|
||||
var idx = collection.ensureCapConstraint(5);
|
||||
var fun = function(d) { return d.n; };
|
||||
|
||||
assertEqual("cap", idx.type);
|
||||
assertEqual(true, idx.isNewlyCreated);
|
||||
assertEqual(5, idx.size);
|
||||
assertEqual(0, idx.byteSize);
|
||||
|
||||
assertEqual(0, collection.count());
|
||||
|
||||
testHelper.waitUnload(collection, true);
|
||||
|
||||
assertEqual(0, collection.count());
|
||||
|
||||
for (var i = 0; i < 10; ++i) {
|
||||
collection.save({ n : i });
|
||||
}
|
||||
|
||||
testHelper.waitUnload(collection, true);
|
||||
|
||||
assertEqual(5, collection.count());
|
||||
assertEqual([5, 6, 7, 8, 9], collection.toArray().map(fun).sort(nsort));
|
||||
|
||||
collection.save({ n : 10 });
|
||||
|
||||
testHelper.waitUnload(collection, true);
|
||||
|
||||
assertEqual(5, collection.count());
|
||||
assertEqual([6, 7, 8, 9, 10], collection.toArray().map(fun).sort(nsort));
|
||||
|
||||
collection.save({ n: 0 });
|
||||
assertEqual([0, 7, 8, 9, 10], collection.toArray().map(fun).sort(nsort));
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test: cap with byteSize
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -1577,8 +1577,15 @@ function resultOk (req, res, httpReturnCode, result, headers) {
|
|||
result = {};
|
||||
}
|
||||
|
||||
result.error = false;
|
||||
result.code = httpReturnCode;
|
||||
// check the type of the result.
|
||||
if (typeof result !== "string" &&
|
||||
typeof result !== "number" &&
|
||||
typeof result !== "boolean") {
|
||||
// only modify result properties if none of the above types
|
||||
// otherwise the strict mode will throw
|
||||
result.error = false;
|
||||
result.code = httpReturnCode;
|
||||
}
|
||||
|
||||
res.body = JSON.stringify(result);
|
||||
|
||||
|
|
|
@ -493,6 +493,9 @@ shutdownActions.startServers = function (dispatchers, cmd, run) {
|
|||
var i;
|
||||
var url;
|
||||
var r;
|
||||
var serverStates = {};
|
||||
var error = false;
|
||||
|
||||
for (i = 0;i < run.endpoints.length;i++) {
|
||||
console.info("Using API to shutdown %s", JSON.stringify(run.pids[i]));
|
||||
url = endpointToURL(run.endpoints[i])+"/_admin/shutdown";
|
||||
|
@ -514,13 +517,20 @@ shutdownActions.startServers = function (dispatchers, cmd, run) {
|
|||
for (i = 0;i < run.pids.length;i++) {
|
||||
var s = statusExternal(run.pids[i]);
|
||||
if (s.status !== "TERMINATED") {
|
||||
console.info("Shutting down %s the hard way...",
|
||||
JSON.stringify(run.pids[i]));
|
||||
killExternal(run.pids[i]);
|
||||
console.info("done.");
|
||||
if (s.hasOwnProperty('signal')) {
|
||||
error = true;
|
||||
console.info("done - with problems: " + s);
|
||||
}
|
||||
else {
|
||||
console.info("Shutting down %s the hard way...",
|
||||
JSON.stringify(run.pids[i]));
|
||||
s.killedState = killExternal(run.pids[i]);
|
||||
console.info("done.");
|
||||
}
|
||||
serverStates[run.pids[i]] = s;
|
||||
}
|
||||
}
|
||||
return {"error": false, "isStartServers": true};
|
||||
return {"error": error, "isStartServers": true, "serverStates" : serverStates};
|
||||
};
|
||||
|
||||
cleanupActions.startAgent = function (dispatchers, cmd) {
|
||||
|
|
|
@ -152,7 +152,7 @@ BaseMiddleware = function () {
|
|||
///
|
||||
/// `request.requestParts()`
|
||||
///
|
||||
/// Returns a list containing the individual parts of a multi-part request.
|
||||
/// Returns an array containing the individual parts of a multi-part request.
|
||||
/// Each part contains a `headers` attribute with all headers of the part,
|
||||
/// and a `data` attribute with the content of the part in a Buffer object.
|
||||
/// If the request is not a multi-part request, this function will throw an
|
||||
|
|
|
@ -24,10 +24,11 @@
|
|||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Dr. Frank Celler, Michael Hackstein
|
||||
/// @author Copyright 2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
var arangodb = require("org/arangodb");
|
||||
var ArangoError = arangodb.ArangoError;
|
||||
var errors = arangodb.errors;
|
||||
|
@ -50,6 +51,7 @@ var download = require("internal").download;
|
|||
var throwDownloadError = arangodb.throwDownloadError;
|
||||
var throwFileNotFound = arangodb.throwFileNotFound;
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -177,52 +179,6 @@ function checkManifest (filename, mf) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief extend a context with some helper functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function extendContext (context, app, root) {
|
||||
"use strict";
|
||||
|
||||
var cp = context.collectionPrefix;
|
||||
var cname = "";
|
||||
|
||||
if (cp === "_") {
|
||||
cname = "_";
|
||||
}
|
||||
else if (cp !== "") {
|
||||
cname = cp + "_";
|
||||
}
|
||||
|
||||
context.collectionName = function (name) {
|
||||
var replaced = cname + name.replace(/[^a-zA-Z0-9]/g, '_').replace(/(^_+|_+$)/g, '').substr(0, 64);
|
||||
|
||||
if (replaced.length === 0) {
|
||||
throw new Error("Cannot derive collection name from '" + name + "'");
|
||||
}
|
||||
|
||||
return replaced;
|
||||
};
|
||||
|
||||
context.collection = function (name) {
|
||||
return arangodb.db._collection(this.collectionName(name));
|
||||
};
|
||||
|
||||
context.path = function (name) {
|
||||
return fs.join(root, app._path, name);
|
||||
};
|
||||
|
||||
context.comments = [];
|
||||
|
||||
context.comment = function (str) {
|
||||
this.comments.push(str);
|
||||
};
|
||||
|
||||
context.clearComments = function () {
|
||||
this.comments = [];
|
||||
};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief finds mount document from mount path or identifier
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -865,40 +821,6 @@ exports.mount = function (appId, mount, options) {
|
|||
return { appId: app._id, mountId: doc._key, mount: mount };
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief tears down a Foxx application
|
||||
///
|
||||
/// Input:
|
||||
/// * mount: the mount path starting with a "/"
|
||||
///
|
||||
/// Output:
|
||||
/// -
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
exports.teardown = function (mount) {
|
||||
"use strict";
|
||||
|
||||
checkParameter(
|
||||
"teardown(<mount>)",
|
||||
[ [ "Mount identifier", "string" ] ],
|
||||
[ mount ] );
|
||||
|
||||
var appId;
|
||||
|
||||
try {
|
||||
var doc = mountFromId(mount);
|
||||
|
||||
appId = doc.app;
|
||||
var app = createApp(appId);
|
||||
|
||||
teardownApp(app, mount, doc.options.collectionPrefix);
|
||||
} catch (err) {
|
||||
console.errorLines(
|
||||
"Teardown not possible for mount '%s': %s", mount, String(err.stack || err));
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief unmounts a Foxx application
|
||||
///
|
||||
|
@ -1209,16 +1131,6 @@ exports.fetchFromGithub = function (url, name, version) {
|
|||
return "app:" + source.name + ":" + source.version;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///// @brief returns all installed FOXX applications
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
exports.listJson = function () {
|
||||
"use strict";
|
||||
|
||||
return utils.listJson();
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initializes the Foxx apps
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1287,6 +1199,7 @@ exports.initializeFoxx = function () {
|
|||
});
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
(function() {
|
||||
"use strict";
|
||||
|
@ -1294,6 +1207,22 @@ exports.initializeFoxx = function () {
|
|||
// --CHAPTER-- used code
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- imports
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
var fs = require("fs");
|
||||
var utils = require("org/arangodb/foxx/manager-utils");
|
||||
var store = require("org/arangodb/foxx/store");
|
||||
var arangodb = require("org/arangodb");
|
||||
var ArangoError = arangodb.ArangoError;
|
||||
var checkParameter = arangodb.checkParameter;
|
||||
var errors = arangodb.errors;
|
||||
var download = require("internal").download;
|
||||
|
||||
var throwDownloadError = arangodb.throwDownloadError;
|
||||
var throwFileNotFound = arangodb.throwFileNotFound;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private variables
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -1321,6 +1250,52 @@ var prefixFromMount = function(mount) {
|
|||
return mount.substr(1).replace(/-/g, "_").replace(/\//g, "_");
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief extend a context with some helper functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var extendContext = function(context, app, root) {
|
||||
var cp = context.collectionPrefix;
|
||||
var cname = "";
|
||||
|
||||
if (cp === "_") {
|
||||
cname = "_";
|
||||
}
|
||||
else if (cp !== "") {
|
||||
cname = cp + "_";
|
||||
}
|
||||
|
||||
context.collectionName = function (name) {
|
||||
var replaced = cname + name.replace(/[^a-zA-Z0-9]/g, '_').replace(/(^_+|_+$)/g, '').substr(0, 64);
|
||||
|
||||
if (replaced.length === 0) {
|
||||
throw new Error("Cannot derive collection name from '" + name + "'");
|
||||
}
|
||||
|
||||
return replaced;
|
||||
};
|
||||
|
||||
context.collection = function (name) {
|
||||
return arangodb.db._collection(this.collectionName(name));
|
||||
};
|
||||
|
||||
context.path = function (name) {
|
||||
return fs.join(root, app._path, name);
|
||||
};
|
||||
|
||||
context.comments = [];
|
||||
|
||||
context.comment = function (str) {
|
||||
this.comments.push(str);
|
||||
};
|
||||
|
||||
context.clearComments = function () {
|
||||
this.comments = [];
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief validates a manifest file and returns it.
|
||||
/// All errors are handled including file not found. Returns undefined if manifest is invalid
|
||||
|
@ -1348,16 +1323,22 @@ var validateManifestFile = function(file) {
|
|||
return mf;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Checks if the mountpoint is reserved for system apps
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var isSystemMount = function(mount) {
|
||||
return (/^\/_/).test(mount);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns the root path for application. Knows about system apps
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var computeRootAppPath = function(mount) {
|
||||
if (/^\/_/.test(mount)) {
|
||||
// Must be a system app
|
||||
if (isSystemMount(mount)) {
|
||||
return module.systemAppPath();
|
||||
}
|
||||
// A standard app
|
||||
return module.appPath();
|
||||
};
|
||||
|
||||
|
@ -1366,7 +1347,9 @@ var computeRootAppPath = function(mount) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var transformMountToPath = function(mount) {
|
||||
return fs.join.apply(this, mount.split("/").push("APP"));
|
||||
var list = mount.split("/");
|
||||
list.push("APP");
|
||||
return fs.join.apply(this, list);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1415,36 +1398,29 @@ var executeAppScript = function(app, name, mount, prefix) {
|
|||
|
||||
app.loadAppScript(appContext, desc[name]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief sets up an app
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function setupApp (app, mount, prefix) {
|
||||
"use strict";
|
||||
|
||||
return executeAppScript(app, "setup", mount, prefix);
|
||||
}
|
||||
var setupApp = function (app, mount, prefix) {
|
||||
return executeAppScript(app, "setup", mount, prefix);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief tears down an app
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function teardownApp (app, mount, prefix) {
|
||||
"use strict";
|
||||
|
||||
return executeAppScript(app, "teardown", mount, prefix);
|
||||
}
|
||||
|
||||
|
||||
|
||||
var teardownApp = function (app, mount, prefix) {
|
||||
return executeAppScript(app, "teardown", mount, prefix);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns the app path and manifest
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var appDescription = function (mount, options) {
|
||||
var appConfig = function (mount, options) {
|
||||
|
||||
var root = computeRootAppPath(mount);
|
||||
var path = transformMountToPath(mount);
|
||||
|
@ -1462,7 +1438,10 @@ function teardownApp (app, mount, prefix) {
|
|||
root: root,
|
||||
path: path,
|
||||
manifest: manifest,
|
||||
options: options
|
||||
options: options,
|
||||
mount: mount,
|
||||
isSystem: isSystemMount(mount),
|
||||
isDevelopment: false
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -1473,8 +1452,9 @@ function teardownApp (app, mount, prefix) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var createApp = function(mount, options) {
|
||||
var description = appDescription(mount);
|
||||
var app = module.createApp(description, options || {});
|
||||
var config = appConfig(mount);
|
||||
config.options = options || {};
|
||||
var app = module.createApp(config);
|
||||
if (app === null) {
|
||||
console.errorLines(
|
||||
"Cannot find application '%s'", mount);
|
||||
|
@ -1632,7 +1612,7 @@ var installAppFromLocal = function(path, targetPath) {
|
|||
/// @brief sets up a Foxx application
|
||||
///
|
||||
/// Input:
|
||||
/// * mount: the mount identifier or path
|
||||
/// * mount: the mount path starting with a "/"
|
||||
///
|
||||
/// Output:
|
||||
/// -
|
||||
|
@ -1655,6 +1635,32 @@ var setup = function (mount) {
|
|||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief tears down a Foxx application
|
||||
///
|
||||
/// Input:
|
||||
/// * mount: the mount path starting with a "/"
|
||||
///
|
||||
/// Output:
|
||||
/// -
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var teardown = function (mount) {
|
||||
checkParameter(
|
||||
"teardown(<mount>)",
|
||||
[ [ "Mount path", "string" ] ],
|
||||
[ mount ] );
|
||||
|
||||
var app = lookupApp(mount);
|
||||
try {
|
||||
teardownApp(app, mount, prefixFromMount(mount));
|
||||
} catch (err) {
|
||||
console.errorLines(
|
||||
"Teardown not possible for mount '%s': %s", mount, String(err.stack || err));
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Scans the sources of the given mountpoint and publishes the routes
|
||||
///
|
||||
|
@ -1662,22 +1668,16 @@ var setup = function (mount) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
var scanFoxx = function(mount, options) {
|
||||
delete appCache[mount];
|
||||
createApp(mount, options);
|
||||
var app = createApp(mount, options);
|
||||
utils.tmp_getStorage().save(app.toJSON());
|
||||
// TODO Routing?
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Installs a new foxx application on the given mount point.
|
||||
///
|
||||
/// TODO: Long Documentation!
|
||||
/// @brief Internal install function. Check install.
|
||||
/// Does not check parameters and throws errors.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
var install = function(appInfo, mount, options) {
|
||||
|
||||
checkParameter(
|
||||
"mount(<appInfo>, <mount>, [<options>])",
|
||||
[ [ "Install information", "string" ],
|
||||
[ "Mount path", "string" ] ],
|
||||
[ appInfo, mount ] );
|
||||
|
||||
var _install = function(appInfo, mount, options, runSetup) {
|
||||
var targetPath = computeAppPath(mount, true);
|
||||
if (fs.exists(targetPath)) {
|
||||
throw "An app is already installed at this location.";
|
||||
|
@ -1685,7 +1685,7 @@ var install = function(appInfo, mount, options) {
|
|||
fs.makeDirectoryRecursive(targetPath);
|
||||
// Remove the empty APP folder.
|
||||
// Ohterwise move will fail.
|
||||
fs.removeDirectoryRecursive(targetPath);
|
||||
fs.removeDirectory(targetPath);
|
||||
|
||||
if (appInfo === "EMPTY") {
|
||||
// Make Empty app
|
||||
|
@ -1701,27 +1701,110 @@ var install = function(appInfo, mount, options) {
|
|||
throw "Not implemented yet";
|
||||
}
|
||||
scanFoxx(mount, options);
|
||||
setup(mount);
|
||||
if (runSetup) {
|
||||
setup(mount);
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Installs a new foxx application on the given mount point.
|
||||
///
|
||||
/// TODO: Long Documentation!
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
var install = function(appInfo, mount, options) {
|
||||
checkParameter(
|
||||
"mount(<appInfo>, <mount>, [<options>])",
|
||||
[ [ "Install information", "string" ],
|
||||
[ "Mount path", "string" ] ],
|
||||
[ appInfo, mount ] );
|
||||
_install(appInfo, mount, options, true);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Internal install function. Check install.
|
||||
/// Does not check parameters and throws errors.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
var _uninstall = function(mount) {
|
||||
var targetPath = computeAppPath(mount, true);
|
||||
if (!fs.exists(targetPath)) {
|
||||
throw "No foxx app found at this location.";
|
||||
}
|
||||
teardown(mount);
|
||||
// TODO Delete routing?
|
||||
utils.tmp_getStorage().removeByExample({mount: mount});
|
||||
delete appCache[mount];
|
||||
// Remove the APP folder.
|
||||
fs.removeDirectoryRecursive(targetPath, true);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Uninstalls the foxx application on the given mount point.
|
||||
///
|
||||
/// TODO: Long Documentation!
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
var uninstall = function(mount) {
|
||||
checkParameter(
|
||||
"mount(<mount>)",
|
||||
[ [ "Mount path", "string" ] ],
|
||||
[ mount ] );
|
||||
_uninstall(mount);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Replaces a foxx application on the given mount point by an other one.
|
||||
///
|
||||
/// TODO: Long Documentation!
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
var replace = function(appInfo, mount, options) {
|
||||
checkParameter(
|
||||
"mount(<appInfo>, <mount>, [<options>])",
|
||||
[ [ "Install information", "string" ],
|
||||
[ "Mount path", "string" ] ],
|
||||
[ appInfo, mount ] );
|
||||
_uninstall(mount, true);
|
||||
_install(appInfo, mount, options, true);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Upgrade a foxx application on the given mount point by a new one.
|
||||
///
|
||||
/// TODO: Long Documentation!
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
var upgrade = function(appInfo, mount, options) {
|
||||
checkParameter(
|
||||
"mount(<appInfo>, <mount>, [<options>])",
|
||||
[ [ "Install information", "string" ],
|
||||
[ "Mount path", "string" ] ],
|
||||
[ appInfo, mount ] );
|
||||
_uninstall(mount, false);
|
||||
_install(appInfo, mount, options, false);
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- exports
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Exports
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
exports.scanFoxx = scanFoxx;
|
||||
exports.install = install;
|
||||
/*
|
||||
exports.uninstall = uninstall;
|
||||
exports.setup = setup;
|
||||
exports.teardown = teardown;
|
||||
exports.list = list;
|
||||
exports.listJson = listJson;
|
||||
exports.replace = replace;
|
||||
exports.mountedApp = mountedApp;
|
||||
exports.upgrade = upgrade;
|
||||
exports.scanFoxx = scanFoxx;
|
||||
exports.developmentMounts = developmentMounts;
|
||||
exports.developmentMountsJson = developmentMountsJson;
|
||||
*/
|
||||
exports.setup = setup;
|
||||
exports.teardown = teardown;
|
||||
exports.uninstall = uninstall;
|
||||
exports.replace = replace;
|
||||
exports.upgrade = upgrade;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Exports from foxx utils module.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
exports.mountedApp = utils.mountedApp;
|
||||
exports.list = utils.list;
|
||||
exports.listJson = utils.listJson;
|
||||
exports.listDevelopment = utils.listDevelopment;
|
||||
exports.listDevelopmentJson = utils.listDevelopmentJson;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Exports from foxx store module.
|
||||
|
|
|
@ -98,6 +98,7 @@ var Planner = require("org/arangodb/cluster").Planner;
|
|||
var Kickstarter = require("org/arangodb/cluster").Kickstarter;
|
||||
|
||||
var endpointToURL = require("org/arangodb/cluster/planner").endpointToURL;
|
||||
var serverCrashed = false;
|
||||
|
||||
var optionsDefaults = { "cluster": false,
|
||||
"valgrind": false,
|
||||
|
@ -394,6 +395,9 @@ function checkInstanceAlive(instanceInfo, options) {
|
|||
copy("bin/arangod", storeArangodPath);
|
||||
}
|
||||
}
|
||||
if (!ret) {
|
||||
serverCrashed = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
var ClusterFit = true;
|
||||
|
@ -419,30 +423,69 @@ function checkInstanceAlive(instanceInfo, options) {
|
|||
}
|
||||
}
|
||||
}
|
||||
return ClusterFit && instanceInfo.kickstarter.isHealthy();
|
||||
if (ClusterFit && instanceInfo.kickstarter.isHealthy()) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
serverCrashed = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function shutdownInstance (instanceInfo, options) {
|
||||
if (!checkInstanceAlive(instanceInfo, options)) {
|
||||
print("Server already dead, doing nothing. This shouldn't happen?");
|
||||
}
|
||||
if (options.cluster) {
|
||||
instanceInfo.kickstarter.shutdown();
|
||||
var rc = instanceInfo.kickstarter.shutdown();
|
||||
if (options.cleanup) {
|
||||
instanceInfo.kickstarter.cleanup();
|
||||
}
|
||||
if (rc.error) {
|
||||
for (var i in rc.serverStates) {
|
||||
if (rc.serverStates.hasOwnProperty(i)){
|
||||
if (rc.serverStates[i].hasOwnProperty('signal')) {
|
||||
print("Server shut down with : " + rc.serverStates[i] + " marking run as crashy.");
|
||||
serverCrashed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (typeof(instanceInfo.exitStatus) === 'undefined') {
|
||||
download(instanceInfo.url+"/_admin/shutdown","",
|
||||
makeAuthorisationHeaders(options));
|
||||
|
||||
if (typeof(options.valgrind) === 'string') {
|
||||
print("Waiting for server shut down");
|
||||
var res = statusExternal(instanceInfo.pid, true);
|
||||
print("Server gone: ");
|
||||
print(res);
|
||||
}
|
||||
else {
|
||||
wait(10);
|
||||
killExternal(instanceInfo.pid);
|
||||
print("Waiting for server shut down");
|
||||
var count = 0;
|
||||
while (1) {
|
||||
instanceInfo.exitStatus = statusExternal(instanceInfo.pid, false);
|
||||
if (instanceInfo.exitStatus.status === "RUNNING") {
|
||||
count ++;
|
||||
if (typeof(options.valgrind) === 'string') {
|
||||
continue;
|
||||
}
|
||||
if (count > 10) {
|
||||
print("forcefully terminating " + instanceInfo.pid + " after 10 s grace period.");
|
||||
serverCrashed = true;
|
||||
killExternal(instanceInfo.pid);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
wait(1);
|
||||
}
|
||||
}
|
||||
else if (instanceInfo.exitStatus.status !== "TERMINATED") {
|
||||
if (instanceInfo.exitStatus.hasOwnProperty('signal')) {
|
||||
print("Server shut down with : " + instanceInfo.exitStatus + " marking build as crashy.");
|
||||
serverCrashed = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
print("Server shutdown: Success.");
|
||||
break; // Success.
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -1485,7 +1528,7 @@ testFuncs.authentication_parameters = function (options) {
|
|||
return results;
|
||||
};
|
||||
|
||||
var internalMembers = ["code", "error", "status", "duration", "failed", "total"];
|
||||
var internalMembers = ["code", "error", "status", "duration", "failed", "total", "crashed", "all_ok", "ok", "message"];
|
||||
|
||||
function unitTestPrettyPrintResults(r) {
|
||||
var testrun;
|
||||
|
@ -1498,13 +1541,13 @@ function unitTestPrettyPrintResults(r) {
|
|||
|
||||
try {
|
||||
for (testrun in r) {
|
||||
if (r.hasOwnProperty(testrun) && (testrun !== 'all_ok')) {
|
||||
if (r.hasOwnProperty(testrun) && (internalMembers.indexOf(testrun) === -1)) {
|
||||
var isSuccess = true;
|
||||
var oneOutput = "";
|
||||
|
||||
oneOutput = "Testrun: " + testrun + "\n";
|
||||
for (test in r[testrun]) {
|
||||
if (r[testrun].hasOwnProperty(test) && (test !== 'ok')) {
|
||||
if (r[testrun].hasOwnProperty(test) && (internalMembers.indexOf(test) === -1)) {
|
||||
if (r[testrun][test].status) {
|
||||
oneOutput += " [Success] " + test + "\n";
|
||||
}
|
||||
|
@ -1599,6 +1642,7 @@ function UnitTest (which, options) {
|
|||
results.all_ok = allok;
|
||||
}
|
||||
results.all_ok = allok;
|
||||
results.crashed = serverCrashed;
|
||||
if (allok) {
|
||||
cleanupDBDirectories(options);
|
||||
}
|
||||
|
@ -1634,6 +1678,7 @@ function UnitTest (which, options) {
|
|||
}
|
||||
r.ok = ok;
|
||||
results.all_ok = ok;
|
||||
results.crashed = serverCrashed;
|
||||
|
||||
if (allok) {
|
||||
cleanupDBDirectories(options);
|
||||
|
@ -1652,6 +1697,7 @@ function UnitTest (which, options) {
|
|||
}
|
||||
}
|
||||
|
||||
exports.internalMembers = internalMembers;
|
||||
exports.testFuncs = testFuncs;
|
||||
exports.UnitTest = UnitTest;
|
||||
exports.unitTestPrettyPrintResults = unitTestPrettyPrintResults;
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
/*jshint unused: false */
|
||||
/*global require, start_pretty_print */
|
||||
|
||||
var internalMembers = ["code", "error", "status", "duration", "failed", "total", "message"];
|
||||
var UnitTest = require("org/arangodb/testing");
|
||||
|
||||
var internalMembers = UnitTest.internalMembers;
|
||||
var fs = require("fs");
|
||||
var print = require("internal").print;
|
||||
|
||||
|
@ -46,10 +48,10 @@ function resultsToXml(results, baseName) {
|
|||
}
|
||||
|
||||
for (var testrun in results) {
|
||||
if ((testrun !== "all_ok") && (results.hasOwnProperty(testrun))) {
|
||||
if ((internalMembers.indexOf(testrun) === -1) && (results.hasOwnProperty(testrun))) {
|
||||
for (var test in results[testrun]) {
|
||||
|
||||
if ((test !== "ok") &&
|
||||
if ((internalMembers.indexOf(test) === -1) &&
|
||||
results[testrun].hasOwnProperty(test) &&
|
||||
!results[testrun][test].hasOwnProperty('skipped')) {
|
||||
|
||||
|
@ -127,7 +129,6 @@ function main (argv) {
|
|||
}
|
||||
}
|
||||
options.jsonReply = true;
|
||||
var UnitTest = require("org/arangodb/testing");
|
||||
start_pretty_print();
|
||||
|
||||
try {
|
||||
|
@ -139,7 +140,7 @@ function main (argv) {
|
|||
print(JSON.stringify(r));
|
||||
}
|
||||
fs.write("UNITTEST_RESULT.json",JSON.stringify(r));
|
||||
fs.write("UNITTEST_RESULT_SUMMARY.txt",JSON.stringify(r.all_ok));
|
||||
fs.write("UNITTEST_RESULT_SUMMARY.txt",JSON.stringify(!r.crashed));
|
||||
try {
|
||||
resultsToXml(r, "UNITTEST_RESULT_");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue