Re: [ovs-dev] [PATCH 15/15] ovsdb-idl: Check internal graph in OVSDB tests.

2016-10-19 Thread Ben Pfaff
On Mon, Oct 17, 2016 at 01:44:03PM -0700, Andy Zhou wrote:
> On Wed, Oct 5, 2016 at 8:16 PM, Ben Pfaff  wrote:
> 
> > Some upcoming tests will add extra trickiness to the IDL internal graph.
> > This worries me, because the IDL doesn't have any checks for its graph
> > consistency.  This commit adds some.
> >
> > Signed-off-by: Ben Pfaff 
> >
> 
> For all 15 patches in the series,
> 
> Acked-by: Andy Zhou 

Thanks Andy.  I applied these to master.
___
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev


Re: [ovs-dev] [PATCH 15/15] ovsdb-idl: Check internal graph in OVSDB tests.

2016-10-17 Thread Andy Zhou
On Wed, Oct 5, 2016 at 8:16 PM, Ben Pfaff  wrote:

> Some upcoming tests will add extra trickiness to the IDL internal graph.
> This worries me, because the IDL doesn't have any checks for its graph
> consistency.  This commit adds some.
>
> Signed-off-by: Ben Pfaff 
>

For all 15 patches in the series,

Acked-by: Andy Zhou 
___
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev


[ovs-dev] [PATCH 15/15] ovsdb-idl: Check internal graph in OVSDB tests.

2016-10-05 Thread Ben Pfaff
Some upcoming tests will add extra trickiness to the IDL internal graph.
This worries me, because the IDL doesn't have any checks for its graph
consistency.  This commit adds some.

Signed-off-by: Ben Pfaff 
---
 lib/ovsdb-idl.c| 122 +
 lib/ovsdb-idl.h|   2 +
 tests/test-ovsdb.c |   7 +++
 3 files changed, 131 insertions(+)

diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c
index b4d3c42..8ce228d 100644
--- a/lib/ovsdb-idl.c
+++ b/lib/ovsdb-idl.c
@@ -629,6 +629,128 @@ ovsdb_idl_set_probe_interval(const struct ovsdb_idl *idl, 
int probe_interval)
 {
 jsonrpc_session_set_probe_interval(idl->session, probe_interval);
 }
+
+static size_t
+find_uuid_in_array(const struct uuid *target,
+   const struct uuid *array, size_t n)
+{
+for (size_t i = 0; i < n; i++) {
+if (uuid_equals([i], target)) {
+return i;
+}
+}
+return SIZE_MAX;
+}
+
+static size_t
+array_contains_uuid(const struct uuid *target,
+const struct uuid *array, size_t n)
+{
+return find_uuid_in_array(target, array, n) != SIZE_MAX;
+}
+
+static bool
+remove_uuid_from_array(const struct uuid *target,
+   struct uuid *array, size_t *n)
+{
+size_t i = find_uuid_in_array(target, array, *n);
+if (i != SIZE_MAX) {
+array[i] = array[--*n];
+return true;
+} else {
+return false;
+}
+}
+
+static void
+add_row_references(const struct ovsdb_base_type *type,
+   const union ovsdb_atom *atoms, size_t n_atoms,
+   const struct uuid *exclude_uuid,
+   struct uuid **dstsp, size_t *n_dstsp,
+   size_t *allocated_dstsp)
+{
+if (type->type != OVSDB_TYPE_UUID || !type->u.uuid.refTableName) {
+return;
+}
+
+for (size_t i = 0; i < n_atoms; i++) {
+const struct uuid *uuid = [i].uuid;
+if (!uuid_equals(uuid, exclude_uuid)
+&& !array_contains_uuid(uuid, *dstsp, *n_dstsp)) {
+if (*n_dstsp >= *allocated_dstsp) {
+*dstsp = x2nrealloc(*dstsp, allocated_dstsp,
+sizeof **dstsp);
+
+}
+(*dstsp)[*n_dstsp] = *uuid;
+++*n_dstsp;
+}
+}
+}
+
+/* Checks for consistency in 'idl''s graph of arcs between database rows.  Each
+ * reference from one row to a different row should be reflected as a "struct
+ * ovsdb_idl_arc" between those rows.
+ *
+ * This function is slow, big-O wise, and aborts if it finds an inconsistency,
+ * thus it is only for use in test programs. */
+void
+ovsdb_idl_check_consistency(const struct ovsdb_idl *idl)
+{
+/* Consistency is broken while a transaction is in progress. */
+if (!idl->txn) {
+return;
+}
+
+bool ok = true;
+
+struct uuid *dsts = NULL;
+size_t allocated_dsts = 0;
+
+for (size_t i = 0; i < idl->class->n_tables; i++) {
+const struct ovsdb_idl_table *table = >tables[i];
+const struct ovsdb_idl_table_class *class = table->class;
+
+const struct ovsdb_idl_row *row;
+HMAP_FOR_EACH (row, hmap_node, >rows) {
+size_t n_dsts = 0;
+if (row->new) {
+size_t n_columns = shash_count(>table->columns);
+for (size_t j = 0; j < n_columns; j++) {
+const struct ovsdb_type *type = >columns[j].type;
+const struct ovsdb_datum *datum = >new[j];
+add_row_references(>key,
+   datum->keys, datum->n, >uuid,
+   , _dsts, _dsts);
+add_row_references(>value,
+   datum->values, datum->n, >uuid,
+   , _dsts, _dsts);
+}
+}
+const struct ovsdb_idl_arc *arc;
+LIST_FOR_EACH (arc, src_node, >src_arcs) {
+if (!remove_uuid_from_array(>dst->uuid,
+dsts, _dsts)) {
+VLOG_ERR("unexpected arc from %s row "UUID_FMT" to %s "
+ "row "UUID_FMT,
+ table->class->name,
+ UUID_ARGS(>uuid),
+ arc->dst->table->class->name,
+ UUID_ARGS(>dst->uuid));
+ok = false;
+}
+}
+for (size_t i = 0; i < n_dsts; i++) {
+VLOG_ERR("%s row "UUID_FMT" missing arc to row "UUID_FMT,
+ table->class->name, UUID_ARGS(>uuid),
+ UUID_ARGS([i]));
+ok = false;
+}
+}
+}
+free(dsts);
+ovs_assert(ok);
+}
 
 static unsigned char *
 ovsdb_idl_get_mode(struct ovsdb_idl *idl,
diff --git a/lib/ovsdb-idl.h b/lib/ovsdb-idl.h
index