Added tests for bio_reader_t
authorTobias Brunner <tobias@strongswan.org>
Tue, 4 Jun 2013 14:25:22 +0000 (16:25 +0200)
committerTobias Brunner <tobias@strongswan.org>
Tue, 11 Jun 2013 09:03:13 +0000 (11:03 +0200)
src/libstrongswan/tests/Makefile.am
src/libstrongswan/tests/test_bio_reader.c [new file with mode: 0644]
src/libstrongswan/tests/test_runner.c
src/libstrongswan/tests/test_runner.h

index babbb28..067bbd2 100644 (file)
@@ -5,8 +5,8 @@ check_PROGRAMS = $(TESTS)
 test_runner_SOURCES = \
   test_runner.c test_runner.h \
   test_linked_list.c test_enumerator.c test_linked_list_enumerator.c \
 test_runner_SOURCES = \
   test_runner.c test_runner.h \
   test_linked_list.c test_enumerator.c test_linked_list_enumerator.c \
-  test_chunk.c test_enum.c test_hashtable.c test_identification.c \
-  test_threading.c test_utils.c
+  test_bio_reader.c test_chunk.c test_enum.c test_hashtable.c \
+  test_identification.c test_threading.c test_utils.c
 
 test_runner_CFLAGS = \
   -I$(top_srcdir)/src/libstrongswan \
 
 test_runner_CFLAGS = \
   -I$(top_srcdir)/src/libstrongswan \
