You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ac...@apache.org on 2014/10/18 01:35:37 UTC
svn commit: r1632696 [2/2] - in /qpid/dispatch/trunk: doc/api/ doc/man/
include/qpid/dispatch/ python/qpid_dispatch/
python/qpid_dispatch/management/ python/qpid_dispatch/qpid_dispatch/
python/qpid_dispatch_internal/ python/qpid_dispatch_internal/manag...
Modified: qpid/dispatch/trunk/src/entity_private.h
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/entity_private.h?rev=1632696&r1=1632695&r2=1632696&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/entity_private.h (original)
+++ qpid/dispatch/trunk/src/entity_private.h Fri Oct 17 23:35:35 2014
@@ -22,6 +22,14 @@
#include <stdbool.h>
#include <qpid/dispatch/dispatch.h>
+/**
+ * @defgroup entity
+xo *
+ * Holds attributes of a managed entity.
+ * @{
+ */
+
+
void qd_entity_free(qd_entity_t* entity);
/** True if the entity has this attribute. */
@@ -60,4 +68,35 @@ long qd_entity_opt_long(qd_entity_t *ent
bool qd_entity_opt_bool(qd_entity_t *entity, const char *attribute, bool default_value);
+/** Set a string valued attribute, entity makes a copy.
+ * If value is NULL clear the attribute.
+ */
+qd_error_t qd_entity_set_string(qd_entity_t *entity, const char* attribute, const char *value);
+
+/** Set a string valued attribute from a printf format */
+qd_error_t qd_entity_set_stringf(qd_entity_t *entity, const char* attribute, const char *format, ...);
+
+/** Set an integer valued attribute. */
+qd_error_t qd_entity_set_long(qd_entity_t *entity, const char* attribute, long value);
+
+/** Set a boolean valued attribute. */
+qd_error_t qd_entity_set_bool(qd_entity_t *entity, const char *attribute, bool value);
+
+/** Set an integer valued attribute. If value is NULL clear the attribute. */
+qd_error_t qd_entity_set_longp(qd_entity_t *entity, const char* attribute, const long *value);
+
+/** Set a boolean valued attribute. If value is NULL clear the attribute. */
+qd_error_t qd_entity_set_boolp(qd_entity_t *entity, const char *attribute, const bool *value);
+
+/** Clear the attribute */
+qd_error_t qd_entity_clear(qd_entity_t *entity, const char *attribute);
+
+/**
+ * Set the attribute to an empty list. Futher qd_entity_set* calls for the attribute
+ * will append values to the list.
+ */
+qd_error_t qd_entity_set_list(qd_entity_t *entity, const char *attribute);
+
+/// @}
+
#endif
Modified: qpid/dispatch/trunk/src/error.c
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/error.c?rev=1632696&r1=1632695&r2=1632696&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/error.c (original)
+++ qpid/dispatch/trunk/src/error.c Fri Oct 17 23:35:35 2014
@@ -19,13 +19,14 @@
#include <Python.h>
#include <qpid/dispatch/error.h>
+#include <qpid/dispatch/enum.h>
#include <qpid/dispatch/log.h>
#include <stdarg.h>
#include <stdio.h>
-#include "static_assert.h"
#include "log_private.h"
+#include "aprintf.h"
-static const char *error_names[] = {
+static const char *qd_error_names[] = {
"No Error",
"Not found",
"Already exists",
@@ -37,9 +38,7 @@ static const char *error_names[] = {
"Value",
"Run Time"
};
-
-STATIC_ASSERT(sizeof(error_names)/sizeof(error_names[0]) == QD_ERROR_ENUM_COUNT,
- error_names_wrong_size);
+ENUM_DEFINE(qd_error, qd_error_names);
#define ERROR_MAX QD_LOG_TEXT_MAX
const int QD_ERROR_MAX = ERROR_MAX;
@@ -56,19 +55,22 @@ void qd_error_initialize() {
log_source = qd_log_source("ERROR");
}
-qd_error_t qd_error(qd_error_t code, const char *fmt, ...) {
+qd_error_t qd_error_impl(qd_error_t code, const char *file, int line, const char *fmt, ...) {
ts.error_code = code;
if (code) {
- int i = 0;
- if (code < QD_ERROR_ENUM_COUNT)
- i = snprintf(ts.error_message, ERROR_MAX,"%s: ", error_names[code]);
+ char *begin = ts.error_message;
+ char *end = begin + ERROR_MAX;
+ const char* name = qd_error_name(code);
+ if (name)
+ aprintf(&begin, end, "%s: ", name);
else
- i = snprintf(ts.error_message, ERROR_MAX, "%d: ", code);
+ aprintf(&begin, end, "%d: ", code);
va_list arglist;
va_start(arglist, fmt);
- vsnprintf(ts.error_message+i, ERROR_MAX-i, fmt, arglist);
+ vaprintf(&begin, end, fmt, arglist);
va_end(arglist);
- qd_log(log_source, QD_LOG_ERROR, "%s", qd_error_message());
+ // NOTE: Use the file/line from the qd_error macro, not this line in error.c
+ qd_log_impl(log_source, QD_LOG_ERROR, file, line, "%s", qd_error_message());
return code;
}
else
@@ -95,7 +97,9 @@ static void py_set_item(PyObject *dict,
Py_DECREF(py_name);
}
-static void log_trace_py(PyObject *type, PyObject *value, PyObject* trace, qd_log_level_t level) {
+static void log_trace_py(PyObject *type, PyObject *value, PyObject* trace, qd_log_level_t level,
+ const char *file, int line)
+{
if (!qd_log_enabled(log_source, level)) return;
if (!(type && value && trace)) return;
@@ -116,10 +120,11 @@ static void log_trace_py(PyObject *type,
Py_DECREF(globals);
Py_DECREF(locals);
+
if (result) {
const char* trace = PyString_AsString(result);
if (strlen(trace) < QD_LOG_TEXT_MAX) {
- qd_log(log_source, level, "%s", trace);
+ qd_log_impl(log_source, level, file, line, "%s", trace);
} else {
// Keep as much of the the tail of the trace as we can.
const char *tail = trace;
@@ -127,14 +132,14 @@ static void log_trace_py(PyObject *type,
tail = strchr(tail, '\n');
if (tail) ++tail;
}
- qd_log(log_source, level, "Traceback truncated:\n%s", tail ? tail : "");
+ qd_log_impl(log_source, level, file, line, "Traceback truncated:\n%s", tail ? tail : "");
}
Py_DECREF(result);
}
}
-qd_error_t qd_error_py() {
+qd_error_t qd_error_py_impl(const char *file, int line) {
if (PyErr_Occurred()) {
PyObject *type, *value, *trace;
PyErr_Fetch(&type, &value, &trace); /* Note clears the python error indicator */
@@ -144,13 +149,13 @@ qd_error_t qd_error_py() {
PyObject *value_str = value ? PyObject_Str(value) : NULL;
const char* str = value_str ? PyString_AsString(value_str) : "Unknown";
if (type_name)
- qd_error(QD_ERROR_PYTHON, "%s: %s", PyString_AsString(type_name), str);
+ qd_error_impl(QD_ERROR_PYTHON, file, line, "%s: %s", PyString_AsString(type_name), str);
else
- qd_error(QD_ERROR_PYTHON, "%s", str);
+ qd_error_impl(QD_ERROR_PYTHON, file, line, "%s", str);
Py_XDECREF(value_str);
Py_XDECREF(type_name);
- log_trace_py(type, value, trace, QD_LOG_ERROR);
+ log_trace_py(type, value, trace, QD_LOG_ERROR, file, line);
Py_XDECREF(type);
Py_XDECREF(value);
Modified: qpid/dispatch/trunk/src/log.c
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/log.c?rev=1632696&r1=1632695&r2=1632696&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/log.c (original)
+++ qpid/dispatch/trunk/src/log.c Fri Oct 17 23:35:35 2014
@@ -19,6 +19,7 @@
#include "log_private.h"
#include "entity_private.h"
+#include "aprintf.h"
#include <qpid/dispatch/ctools.h>
#include <qpid/dispatch/dispatch.h>
#include <qpid/dispatch/alloc.h>
@@ -133,7 +134,8 @@ struct qd_log_source_t {
DEQ_LINKS(qd_log_source_t);
const char *module;
int mask;
- int timestamp;
+ int timestamp; /* boolean or -1 means not set */
+ int source; /* boolean or -1 means not set */
bool syslog;
log_sink_t *sink;
};
@@ -196,17 +198,30 @@ static qd_log_source_t* lookup_log_sourc
return src;
}
-static void write_log(int level, qd_log_source_t *log_source, const char *fmt, ...)
+static bool default_bool(int value, int default_value) {
+ return value == -1 ? default_value : value;
+}
+
+static void write_log(qd_log_source_t *log_source, qd_log_entry_t *entry)
{
log_sink_t* sink = log_source->sink ? log_source->sink : default_log_source->sink;
-
if (!sink) return;
char log_str[LOG_MAX];
- va_list arglist;
- va_start(arglist, fmt);
- vsnprintf(log_str, LOG_MAX, fmt, arglist);
- va_end(arglist);
+ char *begin = log_str;
+ char *end = log_str + LOG_MAX;
+
+ if (default_bool(log_source->timestamp, default_log_source->timestamp)) {
+ char buf[100];
+ buf[0] = '\0';
+ ctime_r(&entry->time, buf);
+ buf[strlen(buf)-1] = '\0'; /* Get rid of trailng \n */
+ aprintf(&begin, end, "%s ", buf);
+ }
+ aprintf(&begin, end, "%s (%s) %s", entry->module, level_for_bit(entry->level)->name, entry->text);
+ if (default_bool(log_source->source, default_log_source->source))
+ aprintf(&begin, end, " (%s:%d)", entry->file, entry->line);
+ aprintf(&begin, end, "\n");
if (sink->file) {
if (fputs(log_str, sink->file) == EOF) {
@@ -218,7 +233,7 @@ static void write_log(int level, qd_log_
fflush(sink->file);
}
if (sink->syslog) {
- int syslog_level = level_for_bit(level)->syslog;
+ int syslog_level = level_for_bit(entry->level)->syslog;
if (syslog_level != -1)
syslog(syslog_level, "%s", log_str);
}
@@ -236,6 +251,7 @@ static qd_log_source_t *qd_log_source_lh
log_source->module = module;
log_source->mask = -1;
log_source->timestamp = -1;
+ log_source->source = -1;
log_source->sink = 0;
DEQ_INSERT_TAIL(source_list, log_source);
}
@@ -273,22 +289,12 @@ void qd_log_impl(qd_log_source_t *source
entry->file = file ? strdup(file) : 0;
entry->line = line;
time(&entry->time);
-
- char ctime[100];
- ctime[0] = '\0';
- bool timestamp = (source->timestamp == -1) ?
- default_log_source->timestamp : source->timestamp;
- assert(timestamp != -1);
- if (timestamp) {
- ctime_r(&entry->time, ctime);
- ctime[24] = '\0';
- strcat(ctime, " ");
- }
va_list ap;
va_start(ap, fmt);
vsnprintf(entry->text, TEXT_MAX, fmt, ap);
va_end(ap);
- write_log(level, source, "%s%s (%s) %s\n", ctime, entry->module, level_for_bit(level)->name, entry->text);
+
+ write_log(source, entry);
sys_mutex_lock(log_lock);
DEQ_INSERT_TAIL(entries, entry);
@@ -314,6 +320,7 @@ void qd_log_initialize(void)
// Only report errors until we have configured the logging system.
default_log_source->mask = levels[INFO].mask;
default_log_source->timestamp = 1;
+ default_log_source->source = 0;
default_log_source->sink = log_sink_lh(SINK_STDERR);
logging_log_source = qd_log_source(SOURCE_LOGGING);
}
Modified: qpid/dispatch/trunk/src/message.c
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/message.c?rev=1632696&r1=1632695&r2=1632696&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/message.c (original)
+++ qpid/dispatch/trunk/src/message.c Fri Oct 17 23:35:35 2014
@@ -25,6 +25,7 @@
#include <qpid/dispatch/log.h>
#include "message_private.h"
#include "compose_private.h"
+#include "aprintf.h"
#include <string.h>
#include <ctype.h>
#include <stdio.h>
@@ -67,34 +68,29 @@ void qd_message_initialize() {
int qd_message_repr_len() { return qd_log_max_len(); }
// Quote non-printable characters suitable for log messages. Output in buffer.
-static int quote(char* bytes, int n, char* buffer, int len) {
- int i = 0;
- for (char* p = bytes; p < bytes+n && i < len; ++p) {
- if (isprint(*p) || isspace(*p)) {
- buffer[i++] = *p;
- }
- else {
- int d = snprintf(buffer+i, len-i, "\\%02hhx", *p);
- i += d;
- }
+static void quote(char* bytes, int n, char **begin, char *end) {
+ for (char* p = bytes; p < bytes+n; ++p) {
+ if (isprint(*p) || isspace(*p))
+ aprintf(begin, end, "%c", (int)*p);
+ else
+ aprintf(begin, end, "\\%02hhx", *p);
}
- return i;
}
/** Copy a message field for use in log messages. Output in buffer. */
-static int copy_field(qd_message_t *msg, int field, int max, char *pre, char *post, char *buffer, size_t len) {
+static void copy_field(qd_message_t *msg, int field, int max, char *pre, char *post,
+ char **begin, char *end)
+{
qd_field_iterator_t* iter = qd_message_field_iterator(msg, field);
- int i = 0;
if (iter) {
- i += snprintf(buffer+i, len-i, "%s", pre);
+ aprintf(begin, end, "%s", pre);
qd_field_iterator_reset(iter);
- for (int j = 0; !qd_field_iterator_end(iter) && i < len && j < max; ++j) {
+ for (int j = 0; !qd_field_iterator_end(iter) && j < max; ++j) {
char byte = qd_field_iterator_octet(iter);
- i += quote(&byte, 1, buffer+i, len-i);
+ quote(&byte, 1, begin, end);
}
- i += snprintf(buffer+i, len-i, "%s", post);
+ aprintf(begin, end, "%s", post);
}
- return i;
}
static const char REPR_END[] = "}\0";
@@ -102,14 +98,13 @@ static const char REPR_END[] = "}\0";
/* TODO aconway 2014-05-13: more detailed message representation. */
char* qd_message_repr(qd_message_t *msg, char* buffer, size_t len) {
qd_message_check(msg, QD_DEPTH_BODY);
- int i = 0;
- len -= sizeof(REPR_END); /* Save space for ending */
- i += snprintf(buffer+i, len-i, "Message(%p){", msg);
- i += copy_field(msg, QD_FIELD_TO, INT_MAX, "to='", "'", buffer+i, len-i);
- i += copy_field(msg, QD_FIELD_REPLY_TO, INT_MAX, " reply-to='", "'", buffer+i, len-i);
- i += copy_field(msg, QD_FIELD_BODY, 16, " body='", "'", buffer+i, len-i);
- assert(i <= len);
- strcat(buffer, REPR_END); /* We saved space at the beginning. */
+ char *begin = buffer;
+ char *end = buffer + len - sizeof(REPR_END); /* Save space for ending */
+ aprintf(&begin, end, "Message(%p){", msg);
+ copy_field(msg, QD_FIELD_TO, INT_MAX, "to='", "'", &begin, end);
+ copy_field(msg, QD_FIELD_REPLY_TO, INT_MAX, " reply-to='", "'", &begin, end);
+ copy_field(msg, QD_FIELD_BODY, 16, " body='", "'", &begin, end);
+ aprintf(&begin, end, "%s", REPR_END); /* We saved space at the beginning. */
return buffer;
}
Modified: qpid/dispatch/trunk/src/python_embedded.c
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/python_embedded.c?rev=1632696&r1=1632695&r2=1632696&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/python_embedded.c (original)
+++ qpid/dispatch/trunk/src/python_embedded.c Fri Oct 17 23:35:35 2014
@@ -17,6 +17,7 @@
* under the License.
*/
+#include "c_entity.h"
#include <qpid/dispatch/python_embedded.h>
#include <qpid/dispatch/threading.h>
#include <qpid/dispatch/log.h>
@@ -679,7 +680,7 @@ static void qd_python_setup(void)
if ((PyType_Ready(&LogAdapterType) < 0) || (PyType_Ready(&IoAdapterType) < 0)) {
qd_error_py();
qd_log(log_source, QD_LOG_ERROR, "Unable to initialize Adapters");
- assert(0);
+ abort();
} else {
PyObject *m = Py_InitModule3("dispatch", empty_methods, "Dispatch Adapter Module");
Modified: qpid/dispatch/trunk/src/router_agent.c
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/router_agent.c?rev=1632696&r1=1632695&r2=1632696&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/router_agent.c (original)
+++ qpid/dispatch/trunk/src/router_agent.c Fri Oct 17 23:35:35 2014
@@ -26,18 +26,74 @@
#include <qpid/dispatch/agent.h>
#include "dispatch_private.h"
#include "router_private.h"
+#include "c_entity.h"
+static const char *qd_router_mode_names[] = {
+ "standalone",
+ "interior",
+ "edge",
+ "endpoint"
+};
+ENUM_DEFINE(qd_router_mode, qd_router_mode_names);
-static const char *qd_router_addr_text(qd_address_t *addr)
+qd_error_t qd_c_entity_update_router(qd_entity_t* entity, void *impl) {
+ qd_dispatch_t *qd = (qd_dispatch_t*) impl;
+ qd_router_t *router = qd->router;
+ if (qd_entity_set_string(entity, "name", router->router_id) == 0 &&
+ qd_entity_set_string(entity, "identity", router->router_id) == 0 &&
+ qd_entity_set_string(entity, "area", router->router_area) == 0 &&
+ qd_entity_set_string(entity, "mode", qd_router_mode_name(router->router_mode)) == 0 &&
+ qd_entity_set_long(entity, "addrCount", DEQ_SIZE(router->addrs)) == 0 &&
+ qd_entity_set_long(entity, "linkCount", DEQ_SIZE(router->links)) == 0 &&
+ qd_entity_set_long(entity, "nodeCount", DEQ_SIZE(router->routers)) == 0
+ )
+ return QD_ERROR_NONE;
+ return qd_error_code();
+}
+
+static const char *address_text(qd_address_t *addr)
{
- if (addr) {
- const unsigned char *text = qd_hash_key_by_handle(addr->hash_handle);
- if (text)
- return (const char*) text;
- }
- return 0;
+ return addr ? (const char*) qd_hash_key_by_handle(addr->hash_handle) : 0;
}
+qd_error_t qd_c_entity_update_router_address(qd_entity_t* entity, void *impl) {
+ qd_address_t *addr = (qd_address_t*) impl;
+ if ((qd_entity_has(entity, "identity") ||
+ qd_entity_set_string(entity, "identity", address_text(addr)) == 0) &&
+ qd_entity_set_bool(entity, "inProcess", addr->handler != 0) == 0 &&
+ qd_entity_set_long(entity, "subscriberCount", DEQ_SIZE(addr->rlinks)) == 0 &&
+ qd_entity_set_long(entity, "remoteCount", DEQ_SIZE(addr->rnodes)) == 0 &&
+ qd_entity_set_long(entity, "deliveriesIngress", addr->deliveries_ingress) == 0 &&
+ qd_entity_set_long(entity, "deliveriesEgress", addr->deliveries_egress) == 0 &&
+ qd_entity_set_long(entity, "deliveriesTransit", addr->deliveries_transit) == 0 &&
+ qd_entity_set_long(entity, "deliveriesToContainer", addr->deliveries_to_container) == 0 &&
+ qd_entity_set_long(entity, "deliveriesFromContainer", addr->deliveries_from_container) == 0
+ )
+ return QD_ERROR_NONE;
+ return qd_error_code();
+}
+
+#define CHECK(err) if (err != 0) return qd_error_code()
+
+qd_error_t qd_c_entity_update_router_node(qd_entity_t* entity, void *impl) {
+ qd_router_node_t *rnode = (qd_router_node_t*) impl;
+
+ if (!qd_entity_has(entity, "identity")) {
+ CHECK(qd_entity_set_stringf(entity, "identity", "%s-%d", QD_ROUTER_NODE_TYPE, rnode->mask_bit));
+ }
+ CHECK(qd_entity_set_string(entity, "addr", address_text(rnode->owning_addr)));
+ long next_hop = rnode->next_hop ? rnode->next_hop->mask_bit : 0;
+ CHECK(qd_entity_set_longp(entity, "nextHop", rnode->next_hop ? &next_hop : 0));
+ long router_link = rnode->peer_link ? rnode->peer_link->mask_bit : 0;
+ CHECK(qd_entity_set_longp(entity, "routerLink", rnode->peer_link ? &router_link : 0));
+ CHECK(qd_entity_set_list(entity, "validOrigins"));
+ for (uint32_t bit = 1; bit < qd_bitmask_width(); bit++) {
+ if (qd_bitmask_value(rnode->valid_origins, bit)) {
+ CHECK(qd_entity_set_long(entity, "validOrigins", bit));
+ }
+ }
+ return QD_ERROR_NONE;
+}
static void router_attr_name(void *object_handle, void *cor, void *unused)
{
@@ -86,7 +142,6 @@ static void router_attr_nodeCount(void *
}
-static const char *ROUTER_TYPE = "org.apache.qpid.dispatch.router";
static const qd_agent_attribute_t ROUTER_ATTRIBUTES[] =
{{"name", router_attr_name, 0},
{"identity", router_attr_name, 0},
@@ -107,7 +162,6 @@ static void qd_router_query_router(void
sys_mutex_unlock(router->lock);
}
-
static void link_attr_name(void *object_handle, void *cor, void *unused)
{
qd_router_link_t *link = (qd_router_link_t*) object_handle;
@@ -140,7 +194,7 @@ static void link_attr_linkDir(void *obje
static void link_attr_owningAddr(void *object_handle, void *cor, void *unused)
{
qd_router_link_t *link = (qd_router_link_t*) object_handle;
- const char *text = qd_router_addr_text(link->owning_addr);
+ const char *text = address_text(link->owning_addr);
if (text)
qd_agent_value_string(cor, 0, text);
else
@@ -162,7 +216,6 @@ static void link_attr_msgFifoDepth(void
}
-static const char *LINK_TYPE = "org.apache.qpid.dispatch.router.link";
static const qd_agent_attribute_t LINK_ATTRIBUTES[] =
{{"name", link_attr_name, 0},
{"identity", link_attr_name, 0},
@@ -173,6 +226,7 @@ static const qd_agent_attribute_t LINK_A
{"msgFifoDepth", link_attr_msgFifoDepth, 0},
{0, 0, 0}};
+
static void qd_router_query_link(void *context, void *cor)
{
qd_router_t *router = (qd_router_t*) context;
@@ -188,6 +242,30 @@ static void qd_router_query_link(void *c
sys_mutex_unlock(router->lock);
}
+static const char *qd_link_type_names[] = { "endpoint", "waypoint", "inter-router", "inter-area" };
+ENUM_DEFINE(qd_link_type, qd_link_type_names);
+
+static const char *qd_router_addr_text(qd_address_t *addr)
+{
+ return addr ? (const char*)qd_hash_key_by_handle(addr->hash_handle) : NULL;
+}
+
+qd_error_t qd_c_entity_update_router_link(qd_entity_t* entity, void *impl)
+{
+ qd_router_link_t *link = (qd_router_link_t*) impl;
+ /* FIXME aconway 2014-10-17: old management used link->bit_mask as name/identity,
+ * but even when prefixed with router.link this is not unique. Let python agent
+ * generate a name for now, revisit with a better name later.
+ */
+ if (!qd_entity_set_string(entity, "linkType", qd_link_type_name(link->link_type)) &&
+ !qd_entity_set_string(entity, "linkDir", (link->link_direction == QD_INCOMING) ? "in": "out") &&
+ !qd_entity_set_string(entity, "owningAddr", qd_router_addr_text(link->owning_addr)) &&
+ !qd_entity_set_long(entity, "eventFifoDepth", DEQ_SIZE(link->event_fifo)) &&
+ !qd_entity_set_long(entity, "msgFifoDepth", DEQ_SIZE(link->msg_fifo))
+ )
+ return QD_ERROR_NONE;
+ return qd_error_code();
+}
static void node_attr_name(void *object_handle, void *cor, void *unused)
{
@@ -199,7 +277,7 @@ static void node_attr_name(void *object_
static void node_attr_addr(void *object_handle, void *cor, void *unused)
{
qd_router_node_t *node = (qd_router_node_t*) object_handle;
- qd_agent_value_string(cor, 0, qd_router_addr_text(node->owning_addr));
+ qd_agent_value_string(cor, 0, address_text(node->owning_addr));
}
@@ -234,7 +312,6 @@ static void node_attr_validOrigins(void
}
-static const char *NODE_TYPE = "org.apache.qpid.dispatch.router.node";
static const qd_agent_attribute_t NODE_ATTRIBUTES[] =
{{"name", node_attr_name, 0},
{"identity", node_attr_name, 0},
@@ -262,7 +339,7 @@ static void qd_router_query_node(void *c
static void addr_attr_name(void *object_handle, void *cor, void *unused)
{
qd_address_t *addr = (qd_address_t*) object_handle;
- qd_agent_value_string(cor, 0, qd_router_addr_text(addr));
+ qd_agent_value_string(cor, 0, address_text(addr));
}
@@ -322,7 +399,6 @@ static void addr_attr_deliveriesFromCont
}
-static const char *ADDRESS_TYPE = "org.apache.qpid.dispatch.router.address";
static const qd_agent_attribute_t ADDRESS_ATTRIBUTES[] =
{{"name", addr_attr_name, 0},
{"identity", addr_attr_name, 0},
@@ -355,13 +431,13 @@ qd_error_t qd_router_agent_setup(qd_rout
{
qd_error_clear();
router->class_router =
- qd_agent_register_class(router->qd, ROUTER_TYPE, router, ROUTER_ATTRIBUTES, qd_router_query_router);
+ qd_agent_register_class(router->qd, QD_ROUTER_TYPE, router, ROUTER_ATTRIBUTES, qd_router_query_router);
router->class_link =
- qd_agent_register_class(router->qd, LINK_TYPE, router, LINK_ATTRIBUTES, qd_router_query_link);
+ qd_agent_register_class(router->qd, QD_ROUTER_LINK_TYPE, router, LINK_ATTRIBUTES, qd_router_query_link);
router->class_node =
- qd_agent_register_class(router->qd, NODE_TYPE, router, NODE_ATTRIBUTES, qd_router_query_node);
+ qd_agent_register_class(router->qd, QD_ROUTER_NODE_TYPE, router, NODE_ATTRIBUTES, qd_router_query_node);
router->class_address =
- qd_agent_register_class(router->qd, ADDRESS_TYPE, router, ADDRESS_ATTRIBUTES, qd_router_query_address);
+ qd_agent_register_class(router->qd, QD_ROUTER_ADDRESS_TYPE, router, ADDRESS_ATTRIBUTES, qd_router_query_address);
return qd_error_code();
}
@@ -369,7 +445,7 @@ qd_error_t qd_router_agent_setup(qd_rout
void qd_router_build_node_list(qd_dispatch_t *qd, qd_composed_field_t *field)
{
qd_router_t *router = qd->router;
- char temp[1000]; // FIXME
+ char temp[1000];
sys_mutex_lock(router->lock);
qd_router_node_t *rnode = DEQ_HEAD(router->routers);
Modified: qpid/dispatch/trunk/src/router_node.c
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/router_node.c?rev=1632696&r1=1632695&r2=1632696&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/router_node.c (original)
+++ qpid/dispatch/trunk/src/router_node.c Fri Oct 17 23:35:35 2014
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include <qpid/dispatch.h>
#include "dispatch_private.h"
+#include "c_entity.h"
#include "router_private.h"
#include "waypoint_private.h"
@@ -156,6 +157,7 @@ void qd_router_check_addr(qd_router_t *r
//
qd_hash_remove_by_handle2(router->addr_hash, addr->hash_handle, &key);
DEQ_REMOVE(router->addrs, addr);
+ qd_c_entity_remove(QD_ROUTER_ADDRESS_TYPE, addr);
qd_hash_handle_free(addr->hash_handle);
free_qd_address_t(addr);
}
@@ -1002,6 +1004,7 @@ static int router_incoming_link_handler(
sys_mutex_lock(router->lock);
rlink->mask_bit = is_router ? qd_router_find_mask_bit_LH(router, link) : 0;
+ qd_c_entity_add(QD_ROUTER_LINK_TYPE, rlink);
DEQ_INSERT_TAIL(router->links, rlink);
sys_mutex_unlock(router->lock);
@@ -1118,7 +1121,7 @@ static int router_outgoing_link_handler(
// assign it an ephemeral and routable address. If it has a non-dynamic
// address, that address needs to be set up in the address list.
//
- char temp_addr[1000]; // FIXME
+ char temp_addr[1000]; // TODO: Use pn_string or aprintf.
if (is_dynamic) {
qd_router_generate_temp_addr(router, temp_addr, 1000);
@@ -1134,6 +1137,7 @@ static int router_outgoing_link_handler(
qd_hash_insert(router->addr_hash, iter, addr, &addr->hash_handle);
DEQ_INSERT_TAIL(router->addrs, addr);
addr->semantics = semantics;
+ qd_c_entity_add(QD_ROUTER_ADDRESS_TYPE, addr);
}
rlink->owning_addr = addr;
@@ -1146,7 +1150,7 @@ static int router_outgoing_link_handler(
//
propagate = (!is_dynamic) && (DEQ_SIZE(addr->rlinks) == 1);
}
-
+ qd_c_entity_add(QD_ROUTER_LINK_TYPE, rlink);
DEQ_INSERT_TAIL(router->links, rlink);
//
@@ -1222,6 +1226,7 @@ static int router_link_detach_handler(vo
// Remove the link from the master list-of-links.
//
DEQ_REMOVE(router->links, rlink);
+ qd_c_entity_remove(QD_ROUTER_LINK_TYPE, rlink);
sys_mutex_unlock(router->lock);
//
@@ -1229,7 +1234,6 @@ static int router_link_detach_handler(vo
//
qd_router_check_addr(router, oaddr, 1);
- // TODO - wrap the free to handle the recursive items
if (rlink->target)
free(rlink->target);
free_qd_router_link_t(rlink);
@@ -1311,6 +1315,7 @@ static void router_outbound_open_handler
DEQ_INIT(rlink->msg_fifo);
qd_link_set_context(receiver, rlink);
+ qd_c_entity_add(QD_ROUTER_LINK_TYPE, rlink);
DEQ_INSERT_TAIL(router->links, rlink);
//
@@ -1348,6 +1353,7 @@ static void router_outbound_open_handler
router->out_links_by_mask_bit[mask_bit] = rlink;
qd_link_set_context(sender, rlink);
+ qd_c_entity_add(QD_ROUTER_LINK_TYPE, rlink);
DEQ_INSERT_TAIL(router->links, rlink);
sys_mutex_unlock(router->lock);
@@ -1493,8 +1499,8 @@ void qd_router_free(qd_router_t *router)
}
qd_hash_handle_free(addr->hash_handle);
-
DEQ_REMOVE_HEAD(router->addrs);
+ qd_c_entity_remove(QD_ROUTER_ADDRESS_TYPE, addr);
free_qd_address_t(addr);
}
@@ -1528,8 +1534,8 @@ qd_address_t *qd_router_register_address
{
char addr_string[1000];
qd_router_t *router = qd->router;
- qd_address_t *addr;
- qd_field_iterator_t *iter;
+ qd_address_t *addr = 0;
+ qd_field_iterator_t *iter = 0;
strcpy(addr_string, global ? "M0" : "L");
strcat(addr_string, address);
@@ -1543,6 +1549,7 @@ qd_address_t *qd_router_register_address
qd_hash_insert(router->addr_hash, iter, addr, &addr->hash_handle);
DEQ_ITEM_INIT(addr);
DEQ_INSERT_TAIL(router->addrs, addr);
+ qd_c_entity_add(QD_ROUTER_ADDRESS_TYPE, addr);
}
qd_field_iterator_free(iter);
@@ -1553,6 +1560,7 @@ qd_address_t *qd_router_register_address
if (handler)
qd_log(router->log_source, QD_LOG_INFO, "In-Process Address Registered: %s", address);
+ assert(addr);
return addr;
}
Modified: qpid/dispatch/trunk/src/router_private.h
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/router_private.h?rev=1632696&r1=1632695&r2=1632696&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/router_private.h (original)
+++ qpid/dispatch/trunk/src/router_private.h Fri Oct 17 23:35:35 2014
@@ -24,6 +24,7 @@
*@internal
*/
+#include <qpid/dispatch/enum.h>
#include <qpid/dispatch/router.h>
#include <qpid/dispatch/message.h>
#include <qpid/dispatch/bitmask.h>
@@ -48,6 +49,7 @@ typedef enum {
QD_ROUTER_MODE_EDGE, ///< Edge router. No transit-router capability.
QD_ROUTER_MODE_ENDPOINT ///< No routing except for internal modules (agent, etc.).
} qd_router_mode_t;
+ENUM_DECLARE(qd_router_mode);
typedef enum {
QD_LINK_ENDPOINT, ///< A link to a connected endpoint
@@ -55,7 +57,7 @@ typedef enum {
QD_LINK_ROUTER, ///< A link to a peer router in the same area
QD_LINK_AREA ///< A link to a peer router in a different area (area boundary)
} qd_link_type_t;
-
+ENUM_DECLARE(qd_link_type);
typedef struct qd_routed_event_t {
DEQ_LINKS(struct qd_routed_event_t);
Modified: qpid/dispatch/trunk/src/router_pynode.c
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/router_pynode.c?rev=1632696&r1=1632695&r2=1632696&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/router_pynode.c (original)
+++ qpid/dispatch/trunk/src/router_pynode.c Fri Oct 17 23:35:35 2014
@@ -26,6 +26,7 @@
#include "dispatch_private.h"
#include "router_private.h"
#include "waypoint_private.h"
+#include "c_entity.h"
static qd_address_semantics_t router_addr_semantics = QD_FANOUT_SINGLE | QD_BIAS_CLOSEST | QD_CONGESTION_DROP | QD_DROP_FOR_SLOW_CONSUMERS | QD_BYPASS_VALID_ORIGINS;
@@ -81,6 +82,7 @@ static char *qd_add_router(qd_router_t *
addr->semantics = router_addr_semantics;
qd_hash_insert(router->addr_hash, iter, addr, &addr->hash_handle);
DEQ_INSERT_TAIL(router->addrs, addr);
+ qd_c_entity_add(QD_ROUTER_ADDRESS_TYPE, addr);
qd_field_iterator_free(iter);
//
@@ -96,6 +98,7 @@ static char *qd_add_router(qd_router_t *
rnode->valid_origins = qd_bitmask(0);
DEQ_INSERT_TAIL(router->routers, rnode);
+ qd_c_entity_add(QD_ROUTER_NODE_TYPE, rnode);
//
// Link the router record to the address record.
@@ -139,6 +142,9 @@ static char *qd_del_router(qd_router_t *
qd_address_t *oaddr = rnode->owning_addr;
assert(oaddr);
+ qd_c_entity_remove(QD_ROUTER_ADDRESS_TYPE, oaddr);
+ qd_c_entity_remove(QD_ROUTER_NODE_TYPE, rnode);
+
//
// Unlink the router node from the address record
//
@@ -387,6 +393,7 @@ static PyObject* qd_map_destination(PyOb
addr->semantics = router_semantics_for_addr(router, iter, phase, &unused);
DEQ_ITEM_INIT(addr);
DEQ_INSERT_TAIL(router->addrs, addr);
+ qd_c_entity_add(QD_ROUTER_ADDRESS_TYPE, addr);
}
qd_field_iterator_free(iter);
Modified: qpid/dispatch/trunk/src/server.c
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/server.c?rev=1632696&r1=1632695&r2=1632696&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/server.c (original)
+++ qpid/dispatch/trunk/src/server.c Fri Oct 17 23:35:35 2014
@@ -21,6 +21,8 @@
#include <qpid/dispatch/threading.h>
#include <qpid/dispatch/log.h>
#include <qpid/dispatch/amqp.h>
+#include "entity_private.h"
+#include "c_entity.h"
#include "dispatch_private.h"
#include "server_private.h"
#include "timer_private.h"
@@ -37,6 +39,14 @@ ALLOC_DEFINE(qd_connector_t);
ALLOC_DEFINE(qd_connection_t);
ALLOC_DEFINE(qd_user_fd_t);
+static const char *conn_state_names[] = {
+ "connecting",
+ "opening",
+ "operational",
+ "failed",
+ "user"
+};
+ENUM_DEFINE(conn_state, conn_state_names);
static qd_thread_t *thread(qd_server_t *qd_server, int id)
{
@@ -53,6 +63,44 @@ static qd_thread_t *thread(qd_server_t *
return thread;
}
+qd_error_t qd_entity_update_connection(qd_entity_t* entity, void *impl);
+
+static qd_error_t connection_entity_update_host(qd_entity_t* entity, qd_connection_t *conn)
+{
+ const qd_server_config_t *config;
+ if (conn->connector) {
+ config = conn->connector->config;
+ char host[strlen(config->host)+strlen(config->port)+2];
+ snprintf(host, sizeof(host), "%s:%s", config->host, config->port);
+ return qd_entity_set_string(entity, "host", host);
+ }
+ else
+ return qd_entity_set_string(entity, "host", pn_connector_name(conn->pn_cxtr));
+}
+
+qd_error_t qd_c_entity_update_connection(qd_entity_t* entity, void *impl)
+{
+ qd_connection_t *conn = (qd_connection_t*)impl;
+ const qd_server_config_t *config =
+ conn->connector ? conn->connector->config : conn->listener->config;
+
+ if ((qd_entity_has(entity, "identity") ||
+ qd_entity_set_string(entity, "identity", pn_connector_name(conn->pn_cxtr)) == 0) &&
+ qd_entity_set_string(entity, "state", conn_state_name(conn->state)) == 0 &&
+ qd_entity_set_string(
+ entity, "container",
+ conn->pn_conn ? pn_connection_remote_container(conn->pn_conn) : 0) == 0 &&
+ connection_entity_update_host(entity, conn) == 0 &&
+ /* FIXME aconway 2014-10-14: change attr name to sasl-mechanisms for consistency? */
+ qd_entity_set_string(entity, "sasl", config->sasl_mechanisms) == 0 &&
+ qd_entity_set_string(entity, "role", config->role) == 0 &&
+ qd_entity_set_string(entity, "dir", conn->connector ? "out" : "in") == 0)
+ return QD_ERROR_NONE;
+ return qd_error_code();
+}
+
+
+
static void thread_process_listeners(qd_server_t *qd_server)
{
@@ -93,6 +141,7 @@ static void thread_process_listeners(qd_
// qd_server->lock is already locked
DEQ_INSERT_TAIL(qd_server->connections, ctx);
+ qd_c_entity_add(QD_CONNECTION_TYPE, ctx);
//
// Get a pointer to the transport so we can insert security components into it
@@ -492,6 +541,7 @@ static void *thread_run(void *arg)
// Check to see if the connector was closed during processing
//
if (pn_connector_closed(cxtr)) {
+ qd_c_entity_remove(QD_CONNECTION_TYPE, ctx);
//
// Connector is closed. Free the context and the connector.
//
@@ -508,6 +558,7 @@ static void *thread_run(void *arg)
sys_mutex_lock(qd_server->lock);
DEQ_REMOVE(qd_server->connections, ctx);
+
pn_connector_free(cxtr);
if (conn)
pn_connection_free(conn);
@@ -607,6 +658,8 @@ static void cxtr_try_open(void *context)
sys_mutex_lock(ct->server->lock);
ctx->pn_cxtr = pn_connector(ct->server->driver, ct->config->host, ct->config->port, (void*) ctx);
DEQ_INSERT_TAIL(ct->server->connections, ctx);
+ qd_c_entity_add(QD_CONNECTION_TYPE, ctx);
+
sys_mutex_unlock(ct->server->lock);
ct->ctx = ctx;
@@ -658,7 +711,7 @@ static void cxtr_try_open(void *context)
}
-qd_server_t *qd_server(int thread_count, const char *container_name)
+qd_server_t *qd_server(qd_dispatch_t *qd, int thread_count, const char *container_name)
{
int i;
@@ -667,6 +720,7 @@ qd_server_t *qd_server(int thread_count,
return 0;
DEQ_INIT(qd_server->connections);
+ qd_server->qd = qd;
qd_server->log_source = qd_log_source("SERVER");
qd_server->thread_count = thread_count;
qd_server->container_name = container_name;
Modified: qpid/dispatch/trunk/src/server_private.h
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/server_private.h?rev=1632696&r1=1632695&r2=1632696&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/server_private.h (original)
+++ qpid/dispatch/trunk/src/server_private.h Fri Oct 17 23:35:35 2014
@@ -19,6 +19,7 @@
* under the License.
*/
+#include <qpid/dispatch/enum.h>
#include <qpid/dispatch/server.h>
#include <qpid/dispatch/user_fd.h>
#include <qpid/dispatch/alloc.h>
@@ -43,6 +44,7 @@ typedef enum {
CONN_STATE_FAILED,
CONN_STATE_USER
} conn_state_t;
+ENUM_DECLARE(conn_state);
#define CONTEXT_NO_OWNER -1
@@ -127,6 +129,7 @@ DEQ_DECLARE(qd_work_item_t, qd_work_list
struct qd_server_t {
+ qd_dispatch_t *qd;
int thread_count;
const char *container_name;
pn_driver_t *driver;
Modified: qpid/dispatch/trunk/src/waypoint.c
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/waypoint.c?rev=1632696&r1=1632695&r2=1632696&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/waypoint.c (original)
+++ qpid/dispatch/trunk/src/waypoint.c Fri Oct 17 23:35:35 2014
@@ -20,6 +20,7 @@
#include "waypoint_private.h"
#include "dispatch_private.h"
#include "router_private.h"
+#include "c_entity.h"
#include <qpid/dispatch/ctools.h>
#include <qpid/dispatch/threading.h>
#include <qpid/dispatch/connection_manager.h>
@@ -68,6 +69,7 @@ static void qd_waypoint_visit_sink_LH(qd
DEQ_INSERT_TAIL(router->addrs, addr);
addr->waypoint = true;
addr->semantics = router_semantics_for_addr(router, iter, wp->in_phase, &unused);
+ qd_c_entity_add(QD_ROUTER_ADDRESS_TYPE, addr);
}
wp->in_address = addr;
@@ -97,6 +99,7 @@ static void qd_waypoint_visit_sink_LH(qd
rlink->target = 0;
DEQ_INIT(rlink->event_fifo);
DEQ_INIT(rlink->msg_fifo);
+ qd_c_entity_add(QD_ROUTER_LINK_TYPE, rlink);
DEQ_INSERT_TAIL(router->links, rlink);
qd_link_set_context(wp->out_link, rlink);
qd_router_add_link_ref_LH(&addr->rlinks, rlink);
@@ -141,6 +144,7 @@ static void qd_waypoint_visit_source_LH(
DEQ_INSERT_TAIL(router->addrs, addr);
addr->waypoint = true;
addr->semantics = router_semantics_for_addr(router, iter, wp->out_phase, &unused);
+ qd_c_entity_add(QD_ROUTER_ADDRESS_TYPE, addr);
}
wp->out_address = addr;
@@ -170,6 +174,7 @@ static void qd_waypoint_visit_source_LH(
rlink->target = 0;
DEQ_INIT(rlink->event_fifo);
DEQ_INIT(rlink->msg_fifo);
+ qd_c_entity_add(QD_ROUTER_LINK_TYPE, rlink);
DEQ_INSERT_TAIL(router->links, rlink);
qd_link_set_context(wp->in_link, rlink);
Modified: qpid/dispatch/trunk/tests/management/client.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/tests/management/client.py?rev=1632696&r1=1632695&r2=1632696&view=diff
==============================================================================
--- qpid/dispatch/trunk/tests/management/client.py (original)
+++ qpid/dispatch/trunk/tests/management/client.py Fri Oct 17 23:35:35 2014
@@ -25,10 +25,10 @@ from qpid_dispatch.management import Url
class UrlTest(unittest.TestCase):
def test_url(self):
- url = Url(scheme='amqp', user='me', password='secret', host='myhost', port=1234, path='foobar')
+ url = Url(scheme='amqp', username='me', password='secret', host='myhost', port=1234, path='foobar')
self.assertEqual(str(url), "amqp://me:secret@myhost:1234/foobar")
self.assertEqual(
- [url.scheme, url.user, url.password, url.host, url.port, url.path],
+ [url.scheme, url.username, url.password, url.host, url.port, url.path],
['amqp', 'me', 'secret', 'myhost', 1234, 'foobar']
)
@@ -42,22 +42,13 @@ class UrlTest(unittest.TestCase):
self.assertNotEqual(str(url), "amqp://me:secret@myhost:5555/foobar")
# Check that we allow None for scheme, port
- url = Url(user='me', password='secret', host='myhost', path='foobar')
+ url = Url(username='me', password='secret', host='myhost', path='foobar')
self.assertEqual(str(url), "me:secret@myhost/foobar")
self.assertEqual(
- [url.scheme, url.user, url.password, url.host, url.port, url.path],
+ [url.scheme, url.username, url.password, url.host, url.port, url.path],
[None, 'me', 'secret', 'myhost', None, 'foobar']
)
- # Scheme defaults
- self.assertEqual(str(Url("me:secret@myhost/foobar").defaults()),
- "amqp://me:secret@myhost:5672/foobar")
- # Correct port for amqps vs. amqps
- self.assertEqual(str(Url("amqps://me:secret@myhost/foobar").defaults()),
- "amqps://me:secret@myhost:5671/foobar")
- self.assertEqual(str(Url("amqp://me:secret@myhost/foobar").defaults()),
- "amqp://me:secret@myhost:5672/foobar")
-
# Empty string for path
self.assertEqual(Url("myhost/").path, "")
self.assertIsNone(Url("myhost").path)
Modified: qpid/dispatch/trunk/tests/management/qdrouter.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/tests/management/qdrouter.py?rev=1632696&r1=1632695&r2=1632696&view=diff
==============================================================================
--- qpid/dispatch/trunk/tests/management/qdrouter.py (original)
+++ qpid/dispatch/trunk/tests/management/qdrouter.py Fri Oct 17 23:35:35 2014
@@ -73,21 +73,21 @@ listener {
content = conf._default_ids(content)
self.assertEqual(content, [
- ["router", {"mode":"standalone", "name":"router0", "identity":"router0"}],
+ ["router", {"mode":"standalone", "name":"router:0", "identity":"router:0"}],
["listener", {"name":"l0", "identity":"l0", "sasl-mechanisms":"ANONYMOUS", "password":"secret"}],
["listener", {"name":"l1", "identity":"l1", "sasl-mechanisms":"ANONYMOUS", "port":"1234"}],
- ["listener", {"name":"listener2", "identity":"listener2", "sasl-mechanisms":"ANONYMOUS", "port":"4567"}]
+ ["listener", {"name":"listener:2", "identity":"listener:2", "sasl-mechanisms":"ANONYMOUS", "port":"4567"}]
])
conf.load(conf_text.split("\n"))
router = conf.by_type('router').next()
- self.assertEqual(router['name'], 'router0')
- self.assertEqual(router['identity'], 'router0')
+ self.assertEqual(router['name'], 'router:0')
+ self.assertEqual(router['identity'], 'router:0')
listeners = list(conf.by_type('listener'))
self.assertEqual(len(listeners), 3)
self.assertEqual(listeners[0]['name'], 'l0')
- self.assertEqual(listeners[2]['name'], 'listener2')
- self.assertEqual(listeners[2]['identity'], 'listener2')
+ self.assertEqual(listeners[2]['name'], 'listener:2')
+ self.assertEqual(listeners[2]['identity'], 'listener:2')
if __name__ == '__main__':
unittest.main()
Modified: qpid/dispatch/trunk/tests/management/schema.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/tests/management/schema.py?rev=1632696&r1=1632695&r2=1632696&view=diff
==============================================================================
--- qpid/dispatch/trunk/tests/management/schema.py (original)
+++ qpid/dispatch/trunk/tests/management/schema.py Fri Oct 17 23:35:35 2014
@@ -21,7 +21,7 @@
#pylint: disable=wildcard-import,missing-docstring,too-many-public-methods
import unittest, json
-from qpid_dispatch_internal.management.schema import Schema, BooleanType, EnumType, AttributeType, schema_file, ValidationError, EnumValue, EntityType
+from qpid_dispatch_internal.management.schema import Schema, BooleanType, EnumType, AttributeType, ValidationError, EnumValue, EntityType
import collections
def replace_od(thing):
@@ -152,14 +152,6 @@ class SchemaTest(unittest.TestCase):
self.assertEqual({'identity': 'x', 'name': 'y'}, e.validate({'identity': 'x', 'name':'y'}))
self.assertRaises(ValidationError, e.validate, {})
- qdrouter_json = schema_file('qdrouter.json')
-
- @staticmethod
- def load_schema(fname=qdrouter_json):
- with open(fname) as f:
- j = json.load(f)
- return Schema(**j)
-
def test_schema_dump(self):
s = Schema(**SCHEMA_1)
self.maxDiff = None # pylint: disable=invalid-name
Modified: qpid/dispatch/trunk/tests/run.py.in
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/tests/run.py.in?rev=1632696&r1=1632695&r2=1632696&view=diff
==============================================================================
--- qpid/dispatch/trunk/tests/run.py.in (original)
+++ qpid/dispatch/trunk/tests/run.py.in Fri Oct 17 23:35:35 2014
@@ -99,7 +99,7 @@ def is_binary_exe(program):
p = Popen(['file', '-bi', program], stdout=PIPE, stderr=PIPE)
return p.communicate()[0].startswith('application/x-executable')
-def with_valgrind(args):
+def with_valgrind(args, outfile=None):
if use_valgrind() and is_binary_exe(find_exe(args[0])):
opts = ['--leak-check=full',
'--demangle=yes',
@@ -107,6 +107,7 @@ def with_valgrind(args):
'--num-callers=12',
'--error-exitcode=42',
'--quiet']
+ if outfile: opts.append('--log-file=%s' % outfile)
return [valgrind_exe]+opts+args
return args
Modified: qpid/dispatch/trunk/tests/system_test.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/tests/system_test.py?rev=1632696&r1=1632695&r2=1632696&view=diff
==============================================================================
--- qpid/dispatch/trunk/tests/system_test.py (original)
+++ qpid/dispatch/trunk/tests/system_test.py Fri Oct 17 23:35:35 2014
@@ -208,7 +208,7 @@ class Process(subprocess.Popen):
@classmethod
def unique(cls, name):
cls.unique_id += 1
- return name + str(cls.unique_id)
+ return "%s-%s" % (name, cls.unique_id)
def __init__(self, args, name=None, expect=EXIT_OK, **kwargs):
"""
@@ -228,7 +228,7 @@ class Process(subprocess.Popen):
self.torndown = False
kwargs.setdefault('stdout', self.out)
kwargs.setdefault('stderr', subprocess.STDOUT)
- args = with_valgrind(args)
+ args = with_valgrind(args, self.outfile + '.vg')
try:
super(Process, self).__init__(args, **kwargs)
except Exception, e:
@@ -376,10 +376,11 @@ class Qdrouterd(Process):
"""
def check():
# FIXME aconway 2014-06-12: this should be a request by name, not a query.
+ # Need to rationalize addresses in management attributes.
+ # endswith check is because of M0/L/R prefixes
addrs = self.management.query(
type='org.apache.qpid.dispatch.router.address',
attribute_names=['name', 'subscriberCount', 'remoteCount']).get_entities()
- # FIXME aconway 2014-06-12: endswith check is because of M0/L prefixes
addrs = [a for a in addrs if a['name'].endswith(address)]
return addrs and addrs[0]['subscriberCount'] >= subscribers and addrs[0]['remoteCount'] >= remotes
assert retry(check, **retry_kwargs)
@@ -398,6 +399,12 @@ class Qdrouterd(Process):
wait_ports(self.ports)
self.wait_connectors()
+ def wait_connected(self, router_id):
+ """Wait till this router is connected to router with router-id"""
+ node = Node(self.addresses[0], router_id, timeout=0.2)
+ retry_exception(lambda: node.query('org.apache.qpid.dispatch.router'))
+
+
class Qpidd(Process):
"""Run a Qpid Daemon"""
Modified: qpid/dispatch/trunk/tests/system_tests_management.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/tests/system_tests_management.py?rev=1632696&r1=1632695&r2=1632696&view=diff
==============================================================================
--- qpid/dispatch/trunk/tests/system_tests_management.py (original)
+++ qpid/dispatch/trunk/tests/system_tests_management.py Fri Oct 17 23:35:35 2014
@@ -23,19 +23,24 @@ import unittest, system_test, re, os
from qpid_dispatch.management import Node, ManagementError, Url, BadRequestStatus, NotImplementedStatus, NotFoundStatus, ForbiddenStatus
from system_test import Qdrouterd, message, retry
-LISTENER = 'org.apache.qpid.dispatch.listener'
-CONNECTOR = 'org.apache.qpid.dispatch.connector'
-FIXED_ADDRESS = 'org.apache.qpid.dispatch.fixed-address'
-WAYPOINT = 'org.apache.qpid.dispatch.waypoint'
-DUMMY = 'org.apache.qpid.dispatch.dummy'
+DISPATCH = 'org.apache.qpid.dispatch'
+LISTENER = DISPATCH + '.listener'
+CONNECTOR = DISPATCH + '.connector'
+FIXED_ADDRESS = DISPATCH + '.fixed-address'
+WAYPOINT = DISPATCH + '.waypoint'
+DUMMY = DISPATCH + '.dummy'
+ROUTER = DISPATCH + '.router'
+LINK = ROUTER + '.link'
+ADDRESS = ROUTER + '.address'
+NODE = ROUTER + '.node'
-ADDRESS = 'org.apache.qpid.dispatch.router.address'
class ManagementTest(system_test.TestCase): # pylint: disable=too-many-public-methods
@classmethod
def setUpClass(cls):
super(ManagementTest, cls).setUpClass()
+ # Stand-alone router
name = cls.__name__
cls.log_file = name+".log"
conf = Qdrouterd.Config([
@@ -52,8 +57,6 @@ class ManagementTest(system_test.TestCas
def setUp(self):
super(ManagementTest, self).setUp()
self.node = self.cleanup(Node(self.router.addresses[0]))
- # Temporary access to separate new management address.
- self.node2 = self.cleanup(Node(Url(self.router.addresses[0], path='$management2')))
self.maxDiff = None
self.longMessage = True
@@ -61,14 +64,12 @@ class ManagementTest(system_test.TestCas
"""Test that various badly formed queries get the proper response"""
# No operation attribute
self.assertRaises(BadRequestStatus, self.node.call, self.node.request())
- # Unknown operation
- self.assertRaises(NotImplementedStatus, self.node.call, self.node.request(operation="nosuch"))
- # No entityType or attributeList
- self.assertRaises(BadRequestStatus, self.node.query)
+ self.assertRaises(NotImplementedStatus, self.node.call,
+ self.node.request(operation="nosuch", type="org.amqp.management"))
def test_query_type(self):
"""Query with type only"""
- response = self.node2.query(type=LISTENER)
+ response = self.node.query(type=LISTENER)
for attr in ['type', 'name', 'identity', 'addr', 'port']:
self.assertTrue(attr in response.attribute_names)
for r in response.get_dicts():
@@ -80,7 +81,7 @@ class ManagementTest(system_test.TestCas
def test_query_type_attributes(self):
"""Query with type and attribute names"""
attribute_names=['type', 'name', 'port']
- response = self.node2.query(type=LISTENER, attribute_names=attribute_names)
+ response = self.node.query(type=LISTENER, attribute_names=attribute_names)
self.assertEqual(attribute_names, response.attribute_names)
expect = [[LISTENER, 'l%s' % i, str(self.router.ports[i])] for i in xrange(3)]
for r in expect: # We might have extras in results due to create tests
@@ -90,12 +91,12 @@ class ManagementTest(system_test.TestCas
def test_query_attributes(self):
"""Query with attributes only"""
attribute_names=['type', 'name', 'port']
- response = self.node2.query(attribute_names=attribute_names)
+ response = self.node.query(attribute_names=attribute_names)
self.assertEqual(attribute_names, response.attribute_names)
expect = [[LISTENER, 'l%s' % i, str(self.router.ports[i])] for i in xrange(3)]
for r in expect: # We might have extras in results due to create tests
self.assertTrue(r in response.results)
- for name in ['router0', 'log0']:
+ for name in [self.router.name, 'log:0']:
self.assertTrue([r for r in response.get_dicts() if r['name'] == name],
msg="Can't find result with name '%s'" % name)
@@ -105,7 +106,7 @@ class ManagementTest(system_test.TestCas
assert not missing, "Not a subset, missing %s, sub=%s, super=%s"%(missing, small, big)
def assert_create_ok(self, type, name, attributes):
- entity = self.node2.create(attributes, type, name)
+ entity = self.node.create(attributes, type, name)
self.assertMapSubset(attributes, entity.attributes)
return entity
@@ -120,20 +121,16 @@ class ManagementTest(system_test.TestCas
self.assertEqual(entity['addr'], '0.0.0.0')
# Connect via the new listener
- node3 = self.cleanup(Node(Url(port=port, path='$management')))
- router = node3.query(type='org.apache.qpid.dispatch.router').get_entities()
+ node3 = self.cleanup(Node(Url(port=port)))
+ router = node3.query(type=ROUTER).get_entities()
self.assertEqual(self.__class__.router.name, router[0]['name'])
def test_create_log(self):
"""Create a log entity"""
- # FIXME aconway 2014-07-04: rework log entity.
- # - allow auto-assigned name/identity? Use module as name/identity?
- # - 1 entity with full log state, allow updates.
log = os.path.abspath("test_create_log.log")
- # FIXME aconway 2014-09-08: PYAGENT->AGENT
- self.assert_create_ok('log', 'log.1', dict(module='PYAGENT', level="error", output=log))
+ self.assert_create_ok('log', 'log.1', dict(module='AGENT', level="error", output=log))
# Cause an error and verify it shows up in the log file.
- self.assertRaises(ManagementError, self.node2.create, type='nosuch', name='nosuch')
+ self.assertRaises(ManagementError, self.node.create, type='nosuch', name='nosuch')
f = self.cleanup(open(log))
logstr = f.read()
self.assertTrue(re.search(r'ValidationError.*nosuch', logstr),
@@ -191,21 +188,21 @@ class ManagementTest(system_test.TestCas
f.close()
def test_entity(self):
- entity = self.node2.read(type=LISTENER, name='l0')
+ entity = self.node.read(type=LISTENER, name='l0')
self.assertEqual('l0', entity.name)
self.assertEqual('l0', entity.identity)
self.assertEqual(str(self.router.ports[0]), entity.port)
- entity = self.node2.read(type=LISTENER, identity='l1')
+ entity = self.node.read(type=LISTENER, identity='l1')
self.assertEqual('l1', entity.name)
self.assertEqual('l1', entity.identity)
self.assertEqual(str(self.router.ports[1]), entity.port)
# Bad type
- self.assertRaises(NotFoundStatus, self.node2.read, type=CONNECTOR, name='l0')
+ self.assertRaises(NotFoundStatus, self.node.read, type=CONNECTOR, name='l0')
# Unknown entity
- self.assertRaises(NotFoundStatus, self.node2.read, type=LISTENER, name='nosuch')
+ self.assertRaises(NotFoundStatus, self.node.read, type=LISTENER, name='nosuch')
# Update and delete are not allowed by the schema
self.assertRaises(ForbiddenStatus, entity.update)
@@ -215,7 +212,7 @@ class ManagementTest(system_test.TestCas
self.assertRaises(ForbiddenStatus, entity.call, 'nosuchop', foo="bar")
# Dummy entity supports all CRUD operations
- dummy = self.node2.create({'arg1': 'START'}, type=DUMMY, name='MyDummy', )
+ dummy = self.node.create({'arg1': 'START'}, type=DUMMY, name='MyDummy', )
self.assertEqual(dummy.type, DUMMY)
self.assertEqual(dummy.name, 'MyDummy')
self.assertEqual(dummy.arg1, 'START')
@@ -237,7 +234,7 @@ class ManagementTest(system_test.TestCas
dict(type=DUMMY, name='MyDummy', identity=identity, arg1='one', num1=42),
dummy.attributes)
- dummy2 = self.node2.read(type=DUMMY, name='MyDummy')
+ dummy2 = self.node.read(type=DUMMY, name='MyDummy')
self.assertEqual(dummy.attributes, dummy2.attributes)
self.assertEqual({'operation': 'callme', 'foo': 'bar', 'type': DUMMY, 'identity': identity},
@@ -247,19 +244,87 @@ class ManagementTest(system_test.TestCas
self.assertRaises(BadRequestStatus, dummy.update)
dummy.delete()
- self.assertRaises(NotFoundStatus, self.node2.read, type=DUMMY, name='MyDummy')
+ self.assertRaises(NotFoundStatus, self.node.read, type=DUMMY, name='MyDummy')
+
+ def test_link(self):
+ """Verify we can find our own reply-to address in links"""
+ response = self.node.query(type=LINK)
+ path = self.node.reply_to.split('/')[-1]
+ mylink = [l for l in response.get_dicts()
+ if l['owningAddr'] and l['owningAddr'].endswith(path)]
+ self.assertTrue(mylink)
+
+ def test_connection(self):
+ """Verify there is at least one connection"""
+ response = self.node.query(type='connection')
+ self.assertTrue(response.get_dicts())
+
+ def test_router(self):
+ """Verify router counts match entity counts"""
+ entities = self.node.query().get_entities()
+ routers = [e for e in entities if e.type == ROUTER]
+ self.assertEqual(1, len(routers))
+ router = routers[0]
+ self.assertEqual(router.linkCount, len([e for e in entities if e.type == LINK]))
+ self.assertEqual(router.addrCount, len([e for e in entities if e.type == ADDRESS]))
+
+ def test_router_node(self):
+ """Test node entity in a pair of linked routers"""
+ # Pair of linked interior routers
+ conf1 = Qdrouterd.Config([
+ ('log', {'module':'DEFAULT', 'level':'trace', 'output':'router1.log'}),
+ ('router', { 'mode': 'interior', 'router-id': 'router1'}),
+ ('listener', {'port':self.get_port(), 'role':'normal'}),
+ ('listener', {'port':self.get_port(), 'role':'inter-router'})
+ ])
+ conf2 = Qdrouterd.Config([
+ ('log', {'module':'DEFAULT', 'level':'trace', 'output':'router2.log'}),
+ ('router', { 'mode': 'interior', 'router-id': 'router2'}),
+ ('listener', {'port':self.get_port(), 'role':'normal'}),
+ ('connector', {'port':conf1.sections('listener')[1]['port'], 'role':'inter-router'})
+ ])
+ routers = [self.qdrouterd('router1', conf1, wait=False),
+ self.qdrouterd('router2', conf2, wait=False)]
+ for r in routers: r.wait_ready()
+ routers[0].wait_connected('router2')
+ routers[1].wait_connected('router1')
+
+ nodes = [self.cleanup(Node(Url(r.addresses[0]))) for r in routers]
+
+ class RNodes(list):
+ def __call__(self):
+ self[:] = sum([n.query(type=NODE).get_entities() for n in nodes], [])
+ return self
+ rnodes = RNodes()
+
+ assert retry(lambda: len(rnodes()) >= 2)
+ self.assertEqual(['Rrouter2', 'Rrouter1'], [r.addr for r in rnodes])
+ # FIXME aconway 2014-10-15: verify nextHop and validOrigins updated correctly
+ self.assertEqual([u'amqp:/_topo/0/router2/$management', u'amqp:/_topo/0/router1/$management'],
+ sum([n.get_mgmt_nodes() for n in nodes], []))
- def test_get_types(self):
- self.assertRaises(NotImplementedStatus, self.node2.get_types)
- def test_get_attributes(self):
- self.assertRaises(NotImplementedStatus, self.node2.get_attributes)
+
+ def test_get_types(self):
+ types = self.node.get_types()
+ self.assertIn('org.apache.qpid.dispatch.listener', types)
+ self.assertIn('org.apache.qpid.dispatch.waypoint', types)
+ self.assertIn('org.apache.qpid.dispatch.router.link', types)
def test_get_operations(self):
- self.assertRaises(NotImplementedStatus, self.node2.get_operations)
+ result = self.node.get_operations(type=DUMMY)
+ self.assertEqual({DUMMY: ["CREATE", "READ", "UPDATE", "DELETE", "CALLME"]}, result)
+ result = self.node.get_operations()
+ for type in LISTENER, WAYPOINT, LINK: self.assertIn(type, result)
+ self.assertEqual(["READ"], result[LINK])
+ self.assertEqual(["CREATE", "READ"], result[WAYPOINT])
- def test_get_mgmt_nodes(self):
- self.assertRaises(NotImplementedStatus, self.node2.get_mgmt_nodes)
+ def test_get_attributes(self):
+ result = self.node.get_attributes(type=DUMMY)
+ self.assertEqual({DUMMY: [u'arg1', u'arg2', u'num1', u'num2', u'name', u'identity', u'type']}, result)
+ result = self.node.get_attributes()
+ for type in LISTENER, WAYPOINT, LINK: self.assertIn(type, result)
+ for a in ['linkType', 'linkDir', 'owningAddr']: self.assertIn(a, result[LINK])
if __name__ == '__main__':
unittest.main()
Modified: qpid/dispatch/trunk/tests/system_tests_one_router.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/tests/system_tests_one_router.py?rev=1632696&r1=1632695&r2=1632696&view=diff
==============================================================================
--- qpid/dispatch/trunk/tests/system_tests_one_router.py (original)
+++ qpid/dispatch/trunk/tests/system_tests_one_router.py Fri Oct 17 23:35:35 2014
@@ -546,7 +546,7 @@ class RouterTest(TestCase):
M.recv()
M.get(response)
- self.assertEqual(response.properties['statusCode'], 200)
+ assert response.properties['statusCode'] == 200, response.properties['statusDescription']
self.assertEqual(response.correlation_id, "C1")
self.assertEqual(response.body, [])
@@ -578,156 +578,6 @@ class RouterTest(TestCase):
M.stop()
- def test_09a_management_get_types(self):
- addr = "amqp:/_local/$management"
-
- M = Messenger()
- M.timeout = 2.0
- M.start()
- M.route("amqp:/*", self.address+"/$1")
- sub = M.subscribe("amqp:/#")
- reply = sub.address
-
- request = Message()
- response = Message()
-
- ##
- ## Unrestricted request
- ##
- request.address = addr
- request.reply_to = reply
- request.properties = {u'type':u'org.amqp.management', u'name':u'self', u'operation':u'GET-TYPES'}
-
- M.put(request)
- M.send()
- M.recv()
- M.get(response)
-
- self.assertEqual(response.properties['statusCode'], 200)
- self.assertEqual(response.body.__class__, dict)
- self.assertTrue('org.apache.qpid.dispatch.router' in response.body.keys())
- self.assertTrue(len(response.body.keys()) > 2)
-
- ##
- ## Restricted Request one match
- ##
- request.address = addr
- request.reply_to = reply
- request.properties = {u'type':u'org.amqp.management', u'name':u'self', u'operation':u'GET-TYPES',
- u'entityType':'org.apache.qpid.dispatch.connection'}
-
- M.put(request)
- M.send()
- M.recv()
- M.get(response)
-
- self.assertEqual(response.properties['statusCode'], 200)
- self.assertEqual(response.body.__class__, dict)
- self.assertTrue('org.apache.qpid.dispatch.connection' in response.body.keys())
- self.assertEqual(len(response.body.keys()), 1)
-
- ##
- ## Restricted Request with no matches
- ##
- request.address = addr
- request.reply_to = reply
- request.properties = {u'type':u'org.amqp.management', u'name':u'self', u'operation':u'GET-TYPES',
- u'entityType':'com.profitron.item'}
-
- M.put(request)
- M.send()
- M.recv()
- M.get(response)
-
- self.assertEqual(response.properties['statusCode'], 200)
- self.assertEqual(response.body, {})
-
- ##
- ## Error Request
- ##
- request.address = addr
- request.reply_to = reply
- request.properties = {u'type':u'org.amqp.management', u'name':u'self', u'operation':u'GET-TYPES',
- u'entityType':['one', 'two']}
-
- M.put(request)
- M.send()
- M.recv()
- M.get(response)
-
- self.assertEqual(response.properties['statusCode'], 400)
-
- M.stop()
-
-
- def test_09b_management_get_attributes(self):
- addr = "amqp:/_local/$management"
-
- M = Messenger()
- M.timeout = 2.0
- M.start()
- M.route("amqp:/*", self.address+"/$1")
- sub = M.subscribe("amqp:/#")
- reply = sub.address
-
- request = Message()
- response = Message()
-
- ##
- ## Unrestricted request
- ##
- request.address = addr
- request.reply_to = reply
- request.properties = {u'type':u'org.amqp.management', u'name':u'self', u'operation':u'GET-ATTRIBUTES'}
-
- M.put(request)
- M.send()
- M.recv()
- M.get(response)
-
- self.assertEqual(response.properties['statusCode'], 200)
- self.assertEqual(response.body.__class__, dict)
- self.assertTrue('org.apache.qpid.dispatch.router' in response.body.keys())
- self.assertTrue(len(response.body.keys()) > 2)
- self.assertTrue(response.body['org.apache.qpid.dispatch.router'].__class__, list)
-
- ##
- ## Restricted Request with a match
- ##
- request.address = addr
- request.reply_to = reply
- request.properties = {u'type':u'org.amqp.management', u'name':u'self', u'operation':u'GET-ATTRIBUTES',
- u'entityType':'org.apache.qpid.dispatch.router'}
-
- M.put(request)
- M.send()
- M.recv()
- M.get(response)
-
- self.assertEqual(response.properties['statusCode'], 200)
- self.assertEqual(response.body.__class__, dict)
- self.assertTrue('org.apache.qpid.dispatch.router' in response.body.keys())
- self.assertEqual(len(response.body.keys()), 1)
- self.assertTrue('mode' in response.body['org.apache.qpid.dispatch.router'])
-
- ##
- ## Restricted Request with no matches
- ##
- request.address = addr
- request.reply_to = reply
- request.properties = {u'type':u'org.amqp.management', u'name':u'self', u'operation':u'GET-ATTRIBUTES',
- u'entityType':'com.profitron.item'}
-
- M.put(request)
- M.send()
- M.recv()
- M.get(response)
-
- self.assertEqual(response.properties['statusCode'], 200)
- self.assertEqual(response.body, {})
-
- M.stop()
-
def test_09c_management_get_operations(self):
addr = "amqp:/_local/$management"
Modified: qpid/dispatch/trunk/tests/system_tests_qdmanage.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/tests/system_tests_qdmanage.py?rev=1632696&r1=1632695&r2=1632696&view=diff
==============================================================================
--- qpid/dispatch/trunk/tests/system_tests_qdmanage.py (original)
+++ qpid/dispatch/trunk/tests/system_tests_qdmanage.py Fri Oct 17 23:35:35 2014
@@ -20,7 +20,7 @@
import re, json, unittest
from system_test import TestCase, Process, Qdrouterd
from subprocess import PIPE, STDOUT
-from copy import copy
+
DUMMY = "org.apache.qpid.dispatch.dummy"
@@ -33,28 +33,26 @@ class QdmanageTest(TestCase):
config = Qdrouterd.Config([
('listener', {'port': cls.tester.get_port()})
])
- cls.router = cls.tester.qdrouterd('test-router', config)
+ cls.router = cls.tester.qdrouterd('test-router', config, wait=True)
def run_qdmanage(self, cmd, input=None, expect=Process.EXIT_OK, **kwargs):
args = filter(None, sum([["--%s" % k.replace('_','-'), v]
for k, v in kwargs.iteritems()], []))
p = self.popen(
- ['qdmanage', cmd, '--bus', self.router.hostports[0]+"/$management2",
- '--indent=-1']+args,
+ ['qdmanage', cmd, '--bus', self.router.hostports[0], '--indent=-1']+args,
stdin=PIPE, stdout=PIPE, stderr=STDOUT, expect=expect)
out = p.communicate(input)[0]
- if expect == Process.EXIT_OK:
- assert p.returncode == 0, "%s exit %s, output:\n%s" % (p.args, p.returncode, out)
- else:
- assert p.returncode != 0, "%s expected to fail but exit 0" %(p.args)
+ try:
+ p.teardown()
+ except Exception, e:
+ raise Exception("%s\n%s" % (e, out))
return out
def test_help(self):
self.run_qdmanage('help', r'Usage: qdmanage', expect=Process.EXIT_FAIL)
for cmd in ['create', 'read', 'update', 'delete', 'query']:
out = self.run_qdmanage(cmd, help=None)
- assert re.search('Usage: %s \[options\]' % cmd, out, re.I), \
- "Can't find '%s' in '%s'" % (regexp, out)
+ assert re.search('Usage: %s \[options\]' % cmd, out, re.I)
def assert_entity_equal(self, expect, actual, copy=None):
"""Copy keys in copy from actual to idenity, then assert maps equal."""
@@ -119,11 +117,12 @@ class QdmanageTest(TestCase):
def test_query(self):
def long_type(name): return u'org.apache.qpid.dispatch.'+name
- TYPES=['listener', 'log', 'container', 'router']
+ TYPES=['listener', 'log', 'container', 'router', 'router.link']
LONG_TYPES=[long_type(name) for name in TYPES]
qall = json.loads(self.run_qdmanage('query'))
- self.assertTrue(set(LONG_TYPES) <= set([e['type'] for e in qall]))
+ qall_types = set([e['type'] for e in qall])
+ for t in LONG_TYPES: self.assertIn(t, qall_types)
qlistener = json.loads(self.run_qdmanage('query', type='listener'))
self.assertEqual([long_type('listener')], [e['type'] for e in qlistener])
@@ -132,10 +131,12 @@ class QdmanageTest(TestCase):
qattr = json.loads(
self.run_qdmanage('query', attribute_names='["type", "name"]'))
for e in qattr: self.assertEqual(2, len(e))
- self.assertEqual(
- set([(e['name'], e['type']) for e in qall]),
- set([(e['name'], e['type']) for e in qattr]))
+ def name_type(entities):
+ ignore_types = [long_type(t) for t in ['router.link', 'connection', 'router.address']]
+ return set((e['name'], e['type']) for e in entities
+ if e['type'] not in ignore_types)
+ self.assertEqual(name_type(qall), name_type(qattr))
if __name__ == '__main__':
unittest.main()
Modified: qpid/dispatch/trunk/tests/system_tests_two_routers.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/tests/system_tests_two_routers.py?rev=1632696&r1=1632695&r2=1632696&view=diff
==============================================================================
--- qpid/dispatch/trunk/tests/system_tests_two_routers.py (original)
+++ qpid/dispatch/trunk/tests/system_tests_two_routers.py Fri Oct 17 23:35:35 2014
@@ -19,8 +19,8 @@
import unittest, os
from proton import Message, PENDING, ACCEPTED, REJECTED, RELEASED, SSLDomain, SSLUnavailable
-from system_test import TestCase, Qdrouterd, retry_exception
-from qpid_dispatch.management import Node
+from system_test import TestCase, Qdrouterd
+
class RouterTest(TestCase):
@classmethod
@@ -50,12 +50,8 @@ class RouterTest(TestCase):
router('B', 'client',
('connector', {'role': 'inter-router', 'port': cls.routers[0].ports[1]}))
- def query_through(address, router):
- n = Node(address, router, timeout=0.2)
- retry_exception(lambda: n.query('org.apache.qpid.dispatch.router'))
- # Wait till we can query through each router to the other.
- query_through(cls.routers[0].addresses[0], 'QDR.B')
- query_through(cls.routers[1].addresses[0], 'QDR.A')
+ cls.routers[0].wait_connected('QDR.B')
+ cls.routers[1].wait_connected('QDR.A')
def test_00_discard(self):
@@ -474,8 +470,8 @@ class RouterTest(TestCase):
M.recv()
M.get(response)
- self.assertEqual(response.properties['statusCode'], 200)
- self.assertTrue('amqp:/_topo/0/QDR.B/$management' in response.body)
+ assert response.properties['statusCode'] == 200, response.properties['statusDescription']
+ self.assertIn('amqp:/_topo/0/QDR.B/$management', response.body)
request.address = "amqp:/_topo/0/QDR.B/$management"
request.reply_to = reply
Modified: qpid/dispatch/trunk/tools/qdmanage
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/tools/qdmanage?rev=1632696&r1=1632695&r2=1632696&view=diff
==============================================================================
--- qpid/dispatch/trunk/tools/qdmanage (original)
+++ qpid/dispatch/trunk/tools/qdmanage Fri Oct 17 23:35:35 2014
@@ -34,7 +34,9 @@ class QdManage(object):
class Commands(list):
"""Decorator to collect command names."""
- def __call__(self, func): self.append(func.__name__); return func
+ def __call__(self, func):
+ self.append(func.__name__.replace('_', '-'));
+ return func
commands = Commands()
@@ -77,9 +79,9 @@ For help with a command: %s <command> --
self.op.add_option_group(connection_options(self.op))
json_group = optparse.OptionGroup(self.op, "JSON Formatting options")
json_group.add_option("--indent", action="store", type="int", default=2, metavar="<spaces>",
- help="Indent for pretty-printing output. -1 means don't pretty-print (default %default)")
+ help="Indent for pretty-printing output. -1 means don't pretty-print (default %default)")
self.op.add_option_group(json_group)
- command = getattr(self, argv[1])
+ command = getattr(self, argv[1].replace('-', '_'))
command() # Call the command method
def setup(self, description, call_opts, other_opts=None):
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org