예제 #1
0
static void test_brick_core_refcount(void)
{
	struct pg_error *error = NULL;
	struct pg_brick *brick;
	struct pg_brick_config *config = pg_brick_config_new("mybrick", 2, 2,
							     PG_MULTIPOLE);

	brick = pg_brick_new("nop", config, &error);
	g_assert(brick);
	g_assert(!error);

	/* Use the brick twice */
	pg_brick_incref(brick);
	pg_brick_incref(brick);

	/* Release it twice */
	brick = pg_brick_decref(brick, &error);
	g_assert(brick);
	g_assert(!error);
	brick = pg_brick_decref(brick, &error);
	g_assert(brick);
	g_assert(!error);

	/* finally destroy the brick */
	brick = pg_brick_decref(brick, &error);
	g_assert(!brick);
	g_assert(!error);

	pg_brick_config_free(config);
}
예제 #2
0
static void test_brick_core_simple_lifecycle(void)
{
	struct pg_error *error = NULL;
	struct pg_brick *brick;
	struct pg_brick_config *config = pg_brick_config_new("mybrick", 2, 2,
							     PG_MULTIPOLE);

	brick = pg_brick_new("foo", config, &error);
	g_assert(!brick);
	g_assert(error);
	g_assert(error->message);
	g_assert_cmpstr(error->message, ==, "Brick 'foo' not found");
	pg_error_free(error);
	error = NULL;

	brick = pg_brick_new("nop", config, &error);
	g_assert(brick);
	g_assert(!error);

	pg_brick_decref(brick, &error);
	g_assert(!error);

	brick = pg_brick_decref(NULL, &error);
	g_assert(!brick);
	g_assert(error);
	g_assert(error->message);
	g_assert_cmpstr(error->message, ==, "NULL brick");
	pg_error_free(error);
	error = NULL;

	pg_brick_config_free(config);
}
예제 #3
0
static void test_brick_core_multiple_unlink_edge(void)
{
	int i;
	struct pg_brick *west[4];
	struct pg_brick *middle;
	struct pg_brick *east[4];
	struct pg_error *error = NULL;
	struct pg_brick_config *config = pg_brick_config_new("mybrick", 4, 4,
							     PG_MULTIPOLE);

	middle = pg_brick_new("nop", config, &error);
	g_assert(middle);
	g_assert(!error);
	for (i = 0; i < 4; i++) {
		west[i] = pg_brick_new("nop", config, &error);
		g_assert(west[i]);
		g_assert(!error);
		east[i] = pg_brick_new("nop", config, &error);
		g_assert(east[i]);
		g_assert(!error);
	}

	for (int i = 0; i < 10; i++)
		test_brick_core_multiple_unlink_edge_(west, middle, east);

	/* destroy */
	for (i = 0; i < 4; i++) {
		pg_brick_decref(west[i], &error);
		g_assert(!error);
		pg_brick_decref(east[i], &error);
		g_assert(!error);
	}
	pg_brick_decref(middle, &error);
	g_assert(!error);

	pg_brick_config_free(config);
}
예제 #4
0
/* this test harness a Linux guest to check that packet are send and received
 * by the vhost brick. An ethernet bridge inside the guest will forward packets
 * between the two vhost-user virtio interfaces.
 */
