Signed-off-by: Fedor Lyakhov <fedor.lyak...@gmail.com> --- tests/Makefile | 3 + tests/test-dhcp-vendopt.c | 203 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 206 insertions(+) create mode 100644 tests/test-dhcp-vendopt.c
diff --git a/tests/Makefile b/tests/Makefile index 88f7105..e82914e 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -55,6 +55,8 @@ gcov-files-test-mul64-y = util/host-utils.c check-unit-y += tests/test-int128$(EXESUF) # all code tested by test-int128 is inside int128.h gcov-files-test-int128-y = +check-unit-y = tests/test-dhcp-vendopt$(EXESUF) +gcov-files-test-dhcp-vendopt-y = slirp/dhcp_vendopt.c check-unit-y += tests/test-bitops$(EXESUF) check-unit-y += tests/test-qdev-global-props$(EXESUF) check-unit-y += tests/check-qom-interface$(EXESUF) @@ -246,6 +248,7 @@ tests/test-opts-visitor$(EXESUF): tests/test-opts-visitor.o $(test-qapi-obj-y) l tests/test-mul64$(EXESUF): tests/test-mul64.o libqemuutil.a tests/test-bitops$(EXESUF): tests/test-bitops.o libqemuutil.a +tests/test-dhcp-vendopt$(EXESUF): tests/test-dhcp-vendopt.o slirp/dhcp_vendopt.o libqos-obj-y = tests/libqos/pci.o tests/libqos/fw_cfg.o libqos-obj-y += tests/libqos/i2c.o diff --git a/tests/test-dhcp-vendopt.c b/tests/test-dhcp-vendopt.c new file mode 100644 index 0000000..9eb500c --- /dev/null +++ b/tests/test-dhcp-vendopt.c @@ -0,0 +1,203 @@ +/* + * test-dhcp-vendopt.c: unit-tests for slirp/dhcp_vendoropt.c + * + * Copyright (c) 2014 Fedor Lyakhov <fedor.lyak...@gmail.com> + * + * 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 3 of the License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/> + */ + +#include <glib.h> +#include "slirp/slirp.h" + +typedef struct _test_data { + const char *in; + const size_t expected_out_len; + const uint8_t *expected_out; + const int expected_rc; +} test_data; + +static void fsetup(Slirp *slirp, const void *tdata) {} +static void fteardown(Slirp *slirp, const void *tdata) {} + +static void test_translate_dhcp_vendopt(Slirp *slirp, const void *tdata) +{ + size_t i; + const test_data *data = (test_data *) tdata; + int rc = translate_dhcp_vendopt(slirp, data->in); + + g_assert_cmpint(rc, ==, data->expected_rc); + g_assert_cmpint(slirp->dhcp_vendopt_len, ==, data->expected_out_len); + for (i = 0; i < data->expected_out_len; i++) { + g_assert_cmpuint(slirp->dhcp_vendopt[i], ==, data->expected_out[i]); + } +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + test_data data_null = { NULL, 0, NULL, 1 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/null", Slirp, + &data_null, fsetup, test_translate_dhcp_vendopt, fteardown); + + test_data data_empty = { "", 0, NULL, 0 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/empty", Slirp, + &data_empty, fsetup, test_translate_dhcp_vendopt, fteardown); + + test_data data_single = { "vendor_name", 13, + (uint8_t *)("\x2B\x0B""vendor_name"), 0 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/single", Slirp, + &data_single, fsetup, test_translate_dhcp_vendopt, fteardown); + + test_data data_single_tagged = { "1:vendor_name", 15, + (uint8_t *)("\x2B\x0D\x01\x0B""vendor_name"), 0 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/single_tagged", Slirp, + &data_single_tagged, fsetup, test_translate_dhcp_vendopt, fteardown); + + test_data data_multiple = { "1:vendor_name;2:http://www.example.com", 39, + (uint8_t *)("\x2B\x25\x01\x0B""vendor_name\x02\x16""http://www.example.com"), 0 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/multiple", Slirp, + &data_multiple, fsetup, test_translate_dhcp_vendopt, fteardown); + + test_data data_zero_tagged_first = { "0:1:vendor_name;2:http://www.example.com", 15, + (uint8_t *)("\x2B\x0D""1:vendor_name"), 0 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/zero_tagged_first", Slirp, + &data_zero_tagged_first, fsetup, test_translate_dhcp_vendopt, fteardown); + + test_data data_zero_tagged_second = { "1:vendor_name;0:2:http://www.example.com;3:ttt", 15, + (uint8_t *)("\x2B\x0D\x01\x0B""vendor_name"), 0 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/zero_tagged_second", Slirp, + &data_zero_tagged_second, fsetup, test_translate_dhcp_vendopt, fteardown); + + test_data data_not_tagged_first = { "vendor_name;2:http://www.example.com;3:ttt", 13, + (uint8_t *)("\x2B\x0B""vendor_name"), 0 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/not_tagged_first", Slirp, + &data_not_tagged_first, fsetup, test_translate_dhcp_vendopt, fteardown); + + test_data data_not_tagged_second = { "1:vendor_name;http://www.example.com;3:ttt", 15, + (uint8_t *)("\x2B\x0D\x01\x0B""vendor_name"), 0 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/not_tagged_second", Slirp, + &data_not_tagged_second, fsetup, test_translate_dhcp_vendopt, fteardown); + + test_data data_uint8_max_tagged_first = { "255:vendor_name;2:http://www.example.com;3:ttt", 17, + (uint8_t *)("\x2B\x0F""255:vendor_name"), 0 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/uint8_max_tagged_first", Slirp, + &data_uint8_max_tagged_first, fsetup, test_translate_dhcp_vendopt, fteardown); + + test_data data_uint8_max_tagged_second = { "1:vendor_name;255:http://www.example.com;3:ttt", 15, + (uint8_t *)("\x2B\x0D\x01\x0B""vendor_name"), 0 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/uint8_max_tagged_second", Slirp, + &data_uint8_max_tagged_second, fsetup, test_translate_dhcp_vendopt, fteardown); + + test_data data_boundary_tagged = { "127:vendor_name;128:http://www.example.com;254:ttt", 44, + (uint8_t *)("\x2B\x2A\x7F\x0B""vendor_name\x80\x16""http://www.example.com\xFE\x03""ttt"), 0 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/boundary_tagged", Slirp, + &data_boundary_tagged, fsetup, test_translate_dhcp_vendopt, fteardown); + + test_data data_over_boundary_tagged = { "300:vendor_name", 17, + (uint8_t *)("\x2B\x0F""300:vendor_name"), 0 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/over_boundary_tagged", Slirp, + &data_over_boundary_tagged, fsetup, test_translate_dhcp_vendopt, fteardown); + + test_data data_macaddr_alfa = { "AA:BB:CC:12:34:56", 19, + (uint8_t *)("\x2B\x11""AA:BB:CC:12:34:56"), 0 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/macaddr_alfa", Slirp, + &data_macaddr_alfa, fsetup, test_translate_dhcp_vendopt, fteardown); + + test_data data_macaddr_num = { "0:11:BB:CC:12:34:56", 19, + (uint8_t *)("\x2B\x11""11:BB:CC:12:34:56"), 0 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/macaddr_num", Slirp, + &data_macaddr_num, fsetup, test_translate_dhcp_vendopt, fteardown); + + test_data data_zero_padded_tags = { "001:vendor_name;02:ttt", 20, + (uint8_t *)("\x2B\x12\x01\x0B""vendor_name\x02\x03""ttt"), 0 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/zero_padded_tags", Slirp, + &data_zero_padded_tags, fsetup, test_translate_dhcp_vendopt, fteardown); + + test_data data_extra_zero_padded_tag = { "0007:vendor_name", 18, + (uint8_t *)("\x2B\x10""0007:vendor_name"), 0 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/extra_zero_padded_tag", Slirp, + &data_extra_zero_padded_tag, fsetup, test_translate_dhcp_vendopt, fteardown); + + /* TODO: ignore spaces around tags */ + test_data data_space_padded_tag = { " 1 :vendor_name", 18, + (uint8_t *)("\x2B\x10"" 1 :vendor_name"), 0 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/space_padded_tag", Slirp, + &data_space_padded_tag, fsetup, test_translate_dhcp_vendopt, fteardown); + + test_data data_space_padded_value = { "1: vendor_name ;2: ttt ", 24, + (uint8_t *)("\x2B\x16\x01\x0D"" vendor_name ""\x02\x05"" ttt "), 0 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/space_padded_value", Slirp, + &data_space_padded_value, fsetup, test_translate_dhcp_vendopt, fteardown); + + /* FIXME: should nothing be written in this case? */ + test_data data_empty_value_tagged = { "1:", 4, + (uint8_t *)("\x2B\x02\x01\x00"), 0 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/empty_value_tagged", Slirp, + &data_empty_value_tagged, fsetup, test_translate_dhcp_vendopt, fteardown); + + /* FIXME: should nothing be written in this case? */ + test_data data_multiple_empty_values = { "1:;2:", 6, + (uint8_t *)("\x2B\x04\x01\x00\x02\x00"), 0 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/multiple_empty_values", Slirp, + &data_multiple_empty_values, fsetup, test_translate_dhcp_vendopt, fteardown); + + test_data data_multiple_tag_delimiters = { "1::vendor_name", 16, + (uint8_t *)("\x2B\x0E\x01\x0C"":vendor_name"), 0 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/multiple_tag_delimiters", Slirp, + &data_multiple_tag_delimiters, fsetup, test_translate_dhcp_vendopt, fteardown); + + test_data data_multiple_option_delimiters = { ";1:vendor_name;;;2:ttt;;", 20, + (uint8_t *)("\x2B\x12\x01\x0B""vendor_name\x02\x03""ttt"), 0 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/multiple_option_delimiters", Slirp, + &data_multiple_option_delimiters, fsetup, test_translate_dhcp_vendopt, fteardown); + + test_data data_overflow_single = { +"vendornamevendornamevendornamevendornamevendornamevendornamevendornamevendorname" +"vendornamevendornamevendornamevendornamevendornamevendornamevendornamevendorname" +"vendornamevendornamevendornamevendornamevendornamevendornamevendornamevendorname" +"vendornamevendornamevendornamevendornamevendornamevendornamevendornamevendorname", + 0, NULL, 0 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/overflow_single", Slirp, + &data_overflow_single, fsetup, test_translate_dhcp_vendopt, fteardown); + + test_data data_overflow_single_tagged = { +"1:vendornamevendornamevendornamevendornamevendornamevendornamevendornamevendorname" +"vendornamevendornamevendornamevendornamevendornamevendornamevendornamevendorname" +"vendornamevendornamevendornamevendornamevendornamevendornamevendornamevendorname" +"vendornamevendornamevendornamevendornamevendornamevendornamevendornamevendorname", + 0, NULL, 0 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/overflow_single_tagged", Slirp, + &data_overflow_single_tagged, fsetup, test_translate_dhcp_vendopt, fteardown); + + test_data data_overflow_second = { +"1:vendor_name;2:vendornamevendornamevendornamevendornamevendornamevendornamevendorname" +"vendornamevendornamevendornamevendornamevendornamevendornamevendornamevendorname" +"vendornamevendornamevendornamevendornamevendornamevendornamevendornamevendorname" +"vendornamevendornamevendornamevendornamevendornamevendornamevendornamevendorname", + 15, (uint8_t *)("\x2B\x0D\x01\x0B""vendor_name"), 0 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/overflow_second", Slirp, + &data_overflow_second, fsetup, test_translate_dhcp_vendopt, fteardown); + + /* Each option is less than UINT8_MAX, but together they are greater. */ + test_data data_overflow_sum = { "1:vendor_name;2:vendorname" +"vendornamevendornamevendornamevendornamevendornamevendornamevendornamevendorname" +"vendornamevendornamevendornamevendornamevendornamevendornamevendornamevendorname" +"vendornamevendornamevendornamevendornamevendornamevendornamevendornamevendorname", + 15, (uint8_t *)("\x2B\x0D\x01\x0B""vendor_name"), 0 }; + g_test_add("/slirp/dhcp_vendopt/translate_dhcp_vendopt/verflow_sum", Slirp, + &data_overflow_sum, fsetup, test_translate_dhcp_vendopt, fteardown); + + return g_test_run(); +} -- 1.8.4.5