libqb/0002-TEST-check-for-a-single-job-causing-a-cpu-spin.patch
Angus Salkeld 09152fda3e Fix #787196
Signed-off-by: Angus Salkeld <asalkeld@redhat.com>
2012-02-06 22:40:21 +11:00

128 lines
3.2 KiB
Diff

From 7d2739fdd23e118bbaa42b3c43381b88ea842c88 Mon Sep 17 00:00:00 2001
From: Angus Salkeld <asalkeld@redhat.com>
Date: Sat, 4 Feb 2012 12:28:45 +1100
Subject: [PATCH 2/3] TEST: check for a single job causing a cpu spin
Signed-off-by: Angus Salkeld <asalkeld@redhat.com>
---
tests/check_loop.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 61 insertions(+), 2 deletions(-)
diff --git a/tests/check_loop.c b/tests/check_loop.c
index 50e80da..eb79a51 100644
--- a/tests/check_loop.c
+++ b/tests/check_loop.c
@@ -60,6 +60,7 @@ static void job_1_r(void *data)
res = qb_loop_job_add(l, QB_LOOP_MED, data, job_2);
ck_assert_int_eq(res, 0);
}
+
static void job_1_add_nuts(void *data)
{
int32_t res;
@@ -153,7 +154,6 @@ START_TEST(test_loop_job_4)
}
END_TEST
-
START_TEST(test_loop_job_nuts)
{
int32_t res;
@@ -169,6 +169,53 @@ START_TEST(test_loop_job_nuts)
}
END_TEST
+static qb_util_stopwatch_t *rl_sw;
+#define RATE_LIMIT_RUNTIME_SEC 3
+
+static void job_add_self(void *data)
+{
+ int32_t res;
+ uint64_t elapsed1;
+ qb_loop_t *l = (qb_loop_t *)data;
+
+ job_1_run_count++;
+ qb_util_stopwatch_stop(rl_sw);
+ elapsed1 = qb_util_stopwatch_us_elapsed_get(rl_sw);
+ if (elapsed1 > (RATE_LIMIT_RUNTIME_SEC * QB_TIME_US_IN_SEC)) {
+ /* run for 3 seconds */
+ qb_loop_stop(l);
+ return;
+ }
+ res = qb_loop_job_add(l, QB_LOOP_MED, data, job_add_self);
+ ck_assert_int_eq(res, 0);
+}
+
+START_TEST(test_job_rate_limit)
+{
+ int32_t res;
+ qb_loop_t *l = qb_loop_create();
+ fail_if(l == NULL);
+
+ rl_sw = qb_util_stopwatch_create();
+ fail_if(rl_sw == NULL);
+
+ qb_util_stopwatch_start(rl_sw);
+
+ res = qb_loop_job_add(l, QB_LOOP_MED, l, job_add_self);
+ ck_assert_int_eq(res, 0);
+
+ qb_loop_run(l);
+ /*
+ * the test is to confirm that a single job does not run away
+ * and cause cpu spin. We are going to say that a spin is more than
+ * one job per 50ms if there is only one job pending in the loop.
+ */
+ _ck_assert_int(job_1_run_count, <, (RATE_LIMIT_RUNTIME_SEC * (QB_TIME_MS_IN_SEC/50)) + 1);
+ qb_loop_destroy(l);
+ qb_util_stopwatch_free(rl_sw);
+}
+END_TEST
+
static Suite *loop_job_suite(void)
{
TCase *tc;
@@ -188,6 +235,12 @@ static Suite *loop_job_suite(void)
tc = tcase_create("run_500");
tcase_add_test(tc, test_loop_job_nuts);
+ tcase_set_timeout(tc, 5);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("rate_limit");
+ tcase_add_test(tc, test_job_rate_limit);
+ tcase_set_timeout(tc, 5);
suite_add_tcase(s, tc);
return s;
@@ -465,12 +518,17 @@ static Suite *loop_timer_suite(void)
tcase_add_test(tc, test_loop_timer_expire_leak);
tcase_set_timeout(tc, 30);
suite_add_tcase(s, tc);
+ return s;
+}
+static Suite *loop_signal_suite(void)
+{
+ TCase *tc;
+ Suite *s = suite_create("loop_signal_suite");
tc = tcase_create("signals");
tcase_add_test(tc, test_loop_sig_handling);
tcase_set_timeout(tc, 10);
suite_add_tcase(s, tc);
-
return s;
}
@@ -479,6 +537,7 @@ int32_t main(void)
int32_t number_failed;
SRunner *sr = srunner_create(loop_job_suite());
srunner_add_suite (sr, loop_timer_suite());
+ srunner_add_suite (sr, loop_signal_suite());
qb_log_init("check", LOG_USER, LOG_EMERG);
qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
--
1.7.7.6