summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTanu Kaskinen <tanuk@iki.fi>2016-12-30 17:52:36 +0200
committerTanu Kaskinen <tanuk@iki.fi>2017-01-03 04:26:30 +0200
commitb6e6e78cc26425fdd8667e51ffb5bf6459e7581c (patch)
treee058132871eff42cfd73eaff34056eefe97f7e23
parent8e9f07074716b248a17b2d044f3a4d27a2e70a32 (diff)
memblockq-test: fix incorrect assumption of pa_memblockq_pop_missing() behaviour
The intuitive meaning of "missing" would be the difference between tlength and the current queue length, and that's how memblockq-test assumed pa_memblockq_pop_missing() to define the term "missing", but that was an incorrect assumption, causing the last pa_memblockq_pop_missing() return value assertion to fail. This patch fixes the failing assertion and adds some comments about how the "missing" and "requested" variables in memblockq work.
-rw-r--r--src/tests/memblockq-test.c95
1 files changed, 75 insertions, 20 deletions
diff --git a/src/tests/memblockq-test.c b/src/tests/memblockq-test.c
index fc83d99d9..2a9b88a69 100644
--- a/src/tests/memblockq-test.c
+++ b/src/tests/memblockq-test.c
@@ -421,74 +421,129 @@ START_TEST (memblockq_test_pop_missing) {
bq = pa_memblockq_new("test memblockq", idx, maxlength, tlength, &ss, prebuf, minreq, maxrewind, &silence);
fail_unless(bq != NULL);
- /* initially, the whole target length of bytes is missing */
+ /* The following equation regarding the internal variables of a memblockq
+ * is always true:
+ *
+ * length + missing + requested = tlength
+ *
+ * "length" is the current memblockq length (write index minus read index)
+ * and "tlength" is the target length. The intuitive meaning of "missing"
+ * would be the difference between tlength and length, but actually
+ * "missing" and "requested" together constitute the amount that is missing
+ * from the queue. Writing to the queue decrements "requested" and reading
+ * from the queue increments "missing". pa_memblockq_pop_missing() resets
+ * "missing" to zero, returns the old "missing" value and adds the
+ * equivalent amount to "requested".
+ *
+ * This test has comments between each step documenting the assumed state
+ * of those internal variables. */
+
+ /* length + missing + requested = tlength
+ * 0 + 100 + 0 = 100 */
+
ck_assert_int_eq(pa_memblockq_pop_missing(bq), tlength);
- /* add 20 bytes of data */
+ /* length + missing + requested = tlength
+ * 0 + 0 + 100 = 100 */
+
for (int i = 0; i != 2; ++i)
ck_assert_int_eq(pa_memblockq_push(bq, &data), 0);
check_queue_invariants(bq);
- /* no new missing data is reported */
+ /* length + missing + requested = tlength
+ * 20 + 0 + 80 = 100 */
+
ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0);
- /* fill up to 100 bytes of data */
+ /* length + missing + requested = tlength
+ * 20 + 0 + 80 = 100 */
+
for (int i = 0; i != 8; ++i)
ck_assert_int_eq(pa_memblockq_push(bq, &data), 0);
check_queue_invariants(bq);
- /* queue fill level is at target level now */
+ /* length + missing + requested = tlength
+ * 100 + 0 + 0 = 100 */
+
ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0);
- /* pop 40 bytes of data, down to 60 bytes fill level */
+ /* length + missing + requested = tlength
+ * 100 + 0 + 0 = 100 */
+
ck_assert_int_eq(pa_memblockq_peek_fixed_size(bq, 40, &chunk), 0);
pa_memblockq_drop(bq, 40);
ck_assert_int_eq(chunk.length - chunk.index, 40);
pa_memblock_unref(chunk.memblock);
check_queue_invariants(bq);
- /* queue fill level is 40 bytes under target length
- * This is less than minreq, so no missing data is reported */
+ /* length + missing + requested = tlength
+ * 60 + 40 + 0 = 100 */
+
+ /* 40 bytes are missing, but that's less than minreq, so 0 is reported */
ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0);
- /* add 30 bytes of data, up to 90 bytes fill level */
+ /* length + missing + requested = tlength
+ * 60 + 40 + 0 = 100 */
+
+ /* Now we push 30 bytes even though it was not requested, so the requested
+ * counter goes negative! */
for (int i = 0; i != 3; ++i)
ck_assert_int_eq(pa_memblockq_push(bq, &data), 0);
check_queue_invariants(bq);
- /* queue fill level is 10 bytes under target length
- * This is less than minreq, so no missing data is reported. */
+ /* length + missing + requested = tlength
+ * 90 + 40 + -30 = 100 */
+
+ /* missing < minreq, so nothing is reported missing. */
ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0);
- /* pop 20 bytes of data, down to 70 bytes of data */
+ /* length + missing + requested = tlength
+ * 90 + 40 + -30 = 100 */
+
ck_assert_int_eq(pa_memblockq_peek_fixed_size(bq, 20, &chunk), 0);
pa_memblockq_drop(bq, 20);
ck_assert_int_eq(chunk.length - chunk.index, 20);
pa_memblock_unref(chunk.memblock);
check_queue_invariants(bq);
- /* queue fill level is 30 bytes under target length
- * This is less than minreq, so no missing data is reported */
+ /* length + missing + requested = tlength
+ * 70 + 60 + -30 = 100 */
+
+ /* missing < minreq, so nothing is reported missing. */
ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0);
- /* add 50 bytes of data, up to 120 bytes fill level */
+ /* length + missing + requested = tlength
+ * 70 + 60 + -30 = 100 */
+
+ /* We push more data again even though it was not requested, so the
+ * requested counter goes further into the negative range. */
for (int i = 0; i != 5; ++i)
ck_assert_int_eq(pa_memblockq_push(bq, &data), 0);
check_queue_invariants(bq);
- /* queue fill level is above target level, so no missing data is reported. */
+ /* length + missing + requested = tlength
+ * 120 + 60 + -80 = 100 */
+
+ /* missing < minreq, so nothing is reported missing. */
ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0);
- /* pop 20 bytes of data, down the target level */
+ /* length + missing + requested = tlength
+ * 120 + 60 + -80 = 100 */
+
ck_assert_int_eq(pa_memblockq_peek_fixed_size(bq, 20, &chunk), 0);
pa_memblockq_drop(bq, 20);
ck_assert_int_eq(chunk.length - chunk.index, 20);
pa_memblock_unref(chunk.memblock);
check_queue_invariants(bq);
- /* queue fill level is at target level now
- * No missing data should be reported. */
- ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0);
+ /* length + missing + requested = tlength
+ * 100 + 80 + -80 = 100 */
+
+ /* missing has now reached the minreq threshold */
+ ck_assert_int_eq(pa_memblockq_pop_missing(bq), 80);
+
+ /* length + missing + requested = tlength
+ * 100 + 0 + 0 = 100 */
/* cleanup */
pa_memblockq_free(bq);