Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 21 Mar 2011 20:13:41 GMT
From:      John Baldwin <jhb@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 190346 for review
Message-ID:  <201103212013.p2LKDfSG067384@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@190346?ac=10

Change 190346 by jhb@jhb_jhbbsd on 2011/03/21 20:12:48

	Add an automated set of regression tests.

Affected files ...

.. //depot/projects/pci/sys/modules/rman/rman.c#3 edit

Differences ...

==== //depot/projects/pci/sys/modules/rman/rman.c#3 (text+ko) ====

@@ -12,6 +12,21 @@
 struct rman test;
 struct resource *r;
 
+/* XXX: Gross hack so we can do assertions.  Copied from subr_rman.c. */
+struct resource_i {
+	struct resource		r_r;
+	TAILQ_ENTRY(resource_i)	r_link;
+	LIST_ENTRY(resource_i)	r_sharelink;
+	LIST_HEAD(, resource_i)	*r_sharehead;
+	u_long	r_start;	/* index of the first entry in this resource */
+	u_long	r_end;		/* index of the last entry (inclusive) */
+	u_int	r_flags;
+	void	*r_virtual;	/* virtual address of this resource */
+	struct	device *r_dev;	/* device which has allocated this resource */
+	struct	rman *r_rm;	/* resource manager from whence this came */
+	int	r_rid;		/* optional rid for this resource. */
+};
+
 SYSCTL_NODE(_debug, OID_AUTO, rman, CTLFLAG_RD, 0, "rman testing");
 
 static u_long start_value;
@@ -89,7 +104,153 @@
 SYSCTL_PROC(_debug_rman, OID_AUTO, release, CTLTYPE_INT | CTLFLAG_RW, 0, 0,
     sysctl_rman_release, "I", "release a resource");
 
