[sheepdog] [PATCH 2/2] tests/unit: use rbtree

MORITA Kazutaka morita.kazutaka at gmail.com
Tue Sep 24 11:48:44 CEST 2013


From: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>

This fixes unittests which are broken recent commits.

Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
 include/sheep.h               |  33 +++++----
 tests/unit/dog/mock_dog.c     |  10 ++-
 tests/unit/sheep/mock_group.c |   6 +-
 tests/unit/sheep/test_hash.c  | 160 +++++++++++++++++++++++++++++++-----------
 4 files changed, 148 insertions(+), 61 deletions(-)

diff --git a/include/sheep.h b/include/sheep.h
index 1795855..293e057 100644
--- a/include/sheep.h
+++ b/include/sheep.h
@@ -219,24 +219,29 @@ static inline bool node_eq(const struct sd_node *a, const struct sd_node *b)
 }
 
 static inline void
+node_to_vnodes(const struct sd_node *n, struct rb_root *vroot)
+{
+	uint64_t hval = sd_hash(&n->nid, offsetof(typeof(n->nid),
+						  io_addr));
+
+	for (int i = 0; i < n->nr_vnodes; i++) {
+		struct sd_vnode *v = xmalloc(sizeof(*v));
+
+		hval = sd_hash_next(hval);
+		v->hash = hval;
+		v->node = n;
+		if (unlikely(rb_insert(vroot, v, rb, vnode_cmp)))
+			panic("vdisk hash collison");
+	}
+}
+
+static inline void
 nodes_to_vnodes(struct rb_root *nroot, struct rb_root *vroot)
 {
 	struct sd_node *n;
 
-	rb_for_each_entry(n, nroot, rb) {
-		uint64_t hval = sd_hash(&n->nid, offsetof(typeof(n->nid),
-							  io_addr));
-
-		for (int i = 0; i < n->nr_vnodes; i++) {
-			struct sd_vnode *v = xmalloc(sizeof(*v));
-
-			hval = sd_hash_next(hval);
-			v->hash = hval;
-			v->node = n;
-			if (unlikely(rb_insert(vroot, v, rb, vnode_cmp)))
-				panic("vdisk hash collison");
-		}
-	}
+	rb_for_each_entry(n, nroot, rb)
+		node_to_vnodes(n, vroot);
 }
 
 static inline void nodes_to_buffer(struct rb_root *nroot, void *buffer)
diff --git a/tests/unit/dog/mock_dog.c b/tests/unit/dog/mock_dog.c
index 6059a0a..80eeb0e 100644
--- a/tests/unit/dog/mock_dog.c
+++ b/tests/unit/dog/mock_dog.c
@@ -15,11 +15,15 @@
 #include "mock.h"
 
 /* dog mock */
-uint8_t sdhost[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 1 };
-int sdport = 7000, sd_vnodes_nr = 100;
+struct node_id sd_nid = {
+	/* default sdhost is "127.0.0.1" */
+	.addr = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 1 },
+	.port = SD_LISTEN_PORT,
+};
 bool highlight = true;
 bool raw_output;
-struct sd_vnode sd_vnodes[SD_MAX_VNODES];
+struct rb_root sd_vroot = RB_ROOT;
+struct rb_root sd_nroot = RB_ROOT;
 
 MOCK_METHOD(update_node_list, int, 0, int max_nodes)
 MOCK_VOID_METHOD(subcommand_usage, char *cmd, char *subcmd, int status)
diff --git a/tests/unit/sheep/mock_group.c b/tests/unit/sheep/mock_group.c
index 52ec307..27e9b6e 100644
--- a/tests/unit/sheep/mock_group.c
+++ b/tests/unit/sheep/mock_group.c
@@ -17,13 +17,13 @@
 #include "cluster.h"
 
 MOCK_VOID_METHOD(sd_accept_handler, const struct sd_node *joined,
-		 const struct sd_node *members, size_t nr_members,
+		 const struct rb_root *nroot, size_t nr_nodes,
 		 const void *opaque)
 MOCK_METHOD(sd_join_handler, bool, true, const struct sd_node *joining,
-	    const struct sd_node *nodes, size_t nr_nodes,
+	    const struct rb_root *nroot, size_t nr_nodes,
 	    void *opaque)
 MOCK_VOID_METHOD(sd_leave_handler, const struct sd_node *left,
-		 const struct sd_node *members, size_t nr_members)
+		 const struct rb_root *nroot, size_t nr_nodes)
 MOCK_VOID_METHOD(sd_notify_handler, const struct sd_node *sender, void *msg,
 		 size_t msg_len)
 MOCK_METHOD(sd_block_handler, bool, true, const struct sd_node *sender)