static void test_vhost_flow_(int qemu_exit_signal)
{
	const char mac_addr_0[18] = "52:54:00:12:34:11";
	const char mac_addr_1[18] = "52:54:00:12:34:12";
	struct rte_mempool *mbuf_pool = pg_get_mempool();
	struct pg_brick *vhost_0, *vhost_1, *collect;
	struct rte_mbuf *pkts[PG_MAX_PKTS_BURST];
	const char *socket_path_0, *socket_path_1;
	struct pg_error *error = NULL;
	struct rte_mbuf **result_pkts;
	int ret, qemu_pid, i;
	uint64_t pkts_mask;

	/* start vhost */
	ret = pg_vhost_start("/tmp", &error);
	g_assert(ret == 0);
	g_assert(!error);

	/* instanciate brick */
	vhost_0 = pg_vhost_new("vhost-0", &error);
	g_assert(!error);
	g_assert(vhost_0);

	vhost_1 = pg_vhost_new("vhost-1", &error);
	g_assert(!error);
	g_assert(vhost_1);

	collect = pg_collect_new("collect", &error);
	g_assert(!error);
	g_assert(collect);

	/* build the graph */
	pg_brick_link(collect, vhost_1, &error);
	g_assert(!error);

	/* spawn first QEMU */
	socket_path_0 = pg_vhost_socket_path(vhost_0, &error);
	g_assert(!error);
	g_assert(socket_path_0);
	socket_path_1 = pg_vhost_socket_path(vhost_1, &error);
	g_assert(!error);
	g_assert(socket_path_1);

	qemu_pid = pg_util_spawn_qemu(socket_path_0, socket_path_1,
				      mac_addr_0, mac_addr_1,
				      glob_vm_path,
				      glob_vm_key_path,
				      glob_hugepages_path, &error);

	g_assert(!error);
	g_assert(qemu_pid);

	/* Prepare VM's bridge. */
#	define SSH(c) \
		g_assert(pg_util_ssh("localhost", ssh_port_id, glob_vm_key_path, c) == 0)
	SSH("brctl addbr br0");
	SSH("ifconfig br0 up");
	SSH("ifconfig ens4 up");
	SSH("ifconfig ens5 up");
	SSH("brctl addif br0 ens4");
	SSH("brctl addif br0 ens5");
	SSH("brctl setfd br0 0");
	SSH("brctl stp br0 off");
#	undef SSH
	ssh_port_id++;

	/* prepare packet to send */
	for (i = 0; i < NB_PKTS; i++) {
		pkts[i] = rte_pktmbuf_alloc(mbuf_pool);
		g_assert(pkts[i]);
		rte_pktmbuf_append(pkts[i], ETHER_MIN_LEN);
		/* set random dst/src mac address so the linux guest bridge
		 * will not filter them
		 */
		pg_set_mac_addrs(pkts[i],
			      "52:54:00:12:34:15", "52:54:00:12:34:16");
		/* set size */
		pg_set_ether_type(pkts[i], ETHER_MIN_LEN - ETHER_HDR_LEN - 4);
	}

	/* send packet to the guest via one interface */
	pg_brick_burst_to_east(vhost_0, 0, pkts,
			       pg_mask_firsts(NB_PKTS), &error);
	g_assert(!error);

	/* let the packet propagate and flow */
	for (i = 0; i < 10; i++) {
		uint16_t count = 0;

		usleep(100000);
		pg_brick_poll(vhost_1, &count, &error);
		g_assert(!error);
		if (count)
			break;
	}

	result_pkts = pg_brick_east_burst_get(collect, &pkts_mask, &error);
	g_assert(!error);
	g_assert(result_pkts);
	g_assert(pg_brick_rx_bytes(vhost_0) == 0);
	g_assert(pg_brick_tx_bytes(vhost_0) != 0);
	g_assert(pg_brick_rx_bytes(vhost_1) != 0);
	g_assert(pg_brick_tx_bytes(vhost_1) == 0);

	/* kill QEMU */
	pg_util_stop_qemu(qemu_pid, qemu_exit_signal);

	/* free result packets */
	pg_packets_free(result_pkts, pkts_mask);

	/* free sent packet */
	for (i = 0; i < NB_PKTS; i++)
		rte_pktmbuf_free(pkts[i]);

	/* break the graph */
	pg_brick_unlink(collect, &error);
	g_assert(!error);

	/* clean up */
	/* pg_brick_decref(vhost_0, &error); */
	pg_brick_destroy(vhost_0);
	g_assert(!error);
	pg_brick_destroy(vhost_1);
	/* pg_brick_decref(vhost_1, &error); */
	g_assert(!error);
	pg_brick_decref(collect, &error);
	g_assert(!error);

	/* stop vhost */
	pg_vhost_stop();
}
예제 #5
0
static void test_brick_flow_west(void)
{
	struct pg_brick_config *config = pg_brick_config_new("mybrick", 4, 4);
	struct pg_brick *brick1, *brick2, *collect_west, *collect_east;
	struct rte_mbuf mbufs[NB_PKTS];
	struct rte_mbuf **result_pkts;
	struct rte_mbuf *pkts[NB_PKTS];
	uint16_t i;
	uint64_t pkts_mask;
	struct pg_error *error = NULL;

	/* prepare the packets to send */
	for (i = 0; i < NB_PKTS; i++) {
		mbufs[i].udata64 = i;
		pkts[i] = &mbufs[i];
	}

	/* create a chain of a few nop brick with collectors on each sides */
	brick1 = pg_brick_new("nop", config, &error);
	g_assert(!error);
	brick2 = pg_brick_new("nop", config, &error);
	g_assert(!error);
	collect_west = pg_brick_new("collect", config, &error);
	g_assert(!error);
	g_assert(collect_west);
	collect_east = pg_brick_new("collect", config, &error);
	g_assert(!error);
	g_assert(collect_east);

	pg_brick_link(collect_west, brick1, &error);
	g_assert(!error);
	pg_brick_link(brick1, brick2, &error);
	g_assert(!error);
	pg_brick_link(brick2, collect_east, &error);
	g_assert(!error);

	/* send a pkts to the west from the eastest nope brick */
	pg_brick_burst_to_west(brick2, 0, pkts, NB_PKTS,
			       pg_mask_firsts(NB_PKTS), &error);
	g_assert(!error);

	/* check pkts counter */
	g_assert(pg_brick_pkts_count_get(collect_east, WEST_SIDE) == 0);
	g_assert(pg_brick_pkts_count_get(collect_east, EAST_SIDE) == 0);
	g_assert(pg_brick_pkts_count_get(collect_west, WEST_SIDE) == 3);
	g_assert(pg_brick_pkts_count_get(collect_west, EAST_SIDE) == 0);
	g_assert(pg_brick_pkts_count_get(brick1, WEST_SIDE) == 3);
	g_assert(pg_brick_pkts_count_get(brick1, EAST_SIDE) == 0);
	g_assert(pg_brick_pkts_count_get(brick2, WEST_SIDE) == 3);
	g_assert(pg_brick_pkts_count_get(brick2, EAST_SIDE) == 0);

	/* check no packet ended on the east */
	result_pkts = pg_brick_west_burst_get(collect_east, &pkts_mask, &error);
	g_assert(!error);
	g_assert(!pkts_mask);
	g_assert(!result_pkts);
	result_pkts = pg_brick_east_burst_get(collect_east, &pkts_mask, &error);
	g_assert(!error);
	g_assert(!pkts_mask);
	g_assert(!result_pkts);

	/* collect pkts on the west */
	result_pkts = pg_brick_west_burst_get(collect_west, &pkts_mask, &error);
	g_assert(!error);
	g_assert(!pkts_mask);
	g_assert(!result_pkts);

	result_pkts = pg_brick_east_burst_get(collect_west, &pkts_mask, &error);
	g_assert(!error);
	g_assert(pkts_mask == pg_mask_firsts(NB_PKTS));
	g_assert(result_pkts);
	for (i = 0; i < NB_PKTS; i++)
		g_assert(result_pkts[i]->udata64 == i);

	/* break the chain */
	pg_brick_unlink(brick1, &error);
	g_assert(!error);
	pg_brick_unlink(brick2, &error);
	g_assert(!error);
	pg_brick_unlink(collect_west, &error);
	g_assert(!error);
	pg_brick_unlink(collect_east, &error);
	g_assert(!error);

	/* destroy */
	pg_brick_decref(brick1, &error);
	g_assert(!error);
	pg_brick_decref(brick2, &error);
	g_assert(!error);
	pg_brick_decref(collect_west, &error);
	g_assert(!error);
	pg_brick_decref(collect_east, &error);
	g_assert(!error);

	pg_brick_config_free(config);
}
예제 #6
0
static void test_queue_friend(void)
{
	struct pg_error *error = NULL;
	struct pg_brick *q1, *q2, *q3;

	q1 = pg_queue_new("q1", 1, &error);
	CHECK_ERROR(error);
	q2 = pg_queue_new("q2", 1, &error);
	CHECK_ERROR(error);
	q3 = pg_queue_new("q3", 1, &error);
	CHECK_ERROR(error);

	/* classic scenario */
	g_assert(!pg_queue_get_friend(q1));
	g_assert(!pg_queue_get_friend(q2));
	g_assert(!pg_queue_friend(q1, q2, &error));
	CHECK_ERROR(error);
	g_assert(pg_queue_get_friend(q1) == q2);
	g_assert(pg_queue_are_friend(q1, q2));
	g_assert(pg_queue_get_friend(q2) == q1);
	g_assert(pg_queue_are_friend(q2, q1));
	pg_queue_unfriend(q1);
	g_assert(!pg_queue_get_friend(q1));
	g_assert(!pg_queue_are_friend(q1, q2));
	g_assert(!pg_queue_get_friend(q2));
	g_assert(!pg_queue_are_friend(q2, q1));

	/* same but unfriend with second brick */
	g_assert(!pg_queue_friend(q1, q2, &error));
	CHECK_ERROR(error);
	g_assert(pg_queue_are_friend(q1, q2));
	g_assert(pg_queue_are_friend(q2, q1));
	pg_queue_unfriend(q2);
	g_assert(!pg_queue_get_friend(q1));
	g_assert(!pg_queue_get_friend(q2));

	/* friend with itself */
	g_assert(!pg_queue_friend(q1, q1, &error));
	CHECK_ERROR(error);
	g_assert(pg_queue_get_friend(q1) == q1);
	g_assert(pg_queue_are_friend(q1, q1));
	pg_queue_unfriend(q1);
	g_assert(!pg_queue_get_friend(q1));

	/* several unfriend ok ? (test should die if not) */
	pg_queue_unfriend(q1);
	pg_queue_unfriend(q1);
	pg_queue_unfriend(q1);

	/* error if already friend */
	g_assert(!pg_queue_friend(q1, q2, &error));
	CHECK_ERROR(error);
	g_assert(pg_queue_friend(q1, q2, &error) == -1);
	g_assert(pg_error_is_set(&error));
	pg_error_free(error);
	error = NULL;
	g_assert(pg_queue_friend(q2, q1, &error) == -1);
	g_assert(pg_error_is_set(&error));
	pg_error_free(error);
	error = NULL;
	g_assert(pg_queue_friend(q1, q3, &error) == -1);
	g_assert(pg_error_is_set(&error));
	pg_error_free(error);
	error = NULL;
	g_assert(pg_queue_friend(q2, q3, &error) == -1);
	g_assert(pg_error_is_set(&error));
	pg_error_free(error);
	error = NULL;
	g_assert(pg_queue_friend(q3, q1, &error) == -1);
	g_assert(pg_error_is_set(&error));
	pg_error_free(error);
	error = NULL;
	g_assert(pg_queue_friend(q3, q2, &error) == -1);
	g_assert(pg_error_is_set(&error));
	pg_error_free(error);
	error = NULL;

	/* check that death break friendship */
	pg_brick_decref(q1, &error);
	CHECK_ERROR(error);
	g_assert(!pg_queue_get_friend(q2));

	/* ... and can be friend again */
	g_assert(!pg_queue_friend(q2, q3, &error));
	g_assert(pg_queue_are_friend(q2, q3));
	g_assert(pg_queue_are_friend(q3, q2));

	pg_brick_decref(q2, &error);
	CHECK_ERROR(error);
	pg_brick_decref(q3, &error);
	CHECK_ERROR(error);
}
예제 #7
0
static void test_queue_reset(void)
{
#	define NB_PKTS 64
	struct pg_error *error = NULL;
	struct pg_brick *queue1, *queue2, *collect;
	struct rte_mbuf **result_pkts;
	struct rte_mbuf *pkts[NB_PKTS];
	uint64_t pkts_mask, i, j;
	uint16_t count = 0;
	struct rte_mempool *mbuf_pool = pg_get_mempool();

	/**
	 * Burst packets in queue1 and test reset of queue1
	 * [queue1] ~ [queue2]----[collect]
	 */
	queue1 = pg_queue_new("q1", 10, &error);
	CHECK_ERROR(error);
	queue2 = pg_queue_new("q2", 10, &error);
	CHECK_ERROR(error);
	collect = pg_collect_new("collect", 1, 1, &error);
	CHECK_ERROR(error);

	pg_brick_link(queue2, collect, &error);
	CHECK_ERROR(error);
	g_assert(!pg_queue_friend(queue1, queue2, &error));
	CHECK_ERROR(error);

	for (i = 0; i < NB_PKTS; i++) {
		pkts[i] = rte_pktmbuf_alloc(mbuf_pool);
		g_assert(pkts[i]);
		pkts[i]->udata64 = i;
		pg_set_mac_addrs(pkts[i],
				 "F0:F1:F2:F3:F4:F5",
				 "E0:E1:E2:E3:E4:E5");
	}

	for (j = 0; j < 100; j++) {
		for (i = 0; i < NB_PKTS; i++)
			pkts[i]->udata64 = i * j;
		/* burst and reset */
		pg_brick_burst_to_east(queue1, 0, pkts, pg_mask_firsts(NB_PKTS),
				       &error);
		CHECK_ERROR(error);
		g_assert(pg_queue_pressure(queue1) > 0);
		g_assert(!pg_brick_reset(queue1, &error));
		g_assert(pg_queue_get_friend(queue1) == NULL);
		g_assert(pg_queue_get_friend(queue2) == NULL);
		g_assert(pg_queue_pressure(queue1) == 0);
		g_assert(pg_queue_pressure(queue2) == 0);
		pg_brick_poll(queue2, &count, &error);
		g_assert(!error);
		g_assert(count == 0);

		/* refriend and burst ok */
		g_assert(!pg_queue_friend(queue1, queue2, &error));
		g_assert(!error);
		g_assert(pg_queue_are_friend(queue1, queue2));
		g_assert(!error);

		pg_brick_burst_to_east(queue1, 0, pkts, pg_mask_firsts(NB_PKTS),
				       &error);
		CHECK_ERROR(error);
		g_assert(pg_queue_pressure(queue1) > 0);
		pg_brick_poll(queue2, &count, &error);
		g_assert(count == NB_PKTS);
		result_pkts = pg_brick_west_burst_get(collect, &pkts_mask,
						      &error);
		CHECK_ERROR(error);
		g_assert(pkts_mask == pg_mask_firsts(NB_PKTS));
		for (i = 0; i < NB_PKTS; i++) {
			g_assert(result_pkts[i]);
			g_assert(result_pkts[i]->udata64 == i * j);
		}
		pg_brick_reset(collect, &error);
		CHECK_ERROR(error);
	}

	/* clean */
	for (i = 0; i < NB_PKTS; i++)
		rte_pktmbuf_free(pkts[i]);
	pg_brick_decref(queue1, &error);
	CHECK_ERROR(error);
	pg_brick_decref(queue2, &error);
	CHECK_ERROR(error);
	pg_brick_decref(collect, &error);
	CHECK_ERROR(error);
#	undef NB_PKTS
}
예제 #8
0
static void test_brick_core_link(void)
{
	struct pg_error *error = NULL;
	struct pg_brick *west_brick, *middle_brick, *east_brick;
	struct pg_brick_config *config = pg_brick_config_new("mybrick", 4, 4,
							     PG_MULTIPOLE);
	int64_t refcount;
	int ret;

	west_brick = pg_brick_new("nop", config, &error);
	g_assert(west_brick);
	g_assert(!error);

	middle_brick = pg_brick_new("nop", config, &error);
	g_assert(middle_brick);
	g_assert(!error);

	east_brick = pg_brick_new("nop", config, &error);
	g_assert(east_brick);
	g_assert(!error);

	ret = pg_brick_link(west_brick, middle_brick,  &error);
	g_assert(ret == 0);
	g_assert(!error);

	ret = pg_brick_link(middle_brick, east_brick, &error);
	g_assert(ret == 0);
	g_assert(!error);

	refcount = pg_brick_refcount(west_brick);
	g_assert(refcount == 2);
	refcount = pg_brick_refcount(middle_brick);
	g_assert(refcount == 3);
	refcount = pg_brick_refcount(east_brick);
	g_assert(refcount == 2);

	pg_brick_unlink(west_brick, &error);
	g_assert(!error);
	refcount = pg_brick_refcount(west_brick);
	g_assert(refcount == 1);
	refcount = pg_brick_refcount(middle_brick);
	g_assert(refcount == 2);
	refcount = pg_brick_refcount(east_brick);
	g_assert(refcount == 2);

	pg_brick_unlink(east_brick, &error);
	g_assert(!error);
	refcount = pg_brick_refcount(west_brick);
	g_assert(refcount == 1);
	refcount = pg_brick_refcount(middle_brick);
	g_assert(refcount == 1);
	refcount = pg_brick_refcount(east_brick);
	g_assert(refcount == 1);

	/* destroy */
	pg_brick_decref(west_brick, &error);
	g_assert(!error);
	pg_brick_decref(middle_brick, &error);
	g_assert(!error);
	pg_brick_decref(east_brick, &error);
	g_assert(!error);

	pg_brick_config_free(config);
}
예제 #9
0
static void test_brick_core_verify_multiple_link(void)
{
	struct pg_brick *west_brick, *middle_brick, *east_brick;
	struct pg_brick_config *config = pg_brick_config_new("mybrick", 4, 4,
							     PG_MULTIPOLE);
	uint32_t links_count;
	struct pg_error *error = NULL;

	west_brick = pg_brick_new("nop", config, &error);
	g_assert(!error);
	middle_brick = pg_brick_new("nop", config, &error);
	g_assert(!error);
	east_brick = pg_brick_new("nop", config, &error);
	g_assert(!error);

	/* create a few links */
	pg_brick_link(west_brick, middle_brick, &error);
	g_assert(!error);
	pg_brick_link(west_brick, middle_brick, &error);
	g_assert(!error);
	pg_brick_link(middle_brick, east_brick, &error);
	g_assert(!error);
	pg_brick_link(middle_brick, east_brick, &error);
	g_assert(!error);
	pg_brick_link(middle_brick, east_brick, &error);
	g_assert(!error);

	/* sanity checks */
	test_brick_sanity_check(west_brick);
	test_brick_sanity_check(middle_brick);
	test_brick_sanity_check(east_brick);

	/* check the link count */
	links_count = pg_brick_links_count_get(west_brick, west_brick, &error);
	g_assert(!error);
	g_assert(links_count == 0);
	links_count = pg_brick_links_count_get(west_brick, middle_brick, &error);
	g_assert(!error);
	g_assert(links_count == 2);
	links_count = pg_brick_links_count_get(west_brick, east_brick, &error);
	g_assert(!error);
	g_assert(links_count == 0);

	links_count = pg_brick_links_count_get(middle_brick, middle_brick, &error);
	g_assert(!error);
	g_assert(links_count == 0);
	links_count = pg_brick_links_count_get(middle_brick, west_brick, &error);
	g_assert(!error);
	g_assert(links_count == 2);
	links_count = pg_brick_links_count_get(middle_brick, east_brick, &error);
	g_assert(!error);
	g_assert(links_count == 3);

	links_count = pg_brick_links_count_get(east_brick, east_brick, &error);
	g_assert(!error);
	g_assert(links_count == 0);
	links_count = pg_brick_links_count_get(east_brick, west_brick, &error);
	g_assert(!error);
	g_assert(links_count == 0);
	links_count = pg_brick_links_count_get(east_brick, middle_brick, &error);
	g_assert(!error);
	g_assert(links_count == 3);

	/* unlink the west brick */
	pg_brick_unlink(west_brick, &error);

	/* sanity checks */
	test_brick_sanity_check(west_brick);
	test_brick_sanity_check(middle_brick);
	test_brick_sanity_check(east_brick);

	/* check again */
	links_count = pg_brick_links_count_get(west_brick, west_brick, &error);
	g_assert(!error);
	g_assert(links_count == 0);
	links_count = pg_brick_links_count_get(west_brick, middle_brick, &error);
	g_assert(!error);
	g_assert(links_count == 0);
	links_count = pg_brick_links_count_get(west_brick, east_brick, &error);
	g_assert(!error);
	g_assert(links_count == 0);

	links_count = pg_brick_links_count_get(middle_brick, middle_brick, &error);
	g_assert(!error);
	g_assert(links_count == 0);
	links_count = pg_brick_links_count_get(middle_brick, west_brick, &error);
	g_assert(!error);
	g_assert(links_count == 0);
	links_count = pg_brick_links_count_get(middle_brick, east_brick, &error);
	g_assert(!error);
	g_assert(links_count == 3);

	links_count = pg_brick_links_count_get(east_brick, east_brick, &error);
	g_assert(!error);
	g_assert(links_count == 0);
	links_count = pg_brick_links_count_get(east_brick, west_brick, &error);
	g_assert(!error);
	g_assert(links_count == 0);
	links_count = pg_brick_links_count_get(east_brick, middle_brick, &error);
	g_assert(!error);
	g_assert(links_count == 3);

	/* unlink the east brick */
	pg_brick_unlink(east_brick, &error);
	g_assert(!error);

	/* sanity checks */
	test_brick_sanity_check(west_brick);
	test_brick_sanity_check(middle_brick);
	test_brick_sanity_check(east_brick);

	/* check again */
	links_count = pg_brick_links_count_get(west_brick, west_brick, &error);
	g_assert(!error);
	g_assert(links_count == 0);
	links_count = pg_brick_links_count_get(west_brick, middle_brick, &error);
	g_assert(!error);
	g_assert(links_count == 0);
	links_count = pg_brick_links_count_get(west_brick, east_brick, &error);
	g_assert(!error);
	g_assert(links_count == 0);

	links_count = pg_brick_links_count_get(middle_brick, middle_brick, &error);
	g_assert(!error);
	g_assert(links_count == 0);
	links_count = pg_brick_links_count_get(middle_brick, west_brick, &error);
	g_assert(!error);
	g_assert(links_count == 0);
	links_count = pg_brick_links_count_get(middle_brick, east_brick, &error);
	g_assert(!error);
	g_assert(links_count == 0);

	links_count = pg_brick_links_count_get(east_brick, east_brick, &error);
	g_assert(!error);
	g_assert(links_count == 0);
	links_count = pg_brick_links_count_get(east_brick, west_brick, &error);
	g_assert(!error);
	g_assert(links_count == 0);
	links_count = pg_brick_links_count_get(east_brick, middle_brick, &error);
	g_assert(!error);
	g_assert(links_count == 0);

	/* destroy */
	pg_brick_decref(west_brick, &error);
	g_assert(!error);
	pg_brick_decref(middle_brick, &error);
	g_assert(!error);
	pg_brick_decref(east_brick, &error);
	g_assert(!error);

	pg_brick_config_free(config);
}