+/* Verify that the resource manager is in a correct state. */
+static void
+assert_rman_ok(void)
+{
+	struct resource_i *i;
+
+	i = TAILQ_FIRST(&test.rm_list);
+	KASSERT(i != NULL, ("empty rman"));
+	KASSERT(i->r_start == 0, ("first entry does not start at 0"));
+	if (r == NULL) {
+		/* There should be one free entry for the entire region. */
+		KASSERT(i->r_flags == 0 && i->r_end == 100, ("bad entry"));
+		return;
+	}
+
+	/*
+	 * If r does not start at 0, then there should be one free entry
+	 * before r.
+	 */
+	if (rman_get_start(r) != 0) {
+		KASSERT(i->r_flags == 0 && i->r_end + 1 == rman_get_start(r),
+		    ("bogus first free entry"));
+		i = TAILQ_NEXT(i, r_link);
+	}
+
+	/*
+	 * 'i' should now be the entry holding allocated resource 'r'
+	 */
+	KASSERT(r == &i->r_r, ("resource mismatch"));
+	KASSERT(i->r_flags & RF_ALLOCATED, ("r not allocated"));
+
+	/*
+	 * If r does not end at 100, then there should be one free entry
+	 * after r.
+	 */
+	if (i->r_end != 100) {
+		i = TAILQ_NEXT(i, r_link);
+		KASSERT(i->r_flags == 0 && rman_get_end(r) + 1 == i->r_start,
+		    ("bogus last free entry"));
+	}
+
+	/* 'i' should now reference the last entry ending at 100. */
+	KASSERT(i->r_end == 100 && TAILQ_NEXT(i, r_link) == NULL,
+	    ("bad last entry"));
+}
+
+static void
+regression_tests(void)
+{
+	int error;
+
+#define ADJUST_SHOULD_FAIL(start, end, err) do {			\
+	error = rman_adjust_resource(r, (start), (end));		\
+	if (error == (err))						\
+		printf("Correctly failed to adjust to (%u, %u)\n",	\
+		    (start), (end));					\
+	else {								\
+		if (error)						\
+			printf("Failed to adjust to (%u, %u) with %d\n", \
+			    (start), (end), error);			\
+		else							\
+			printf("Incorrectly adjusted to (%lu, %lu)\n",	\
+			    rman_get_start(r), rman_get_end(r));	\
+		return;							\
+	}								\
+	assert_rman_ok();						\
+} while (0)
+
+#define ADJUST_SHOULD_WORK(start, end) do {				\
+	error = rman_adjust_resource(r, (start), (end));		\
+	if (error) {							\
+		printf("Failed to adjust to (%u, %u) with %d\n",	\
+		    (start), (end), error);				\
+		return;							\
+	}								\
+	if (rman_get_start(r) != (start) || rman_get_end(r) != (end)) {	\
+		printf("Adjusted incorrectly, tried (%u, %u),"		\
+		    " got (%lu, %lu)\n", (start), (end),		\
+		    rman_get_start(r), rman_get_end(r));		\
+		return;							\
+	}								\
+	printf("Adjusted to (%lu, %lu)\n", rman_get_start(r),		\
+	    rman_get_end(r));						\
+	assert_rman_ok();						\
+} while (0)
+
+	/* Allocate a range in the middle: 30-60. */
+	if (r != NULL)
+		rman_release_resource(r);
+	r = rman_reserve_resource(&test, 30, 60, 30, 0, NULL);
+	if (r == NULL) {
+		printf("Failed to allocate resource\n");
+		return;
+	}
+	printf("Allocated (%lu, %lu)\n", rman_get_start(r), rman_get_end(r));
+	assert_rman_ok();
+
+	/* Non-overlapping adjust regions should fail. */
+	ADJUST_SHOULD_FAIL(5, 10, EINVAL);
+	ADJUST_SHOULD_FAIL(5, 29, EINVAL);
+	ADJUST_SHOULD_FAIL(65, 70, EINVAL);
+	ADJUST_SHOULD_FAIL(61, 70, EINVAL);
+
+	/* Shrinking just one end should work. */
+	ADJUST_SHOULD_WORK(35, 60);
+	ADJUST_SHOULD_WORK(35, 55);
+
+	/* Expanding either end should work. */
+	ADJUST_SHOULD_WORK(30, 55);
+	ADJUST_SHOULD_WORK(30, 60);
+
+	/* Shrinking both ends. */
+	ADJUST_SHOULD_WORK(35, 55);
+
+	/* Expanding both ends. */
+	ADJUST_SHOULD_WORK(30, 60);
+
+	/* Shrinking one end, expanding the other. */
+	ADJUST_SHOULD_WORK(35, 65);
+	ADJUST_SHOULD_WORK(30, 60);
+
+	/* Only overlapping with old region at one end. */
+	ADJUST_SHOULD_WORK(60, 75);
+	ADJUST_SHOULD_WORK(30, 60);
+
+	/* Cleaning up. */
+	rman_release_resource(r);
+	r = NULL;
+	assert_rman_ok();
+}
+
 static int
+sysctl_rman_test(SYSCTL_HANDLER_ARGS)
+{
+	int error, i = 0;
+
+	error = sysctl_handle_int(oidp, &i, sizeof(i), req);
+	if (error || req->newptr == NULL || i == 0)
+		return (error);
+	regression_tests();
+	return (error);
+}
+SYSCTL_PROC(_debug_rman, OID_AUTO, test, CTLTYPE_INT | CTLFLAG_RW, 0, 0,
+    sysctl_rman_test, "I", "run regression tests");
+
+
+static int
 load(void)
 {
 	int error;
@@ -108,6 +269,7 @@
 		printf("Failed to manage region: %d\n", error);
 		unload();
 	}
+	assert_rman_ok();
 	return (error);
 }
 
@@ -116,8 +278,11 @@
 {
 	int error;
 
-	if (r != NULL)
+	if (r != NULL) {
+		assert_rman_ok();
 		rman_release_resource(r);
+	}
+	assert_rman_ok();
 	error = rman_fini(&test);
 	if (error)
 		printf("Failed to destroy rman: %d\n", error);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201103212013.p2LKDfSG067384>