diff --git a/tests/unit/sheep/test_hash.c b/tests/unit/sheep/test_hash.c
index 0c7320f..26386b9 100644
--- a/tests/unit/sheep/test_hash.c
+++ b/tests/unit/sheep/test_hash.c
@@ -230,46 +230,83 @@ static void node5_setup(void)
 	gen_nodes = gen_many_nodes_some_vnodes;
 }
 
+static size_t get_vnodes_array(struct rb_root *vroot, struct sd_vnode *vnodes)
+{
+	struct sd_vnode *vnode;
+	size_t nr = 0;
+
+	rb_for_each_entry(vnode, vroot, rb) {
+		nr++;
+		*vnodes++ = *vnode;
+	}
+
+	return nr;
+}
+
 /* check the existing vnodes don't change */
 START_TEST(test_nodes_update)
 {
 	size_t nr_vnodes;
 	size_t nr_vnodes_after;
 	struct sd_node nodes[DATA_SIZE];
-	struct sd_vnode vnodes[SD_MAX_VNODES];
-	struct sd_vnode vnodes_after[SD_MAX_VNODES];
+	struct sd_vnode vnodes[DATA_SIZE];
+	struct sd_vnode vnodes_after[DATA_SIZE];
+	struct rb_root vroot;
 
 	gen_nodes(nodes, 0);
 
-	nr_vnodes = nodes_to_vnodes(nodes, 1, vnodes);
+	INIT_RB_ROOT(&vroot);
+	node_to_vnodes(nodes, &vroot);
+	nr_vnodes = get_vnodes_array(&vroot, vnodes);
 	/* 1 node join */
-	nr_vnodes_after = nodes_to_vnodes(nodes, 2, vnodes_after);
+	node_to_vnodes(nodes + 1, &vroot);
+	nr_vnodes_after = get_vnodes_array(&vroot, vnodes_after);
 	ck_assert(is_subset(vnodes_after, nr_vnodes_after, vnodes,
 			    nr_vnodes, vnode_cmp));
 
-	nr_vnodes = nodes_to_vnodes(nodes, 100, vnodes);
+	INIT_RB_ROOT(&vroot);
+	for (int i = 0; i < 100; i++)
+		node_to_vnodes(nodes + i, &vroot);
+	nr_vnodes = get_vnodes_array(&vroot, vnodes);
 	/* 1 node join */
-	nr_vnodes_after = nodes_to_vnodes(nodes, 101, vnodes_after);
+	node_to_vnodes(nodes + 100, &vroot);
+	nr_vnodes_after = get_vnodes_array(&vroot, vnodes_after);
 	ck_assert(is_subset(vnodes_after, nr_vnodes_after, vnodes,
 			    nr_vnodes, vnode_cmp));
 	/* 100 nodes join */
-	nr_vnodes_after = nodes_to_vnodes(nodes, 200, vnodes_after);
+	for (int i = 101; i < 200; i++)
+		node_to_vnodes(nodes + i, &vroot);
+	nr_vnodes_after = get_vnodes_array(&vroot, vnodes_after);
 	ck_assert(is_subset(vnodes_after, nr_vnodes_after, vnodes,
 			    nr_vnodes, vnode_cmp));
 
-	nr_vnodes = nodes_to_vnodes(nodes, 2, vnodes);
+	INIT_RB_ROOT(&vroot);
+	node_to_vnodes(nodes, &vroot);
+	node_to_vnodes(nodes + 1, &vroot);
+	nr_vnodes = get_vnodes_array(&vroot, vnodes);
 	/* 1 node leave */
-	nr_vnodes_after = nodes_to_vnodes(nodes + 1, 1, vnodes_after);
+	INIT_RB_ROOT(&vroot);
+	node_to_vnodes(nodes, &vroot);
+	nr_vnodes_after = get_vnodes_array(&vroot, vnodes_after);
 	ck_assert(is_subset(vnodes, nr_vnodes, vnodes_after,
 			    nr_vnodes_after, vnode_cmp));
 
-	nr_vnodes = nodes_to_vnodes(nodes, 200, vnodes);
+	INIT_RB_ROOT(&vroot);
+	for (int i = 0; i < 200; i++)
+		node_to_vnodes(nodes + i, &vroot);
+	nr_vnodes = get_vnodes_array(&vroot, vnodes);
 	/* 1 node leave */
-	nr_vnodes_after = nodes_to_vnodes(nodes + 1, 199, vnodes_after);
+	INIT_RB_ROOT(&vroot);
+	for (int i = 0; i < 199; i++)
+		node_to_vnodes(nodes + i, &vroot);
+	nr_vnodes_after = get_vnodes_array(&vroot, vnodes_after);
 	ck_assert(is_subset(vnodes, nr_vnodes, vnodes_after,
 			    nr_vnodes_after, vnode_cmp));
 	/* 100 nodes leave */
-	nr_vnodes_after = nodes_to_vnodes(nodes + 50, 100, vnodes_after);
+	INIT_RB_ROOT(&vroot);
+	for (int i = 50; i < 150; i++)
+		node_to_vnodes(nodes + i, &vroot);
+	nr_vnodes_after = get_vnodes_array(&vroot, vnodes_after);
 	ck_assert(is_subset(vnodes, nr_vnodes, vnodes_after,
 			    nr_vnodes_after, vnode_cmp));
 }