diff --git a/src/libstrongswan/tests/test_bio_reader.c b/src/libstrongswan/tests/test_bio_reader.c
new file mode 100644 (file)
index 0000000..f2df1e2
--- /dev/null
@@ -0,0 +1,458 @@
+/*
+ * Copyright (C) 2013 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <check.h>
+
+#include <bio/bio_reader.h>
+
+/*******************************************************************************
+ * different integer reads
+ */
+
+#define assert_integer_read(data, bits, val) ({ \
+       bio_reader_t *reader = bio_reader_create(data); \
+       typeof(val) i; \
+       for (i = 0; reader->remaining(reader) >= (bits / 8); i++) \
+       { \
+               ck_assert(reader->read_uint##bits(reader, &val)); \
+               ck_assert_int_eq(i, val); \
+       } \
+       ck_assert_int_eq(i, data.len / (bits / 8)); \
+       ck_assert_int_eq(reader->remaining(reader), data.len % (bits / 8)); \
+       ck_assert(!reader->read_uint##bits(reader, &val)); \
+       reader->destroy(reader); \
+})
+
+#define assert_integer_read_uneven(data, bits, val) ({ \
+       int i; \
+       for (i = 0; i <= bits / 8; i++, data.len++) \
+       { \
+               assert_integer_read(data, bits, val); \
+       } \
+})
+
+#define assert_basic_read(bits, val) ({ \
+       chunk_t data; \
+       data = chunk_empty; \
+       assert_integer_read(data, bits, val); \
+       data = chunk_alloca(bits / 8); \
+       memset(data.ptr, 0, data.len); \
+       data.len = 0; \
+       assert_integer_read_uneven(data, bits, val); \
+})
+
+#define assert_extended_read(data, bits, val) ({ \
+       chunk_t extended = chunk_alloca(data.len + bits / 8); \
+       memset(extended.ptr, 0, extended.len); \
+       extended.ptr[extended.len - 1] = data.len / (bits / 8); \
+       memcpy(extended.ptr, data.ptr, data.len); \
+       extended.len = data.len; \
+       assert_integer_read_uneven(extended, bits, val); \
+})
+
+START_TEST(test_read_uint8)
+{
+       chunk_t data = chunk_from_chars(0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07);
+       u_int8_t val;
+
+       assert_integer_read(data, 8, val);
+       assert_basic_read(8, val);
+       assert_extended_read(data, 8, val);
+}
+END_TEST
+
+START_TEST(test_read_uint16)
+{
+       chunk_t data = chunk_from_chars(0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03);
+       u_int16_t val;
+
+       assert_integer_read(data, 16, val);
+       assert_basic_read(16, val);
+       assert_extended_read(data, 16, val);
+}
+END_TEST
+
+START_TEST(test_read_uint24)
+{
+       chunk_t data = chunk_from_chars(0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03);
+       u_int32_t val;
+
+       assert_integer_read(data, 24, val);
+       assert_basic_read(24, val);
+       assert_extended_read(data, 24, val);
+}
+END_TEST
+
+START_TEST(test_read_uint32)
+{
+       chunk_t data = chunk_from_chars(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+                                                                       0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03);
+       u_int32_t val;
+
+       assert_integer_read(data, 32, val);
+       assert_basic_read(32, val);
+       assert_extended_read(data, 32, val);
+}
+END_TEST
+
+START_TEST(test_read_uint64)
+{
+       chunk_t data = chunk_from_chars(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+                                                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+                                                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03);
+       u_int64_t val;
+
+       assert_integer_read(data, 64, val);
+       assert_basic_read(64, val);
+       assert_extended_read(data, 64, val);
+}
+END_TEST
+
+/*******************************************************************************
+ * different integer reads from the end of a buffer
+ */
+
+#define assert_integer_read_end(data, bits, val) ({ \
+       bio_reader_t *reader = bio_reader_create(data); \
+       typeof(val) i; \
+       for (i = 0; reader->remaining(reader) >= (bits / 8); i++) \
+       { \
+               ck_assert(reader->read_uint##bits##_end(reader, &val)); \
+               ck_assert_int_eq(i, val); \
+       } \
+       ck_assert_int_eq(i, data.len / (bits / 8)); \
+       ck_assert_int_eq(reader->remaining(reader), data.len % (bits / 8)); \
+       ck_assert(!reader->read_uint##bits##_end(reader, &val)); \
+       reader->destroy(reader); \
+})
+
+#define assert_integer_read_end_uneven(data, bits, val) ({ \
+       int i; \
+       data.ptr += bits / 8; \
+       for (i = 0; i <= bits / 8; i++, data.ptr--, data.len++) \
+       { \
+               assert_integer_read_end(data, bits, val); \
+       } \
+})
+
+#define assert_basic_read_end(bits, val) ({ \
+       chunk_t data; \
+       data = chunk_empty; \
+       assert_integer_read_end(data, bits, val); \
+       data = chunk_alloca(bits / 8); \
+       memset(data.ptr, 0, data.len); \
+       data.len = 0; \
+       assert_integer_read_end_uneven(data, bits, val); \
+})
+
+#define assert_extended_read_end(data, bits, val) ({ \
+       chunk_t extended = chunk_alloca(data.len + bits / 8); \
+       memset(extended.ptr, 0, extended.len); \
+       extended.ptr[bits / 8 - 1] = data.len / (bits / 8); \
+       memcpy(extended.ptr + bits / 8, data.ptr, data.len); \
+       extended.len = data.len; \
+       assert_integer_read_end_uneven(extended, bits, val); \
+})
+
+START_TEST(test_read_uint8_end)
+{
+       chunk_t data = chunk_from_chars(0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00);
+       u_int8_t val;
+
+       assert_integer_read_end(data, 8, val);
+       assert_basic_read_end(8, val);
+       assert_extended_read_end(data, 8, val);
+}
+END_TEST
+
+START_TEST(test_read_uint16_end)
+{
+       chunk_t data = chunk_from_chars(0x00, 0x03, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00);
+       u_int16_t val;
+
+       assert_integer_read_end(data, 16, val);
+       assert_basic_read_end(16, val);
+       assert_extended_read_end(data, 16, val);
+}
+END_TEST
+
+START_TEST(test_read_uint24_end)
+{
+       chunk_t data = chunk_from_chars(0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00);
+       u_int32_t val;
+
+       assert_integer_read_end(data, 24, val);
+       assert_basic_read_end(24, val);
+       assert_extended_read_end(data, 24, val);
+}
+END_TEST
+
+START_TEST(test_read_uint32_end)
+{
+       chunk_t data = chunk_from_chars(0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02,
+                                                                       0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00);
+       u_int32_t val;
+
+       assert_integer_read_end(data, 32, val);
+       assert_basic_read_end(32, val);
+       assert_extended_read_end(data, 32, val);
+}
+END_TEST
+
+START_TEST(test_read_uint64_end)
+{
+       chunk_t data = chunk_from_chars(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+                                                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+                                                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+                                                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+       u_int64_t val;
+
+       assert_integer_read_end(data, 64, val);
+       assert_basic_read_end(64, val);
+       assert_extended_read_end(data, 64, val);
+}
+END_TEST
+
+/*******************************************************************************
+ * read data
+ */
+
+static inline void assert_reader_after_read(bio_reader_t *reader, chunk_t data)
+{
+       chunk_t peek;
+
+       ck_assert_int_eq(reader->remaining(reader), data.len);
+       peek = reader->peek(reader);
+       ck_assert_int_eq(reader->remaining(reader), data.len);
+       ck_assert(peek.ptr == data.ptr);
+       data.ptr != NULL ? ck_assert(chunk_equals(peek, data))
+                                        : ck_assert(peek.ptr == NULL);
+}
+
+START_TEST(test_read_data)
+{
+       chunk_t read, data = chunk_from_chars(0x00, 0x00, 0x00, 0x00);
+       bio_reader_t *reader;
+
+       reader = bio_reader_create(chunk_empty);
+       ck_assert_int_eq(reader->remaining(reader), 0);
+       ck_assert(reader->read_data(reader, 0, &read));
+       ck_assert(!reader->read_data(reader, 1, &read));
+       reader->destroy(reader);
+
+       reader = bio_reader_create(data);
+       ck_assert(reader->read_data(reader, 0, &read));
+       ck_assert_int_eq(read.len, 0);
+       ck_assert(read.ptr == data.ptr);
+       assert_reader_after_read(reader, data);
+
+       ck_assert(reader->read_data(reader, 1, &read));
+       ck_assert_int_eq(read.len, 1);
+       ck_assert(read.ptr == data.ptr);
+       assert_reader_after_read(reader, chunk_skip(data, 1));
+
+       ck_assert(reader->read_data(reader, 2, &read));
+       ck_assert_int_eq(read.len, 2);
+       ck_assert(read.ptr == data.ptr + 1);
+       assert_reader_after_read(reader, chunk_skip(data, 3));
+
+       ck_assert(!reader->read_data(reader, 2, &read));
+       ck_assert(reader->read_data(reader, 1, &read));
+       ck_assert_int_eq(read.len, 1);
+       ck_assert(read.ptr == data.ptr + 3);
+       assert_reader_after_read(reader, chunk_skip(data, 4));
+
+       ck_assert_int_eq(reader->remaining(reader), 0);
+       ck_assert(reader->read_data(reader, 0, &read));
+       ck_assert(!reader->read_data(reader, 1, &read));
+       reader->destroy(reader);
+}
+END_TEST
+
+START_TEST(test_read_data_end)
+{
+       chunk_t read, data = chunk_from_chars(0x00, 0x00, 0x00, 0x00);
+       bio_reader_t *reader;
+
+       reader = bio_reader_create(chunk_empty);
+       ck_assert_int_eq(reader->remaining(reader), 0);
+       ck_assert(reader->read_data_end(reader, 0, &read));
+       ck_assert(!reader->read_data_end(reader, 1, &read));
+       reader->destroy(reader);
+
+       reader = bio_reader_create(data);
+       ck_assert(reader->read_data_end(reader, 0, &read));
+       ck_assert_int_eq(read.len, 0);
+       ck_assert(read.ptr == data.ptr + data.len);
+       assert_reader_after_read(reader, data);
+
+       ck_assert(reader->read_data_end(reader, 1, &read));
+       ck_assert_int_eq(read.len, 1);
+       data.len--;
+       ck_assert(read.ptr == data.ptr + data.len);
+       assert_reader_after_read(reader, data);
+
+       ck_assert(reader->read_data_end(reader, 2, &read));
+       ck_assert_int_eq(read.len, 2);
+       data.len -= 2;
+       ck_assert(read.ptr == data.ptr + data.len);
+       assert_reader_after_read(reader, data);
+
+       ck_assert(!reader->read_data(reader, 2, &read));
+       ck_assert(reader->read_data(reader, 1, &read));
+       ck_assert_int_eq(read.len, 1);
+       ck_assert(read.ptr == data.ptr);
+       assert_reader_after_read(reader, chunk_empty);
+
+       ck_assert_int_eq(reader->remaining(reader), 0);
+       ck_assert(reader->read_data(reader, 0, &read));
+       ck_assert(!reader->read_data(reader, 1, &read));
+       reader->destroy(reader);
+}
+END_TEST
+
+/*******************************************************************************
+ * read length followed by data
+ */
+
+#define assert_read_data_len(bits) ({ \
+       bio_reader_t *reader; \
+       chunk_t read, data; \
+       int i, len = bits / 8; \
+       data = chunk_empty; \
+       reader = bio_reader_create(data); \
+       ck_assert(!reader->read_data##bits(reader, &read)); \
+       reader->destroy(reader); \
+       data = chunk_alloca(len + 8); \
+       memset(data.ptr, 0, data.len); \
+       for (i = 0; i <= 8; i++) \
+       { \
+               data.ptr[len - 1] = i; \
+               data.len = len + i; \
+               reader = bio_reader_create(data); \
+               ck_assert(reader->read_data##bits(reader, &read)); \
+               ck_assert_int_eq(reader->remaining(reader), 0); \
+               ck_assert_int_eq(read.len, i); \
+               ck_assert((!read.ptr && !read.len) || (read.ptr == data.ptr + len)); \
+               reader->destroy(reader); \
+       } \
+       data.ptr[len - 1] = i; \
+       reader = bio_reader_create(data); \
+       ck_assert(!reader->read_data##bits(reader, &read)); \
+       reader->destroy(reader); \
+})
+
+START_TEST(test_read_data8)
+{
+       assert_read_data_len(8);
+}
+END_TEST
+
+START_TEST(test_read_data16)
+{
+       assert_read_data_len(16);
+}
+END_TEST
+
+START_TEST(test_read_data24)
+{
+       assert_read_data_len(24);
+}
+END_TEST
+
+START_TEST(test_read_data32)
+{
+       assert_read_data_len(32);
+}
+END_TEST
+
+/*******************************************************************************
+ * test constructors
+ */
+
+START_TEST(test_create)
+{
+       chunk_t data = chunk_from_str("foobar");
+       bio_reader_t *reader;
+
+       lib->leak_detective->set_state(lib->leak_detective, TRUE);
+
+       data = chunk_clone(data);
+       reader = bio_reader_create(data);
+       reader->destroy(reader);
+       chunk_free(&data);
+
+       ck_assert_int_eq(lib->leak_detective->leaks(lib->leak_detective), 0);
+}
+END_TEST
+
+START_TEST(test_create_own)
+{
+       chunk_t data = chunk_from_str("foobar");
+       bio_reader_t *reader;
+
+       lib->leak_detective->set_state(lib->leak_detective, TRUE);
+
+       data = chunk_clone(data);
+       reader = bio_reader_create_own(data);
+       reader->destroy(reader);
+
+       ck_assert_int_eq(lib->leak_detective->leaks(lib->leak_detective), 0);
+}
+END_TEST
+
+Suite *bio_reader_suite_create()
+{
+       Suite *s;
+       TCase *tc;
+
+       s = suite_create("bio_reader");
+
+       tc = tcase_create("integer reads");
+       tcase_add_test(tc, test_read_uint8);
+       tcase_add_test(tc, test_read_uint16);
+       tcase_add_test(tc, test_read_uint24);
+       tcase_add_test(tc, test_read_uint32);
+       tcase_add_test(tc, test_read_uint64);
+       suite_add_tcase(s, tc);
+
+       tc = tcase_create("integer reads from end");
+       tcase_add_test(tc, test_read_uint8_end);
+       tcase_add_test(tc, test_read_uint16_end);
+       tcase_add_test(tc, test_read_uint24_end);
+       tcase_add_test(tc, test_read_uint32_end);
+       tcase_add_test(tc, test_read_uint64_end);
+       suite_add_tcase(s, tc);
+
+       tc = tcase_create("data reads and peek");
+       tcase_add_test(tc, test_read_data);
+       tcase_add_test(tc, test_read_data_end);
+       suite_add_tcase(s, tc);
+
+       tc = tcase_create("data length reads");
+       tcase_add_test(tc, test_read_data8);
+       tcase_add_test(tc, test_read_data16);
+       tcase_add_test(tc, test_read_data24);
+       tcase_add_test(tc, test_read_data32);
+       suite_add_tcase(s, tc);
+
+       tc = tcase_create("constructors");
+       tcase_add_test(tc, test_create);
+       tcase_add_test(tc, test_create_own);
+       suite_add_tcase(s, tc);
+
+       return s;
+}
index f00226a..1af3d66 100644 (file)
@@ -24,7 +24,8 @@ int main()
        SRunner *sr;
        int nf;
 
        SRunner *sr;
        int nf;
 
-       /* if a test fails there is no cleanup, so disable leak detective */
+       /* test cases are forked and there is no cleanup, so disable leak detective.
+        * can be enabled for individual tests with leak_detective_t.set_state */
        setenv("LEAK_DETECTIVE_DISABLE", "1", 1);
        /* redirect all output to stderr (to redirect make's stdout to /dev/null) */
        dup2(2, 1);
        setenv("LEAK_DETECTIVE_DISABLE", "1", 1);
        /* redirect all output to stderr (to redirect make's stdout to /dev/null) */
        dup2(2, 1);
@@ -32,6 +33,7 @@ int main()
        library_init(NULL);
 
        sr = srunner_create(NULL);
        library_init(NULL);
 
        sr = srunner_create(NULL);
+       srunner_add_suite(sr, bio_reader_suite_create());
        srunner_add_suite(sr, chunk_suite_create());
        srunner_add_suite(sr, enum_suite_create());
        srunner_add_suite(sr, enumerator_suite_create());
        srunner_add_suite(sr, chunk_suite_create());
        srunner_add_suite(sr, enum_suite_create());
        srunner_add_suite(sr, enumerator_suite_create());
index 3a6253a..8798b62 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <check.h>
 
 
 #include <check.h>
 
+Suite *bio_reader_suite_create();
 Suite *chunk_suite_create();
 Suite *enum_suite_create();
 Suite *enumerator_suite_create();
 Suite *chunk_suite_create();
 Suite *enum_suite_create();
 Suite *enumerator_suite_create();