From fec2a3dd05e2e78fd22c402deb356b2ddad49c46 Mon Sep 17 00:00:00 2001 From: Ulrich Eckhardt Date: Sun, 26 Jun 2016 21:15:44 +0200 Subject: [PATCH] memblockq-test: Add a test for missing data behaviour This involves in particular pa_memblockq_missing() and pa_memblockq_pop_missing(). The test demonstrates that the latter doesn't work as expected. It should report whenever queue level is drained below target level. Instead, it reports any case that the queue level is drained, even when it is still above target level. --- src/tests/memblockq-test.c | 112 +++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/src/tests/memblockq-test.c b/src/tests/memblockq-test.c index d08778e9c..3673f84b6 100644 --- a/src/tests/memblockq-test.c +++ b/src/tests/memblockq-test.c @@ -408,6 +408,116 @@ START_TEST (memblockq_test_length_changes) { } END_TEST +START_TEST (memblockq_test_pop_missing) { + pa_mempool *p; + pa_memblockq *bq; + pa_memchunk silence, data, chunk; + pa_sample_spec ss = { + .format = PA_SAMPLE_S16BE, + .rate = 48000, + .channels = 1 + }; + int64_t idx = 0; + size_t maxlength = 200; + size_t tlength = 100; + size_t prebuf = 0; + size_t minreq = 80; + size_t maxrewind = 0; + + p = pa_mempool_new(PA_MEM_TYPE_PRIVATE, 0, true); + ck_assert_ptr_ne(p, NULL); + + silence = memchunk_from_str(p, "____"); + data = memchunk_from_str(p, "1234567890"); + + 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 */ + ck_assert_int_eq(pa_memblockq_missing(bq), tlength); + ck_assert_int_eq(pa_memblockq_pop_missing(bq), tlength); + + /* add 20 bytes of data */ + for (int i = 0; i != 2; ++i) + ck_assert_int_eq(pa_memblockq_push(bq, &data), 0); + check_queue_invariants(bq); + + /* the missing bytes are reduced, but no new missing data is reported */ + ck_assert_int_eq(pa_memblockq_missing(bq), tlength - 20); + ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0); + + /* fill up to 100 bytes of data */ + 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 */ + ck_assert_int_eq(pa_memblockq_missing(bq), 0); + ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0); + + /* pop 40 bytes of data, down to 60 bytes fill level */ + 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 */ + ck_assert_int_eq(pa_memblockq_missing(bq), 0); + ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0); + + /* add 30 bytes of data, up to 90 bytes fill level */ + 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. */ + ck_assert_int_eq(pa_memblockq_missing(bq), 0); + ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0); + + /* pop 20 bytes of data, down to 70 bytes of data */ + 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 */ + ck_assert_int_eq(pa_memblockq_missing(bq), 0); + ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0); + + /* add 50 bytes of data, up to 120 bytes fill level */ + 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. */ + ck_assert_int_eq(pa_memblockq_missing(bq), 0); + ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0); + + /* pop 20 bytes of data, down the target level */ + 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_missing(bq), 0); + ck_assert_int_eq(pa_memblockq_pop_missing(bq), 0); + + /* cleanup */ + pa_memblockq_free(bq); + pa_memblock_unref(silence.memblock); + pa_memblock_unref(data.memblock); + pa_mempool_unref(p); +} +END_TEST + START_TEST (pop_missing_test) { int ret; size_t missing; @@ -487,6 +597,7 @@ START_TEST (pop_missing_test) { } END_TEST + int main(int argc, char *argv[]) { int failed = 0; Suite *s; @@ -502,6 +613,7 @@ int main(int argc, char *argv[]) { tcase_add_test(tc, memblockq_test_initial_properties); tcase_add_test(tc, memblockq_test); tcase_add_test(tc, memblockq_test_length_changes); + tcase_add_test(tc, memblockq_test_pop_missing); tcase_add_test(tc, pop_missing_test); suite_add_tcase(s, tc);