@@ -278,16 +315,20 @@ END_TEST
 static void gen_data_from_nodes(double *data, int idx)
 {
 	struct sd_node nodes[DATA_SIZE];
-	struct sd_vnode vnodes[DATA_SIZE];
+	struct sd_vnode *vnode;
+	struct rb_root vroot;
 	int nr_nodes;
-	int nr_vnodes;
+	double *p = data;
 
 	nr_nodes = gen_nodes(nodes, idx);
-	nr_vnodes = nodes_to_vnodes(nodes, nr_nodes, vnodes);
-	ck_assert_int_eq(nr_vnodes, DATA_SIZE);
+	INIT_RB_ROOT(&vroot);
+	for (int i = 0; i < nr_nodes; i++)
+		node_to_vnodes(nodes + i, &vroot);
 
-	for (int i = 0; i < DATA_SIZE; i++)
-		data[i] = vnodes[i].id;
+	rb_for_each_entry(vnode, &vroot, rb)
+		*p++ = vnode->hash;
+
+	ck_assert_int_eq(p - data, DATA_SIZE);
 }
 
 START_TEST(test_nodes_dispersion)
@@ -304,7 +345,7 @@ static size_t gen_many_vdisks(struct disk *disks, int idx)
 	memset(disks, 0, sizeof(*disks));
 
 	snprintf(disks[0].path, sizeof(disks[0].path), "/%x", idx);
-	disks[0].nr_vdisks = DATA_SIZE;
+	disks[0].space = MD_VDISK_SIZE * DATA_SIZE;
 
 	return 1;
 }
@@ -322,7 +363,7 @@ static size_t gen_many_disks_one_vdisk(struct disk *disks, int idx)
 	for (int i = 0; i < DATA_SIZE; i++) {
 		snprintf(disks[i].path, sizeof(disks[i].path),
 			 "/%x/%x", idx, i);
-		disks[i].nr_vdisks = 1;
+		disks[i].space = MD_VDISK_SIZE;
 	}
 
 	return DATA_SIZE;
@@ -341,7 +382,7 @@ static size_t gen_many_disks_some_vdisks(struct disk *disks, int idx)
 	for (int i = 0; i < DATA_SIZE / 4; i++) {
 		snprintf(disks[i].path, sizeof(disks[i].path),
 			 "/%x/%x", idx, i);
-		disks[i].nr_vdisks = 4;
+		disks[i].space = MD_VDISK_SIZE * 4;
 	}
 
 	return DATA_SIZE / 4;
@@ -352,45 +393,79 @@ static void disk3_setup(void)
 	gen_disks = gen_many_disks_some_vdisks;
 }
 
+static size_t get_vdisks_array(struct vdisk *vdisks)
+{
+	struct vdisk *vdisk;
+	size_t nr = 0;
+
+	rb_for_each_entry(vdisk, &md.vroot, rb) {
+		nr++;
+		*vdisks++ = *vdisk;
+	}
+
+	return nr;
+}
+
 START_TEST(test_disks_update)
 {
 	size_t nr_vdisks;
 	size_t nr_vdisks_after;
 	struct disk disks[DATA_SIZE];
-	struct vdisk vdisks[MD_MAX_VDISK];
-	struct vdisk vdisks_after[MD_MAX_VDISK];
+	struct vdisk vdisks[DATA_SIZE];
+	struct vdisk vdisks_after[DATA_SIZE];
 
 	gen_disks(disks, 0);
 
-	nr_vdisks = disks_to_vdisks(disks, 1, vdisks);
+	INIT_RB_ROOT(&md.vroot);
+	create_vdisks(disks);
+	nr_vdisks = get_vdisks_array(vdisks);
 	/* add 1 disk */
-	nr_vdisks_after = disks_to_vdisks(disks, 2, vdisks_after);
+	create_vdisks(disks + 1);
+	nr_vdisks_after = get_vdisks_array(vdisks_after);
 	ck_assert(is_subset(vdisks_after, nr_vdisks_after, vdisks,
 			    nr_vdisks, vdisk_cmp));
 
-	nr_vdisks = disks_to_vdisks(disks, 30, vdisks);
+	INIT_RB_ROOT(&md.vroot);
+	for (int i = 0; i < 30; i++)
+		create_vdisks(disks + i);
+	nr_vdisks = get_vdisks_array(vdisks);
 	/* add 1 disk */
-	nr_vdisks_after = disks_to_vdisks(disks, 31, vdisks_after);
+	create_vdisks(disks + 30);
+	nr_vdisks_after = get_vdisks_array(vdisks_after);
 	ck_assert(is_subset(vdisks_after, nr_vdisks_after, vdisks,
 			    nr_vdisks, vdisk_cmp));
 	/* add 20 disks */
-	nr_vdisks_after = disks_to_vdisks(disks, 50, vdisks_after);
+	for (int i = 31; i < 50; i++)
+		create_vdisks(disks + i);
+	nr_vdisks_after = get_vdisks_array(vdisks_after);
 	ck_assert(is_subset(vdisks_after, nr_vdisks_after, vdisks,
 			    nr_vdisks, vdisk_cmp));
 
-	nr_vdisks = disks_to_vdisks(disks, 2, vdisks);
+	INIT_RB_ROOT(&md.vroot);
+	create_vdisks(disks);
+	create_vdisks(disks + 1);
+	nr_vdisks = get_vdisks_array(vdisks);
 	/* remove 1 disk */
-	nr_vdisks_after = disks_to_vdisks(disks + 1, 1, vdisks_after);
+	remove_vdisks(disks);
+	nr_vdisks_after = get_vdisks_array(vdisks_after);
 	ck_assert(is_subset(vdisks, nr_vdisks, vdisks_after,
 			    nr_vdisks_after, vdisk_cmp));
 
-	nr_vdisks = disks_to_vdisks(disks, 50, vdisks);
+	INIT_RB_ROOT(&md.vroot);
+	for (int i = 0; i < 50; i++)
+		create_vdisks(disks + i);
+	nr_vdisks = get_vdisks_array(vdisks);
 	/* remove 1 disk */
-	nr_vdisks_after = disks_to_vdisks(disks + 1, 49, vdisks_after);
+	remove_vdisks(disks);
+	nr_vdisks_after = get_vdisks_array(vdisks_after);
 	ck_assert(is_subset(vdisks, nr_vdisks, vdisks_after,
 			    nr_vdisks_after, vdisk_cmp));
 	/* remove 20 disks */
-	nr_vdisks_after = disks_to_vdisks(disks + 10, 30, vdisks_after);
+	for (int i = 1; i < 10; i++)
+		remove_vdisks(disks + i);
+	for (int i = 40; i < 50; i++)
+		remove_vdisks(disks + i);
+	nr_vdisks_after = get_vdisks_array(vdisks_after);
 	ck_assert(is_subset(vdisks, nr_vdisks, vdisks_after,
 			    nr_vdisks_after, vdisk_cmp));
 }
@@ -399,16 +474,19 @@ END_TEST
 static void gen_data_from_disks(double *data, int idx)
 {
 	struct disk disks[DATA_SIZE];
-	struct vdisk vdisks[DATA_SIZE];
+	struct vdisk *vdisk;
 	int nr_disks;
-	int nr_vdisks;
+	double *p = data;
 
 	nr_disks = gen_disks(disks, idx);
-	nr_vdisks = disks_to_vdisks(disks, nr_disks, vdisks);
-	ck_assert_int_eq(nr_vdisks, DATA_SIZE);
+	INIT_RB_ROOT(&md.vroot);
+	for (int i = 0; i < nr_disks; i++)
+		create_vdisks(disks + i);
 
-	for (int i = 0; i < DATA_SIZE; i++)
-		data[i] = vdisks[i].id;
+	rb_for_each_entry(vdisk, &md.vroot, rb)
+		*p++ = vdisk->hash;
+
+	ck_assert_int_eq(p - data, DATA_SIZE);
 }
 
 START_TEST(test_disks_dispersion)
@@ -475,8 +553,8 @@ static Suite *test_suite(void)
 	TCase *tc_nodes4 = tcase_create("many nodes with one vnode");
 	TCase *tc_nodes5 = tcase_create("many nodes with some vnodes");
 	TCase *tc_disks1 = tcase_create("many vdisks on one disk");
-	TCase *tc_disks2 = tcase_create("many disks with one vnode");
-	TCase *tc_disks3 = tcase_create("many disks with some vnodes");
+	TCase *tc_disks2 = tcase_create("many disks with one vdisk");
+	TCase *tc_disks3 = tcase_create("many disks with some vdisks");
 	TCase *tc_objects1 = tcase_create("many data objects");
 	TCase *tc_objects2 = tcase_create("many vdi objects");
 
-- 
1.8.1.2




More information about the sheepdog mailing list