From de73b255029b11b24fbd72750477f7d8ea0fcc90 Mon Sep 17 00:00:00 2001 From: Gregory Date: Sat, 2 Mar 2019 20:52:33 +0200 Subject: [PATCH] migrate from munit test to simple macros --- Makefile | 11 +- inc/t.h | 24 + inc/tests.h | 63 +- inc/tests_macros.h | 34 - lib/munit/COPYING | 21 - lib/munit/Makefile | 55 -- lib/munit/README.md | 54 -- lib/munit/example.c | 351 ------- lib/munit/meson.build | 37 - lib/munit/munit.c | 2055 ----------------------------------------- lib/munit/munit.h | 535 ----------- t/base64_tests.c | 34 +- t/md5_tests.c | 113 ++- t/sha_tests.c | 210 ++--- t/tests.c | 68 +- 15 files changed, 216 insertions(+), 3449 deletions(-) create mode 100644 inc/t.h delete mode 100644 inc/tests_macros.h delete mode 100644 lib/munit/COPYING delete mode 100644 lib/munit/Makefile delete mode 100644 lib/munit/README.md delete mode 100644 lib/munit/example.c delete mode 100644 lib/munit/meson.build delete mode 100644 lib/munit/munit.c delete mode 100644 lib/munit/munit.h diff --git a/Makefile b/Makefile index 44c4b195..6698fb9b 100644 --- a/Makefile +++ b/Makefile @@ -43,9 +43,6 @@ LIBFT_INC := -I $(LIBFT_DIR)includes/ LIBFT_LIB := -lft -L $(LIBFT_DIR) LIBFT = $(LIBFT_DIR)libft.a -MUINUT_DIR := $(LIB_DIR)munit/ -MUINUT_INC := -I $(MUINUT_DIR) - # project source files MD5_SRC = ft_md5.c \ @@ -126,9 +123,7 @@ SHA_TESTS += $(SHA_SRC) BASE64_TESTS = base64_tests.c BASE64_TESTS += $(BASE64_SRC) -TEST_SRC = tests.c \ - munit.c - +TEST_SRC = tests.c TEST_SRC += $(MD5_TESTS) \ $(SHA_TESTS) \ $(BASE64_TESTS) @@ -221,8 +216,6 @@ vpath %.c $(SRC_DIR) \ $(MD5_DIR) \ $(SHA_DIR) \ $(B64_DIR) \ - $(TST_DIR) \ - $(MUINUT_DIR) - + $(TST_DIR) .PHONY: all check clean fclean re multi diff --git a/inc/t.h b/inc/t.h new file mode 100644 index 00000000..88d4cce6 --- /dev/null +++ b/inc/t.h @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* t.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gtertysh +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2018/10/23 19:36:58 by gtertysh #+# #+# */ +/* Updated: 2018/10/23 19:40:12 by gtertysh ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef T_H +# define T_H +# include + +# define FAIL() printf("\nfail in %s() %s:%d\n\n", __func__, __FILE__, __LINE__) +# define _is(t) do { if (!(t)) { FAIL(); return 1; } } while(0) +# define _should(t) do { int r = t(); if(r) return r; } while(0) +# define _p_start(m) do { printf("%s\n", m); } while(0) +# define _verify(m, t) do { _p_start(m); int r = t(); if(r) return r; } while(0) +# define _end(m) do { printf(" %s - OK\n", m); return 0; } while(0) + +#endif diff --git a/inc/tests.h b/inc/tests.h index fbda3867..7c4ab775 100644 --- a/inc/tests.h +++ b/inc/tests.h @@ -13,65 +13,8 @@ #ifndef TESTS_H # define TESTS_H -# define MUNIT_ENABLE_ASSERT_ALIASES -# include "munit.h" +int md5_tests(void); +int sha_tests(void); +int base64_tests(void); -/* -** MD5 -*/ -MunitResult should_init_md5_ctx(const MunitParameter test_params[], - void *test_data); -MunitResult md5_update_change_count(const MunitParameter test_params[], - void *test_data); -MunitResult md5_decode_string_to_int(const MunitParameter test_params[], - void *test_data); -MunitResult md5_encode_bits_to_string(const MunitParameter test_params[], - void *test_data); -MunitResult md5_encode_register(const MunitParameter test_params[], - void *test_data); -MunitResult md5_create_digest(const MunitParameter test_params[], - void *test_data); -MunitResult md5_create_string(const MunitParameter test_params[], - void *test_data); - -/* -** SHA256 -*/ -MunitResult should_init_ctx_sha256(const MunitParameter test_params[], - void *test_data); -MunitResult decode_string_to_int_sha256(const MunitParameter test_params[], - void *test_data); -MunitResult encode_len_to_string_sha256(const MunitParameter test_params[], - void *test_data); -MunitResult encode_register_to_string_sha256(const MunitParameter test_params[], - void *test_data); -MunitResult update_bit_count_sha256(const MunitParameter test_params[], - void *test_data); -MunitResult fill_buffer_sha256(const MunitParameter test_params[], - void *test_data); -MunitResult add_right_padding_sha256(const MunitParameter test_params[], - void *test_data); -MunitResult compute_digest_sha256(const MunitParameter test_params[], - void *test_data); -MunitResult create_digest_string_sha256(const MunitParameter test_params[], - void *test_data); - -/* -** SHA224 -*/ -MunitResult should_init_ctx_sha224(const MunitParameter test_params[], - void *test_data); -MunitResult compute_digest_sha224(const MunitParameter test_params[], - void *test_data); -MunitResult create_digest_string_sha224(const MunitParameter test_params[], - void *test_data); - -/* -** BASE64 -*/ -MunitResult should_init_base64_ctx(const MunitParameter test_params[], - void *test_data); - -MunitResult should_transform_base64_block(const MunitParameter test_params[], - void *test_data); #endif diff --git a/inc/tests_macros.h b/inc/tests_macros.h deleted file mode 100644 index 583061c8..00000000 --- a/inc/tests_macros.h +++ /dev/null @@ -1,34 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* tests_macros.h :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: gtertysh +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2018/10/23 19:46:23 by gtertysh #+# #+# */ -/* Updated: 2018/10/23 19:46:33 by gtertysh ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#ifndef TESTS_MACROS_H -# define TESTS_MACROS_H - -# include "munit.h" - -# define UNUSED(x) (void)(x) - -# define TEST_RESULT MunitResult -# define TEST_PARAMS const MunitParameter test_params[] -# define TEST_DATA void *test_data -# define CASE(f) TEST_RESULT f(TEST_PARAMS, TEST_DATA) - -# define N(name) (char *)name -# define T(test_function) test_function -# define S(setup_function) setup_function -# define TD(tear_down_function) tear_down_function -# define O(options) options -# define P(paramenters) paramenters -# define IT(n, t, s, td, o, p) { N(n), T(t), S(s), TD(td), O(o), P(p) } -# define END_IT IT(NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL) - -#endif diff --git a/lib/munit/COPYING b/lib/munit/COPYING deleted file mode 100644 index 2991ac70..00000000 --- a/lib/munit/COPYING +++ /dev/null @@ -1,21 +0,0 @@ -µnit Testing Framework -Copyright (c) 2013-2016 Evan Nemerson - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/lib/munit/Makefile b/lib/munit/Makefile deleted file mode 100644 index 65d33fcc..00000000 --- a/lib/munit/Makefile +++ /dev/null @@ -1,55 +0,0 @@ -# Using µnit is very simple; just include the header and add the C -# file to your sources. That said, here is a simple Makefile to build -# the example. - -CSTD:=99 -OPENMP:=n -ASAN:=n -UBSAN:=n -EXTENSION:= -TEST_ENV:= -CFLAGS:= -AGGRESSIVE_WARNINGS=n - -ifeq ($(CC),pgcc) - CFLAGS+=-c$(CSTD) -else - CFLAGS+=-std=c$(CSTD) -endif - -ifeq ($(OPENMP),y) - ifeq ($(CC),pgcc) - CFLAGS+=-mp - else - CFLAGS+=-fopenmp - endif -endif - -ifneq ($(SANITIZER),) - CFLAGS+=-fsanitize=$(SANITIZER) -endif - -ifneq ($(CC),pgcc) - ifeq ($(EXTRA_WARNINGS),y) - CFLAGS+=-Wall -Wextra -Werror - endif - - ifeq ($(ASAN),y) - CFLAGS+=-fsanitize=address - endif - - ifeq ($(UBSAN),y) - CFLAGS+=-fsanitize=undefined - endif -endif - -example$(EXTENSION): munit.h munit.c example.c - $(CC) $(CFLAGS) -o $@ munit.c example.c - -test: - $(TEST_ENV) ./example$(EXTENSION) - -clean: - rm -f example$(EXTENSION) - -all: example$(EXTENSION) diff --git a/lib/munit/README.md b/lib/munit/README.md deleted file mode 100644 index 9f861f2a..00000000 --- a/lib/munit/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# µnit - -µnit is a small but full-featured unit testing framework for C. It has -no dependencies (beyond libc), is permissively licensed (MIT), and is -easy to include into any project. - -For more information, see -[the µnit web site](https://nemequ.github.io/munit). - -[![Build status](https://travis-ci.org/nemequ/munit.svg?branch=master)](https://travis-ci.org/nemequ/munit) -[![Windows build status](https://ci.appveyor.com/api/projects/status/db515g5ifcwjohq7/branch/master?svg=true)](https://ci.appveyor.com/project/quixdb/munit/branch/master) - -## Features - -Features µnit currently includes include: - - * Handy assertion macros which make for nice error messages. - * Reproducible cross-platform random number generation, including - support for supplying a seed via CLI. - * Timing of both wall-clock and CPU time. - * Parameterized tests. - * Nested test suites. - * Flexible CLI. - * Forking - ([except on Windows](https://github.com/nemequ/munit/issues/2)). - * Hiding output of successful tests. - -Features µnit does not currently include, but some day may include -(a.k.a., if you file a PR…), include: - - * [TAP](http://testanything.org/) support; feel free to discuss in - [issue #1](https://github.com/nemequ/munit/issues/1) - -### Include into your project with meson - -In your `subprojects` folder put a `munit.wrap` file containing: - -``` -[wrap-git] -directory=munit -url=https://github.com/nemequ/munit/ -revision=head -``` - -Then you can use a subproject fallback when you include munit as a -dependency to your project: `dependency('munit', fallback: ['munit', 'munit_dep'])` - -## Documentation - -See [the µnit web site](https://nemequ.github.io/munit). - -Additionally, there is a heavily-commented -[example.c](https://github.com/nemequ/munit/blob/master/example.c) in -the repository. diff --git a/lib/munit/example.c b/lib/munit/example.c deleted file mode 100644 index d238d093..00000000 --- a/lib/munit/example.c +++ /dev/null @@ -1,351 +0,0 @@ -/* Example file for using µnit. - * - * µnit is MIT-licensed, but for this file and this file alone: - * - * To the extent possible under law, the author(s) of this file have - * waived all copyright and related or neighboring rights to this - * work. See for - * details. - *********************************************************************/ - -#include "munit.h" - -/* This is just to disable an MSVC warning about conditional - * expressions being constant, which you shouldn't have to do for your - * code. It's only here because we want to be able to do silly things - * like assert that 0 != 1 for our demo. */ -#if defined(_MSC_VER) -#pragma warning(disable: 4127) -#endif - -/* Tests are functions that return void, and take a single void* - * parameter. We'll get to what that parameter is later. */ -static MunitResult -test_compare(const MunitParameter params[], void* data) { - /* We'll use these later */ - const unsigned char val_uchar = 'b'; - const short val_short = 1729; - double pi = 3.141592654; - char* stewardesses = "stewardesses"; - char* most_fun_word_to_type; - - /* These are just to silence compiler warnings about the parameters - * being unused. */ - (void) params; - (void) data; - - /* Let's start with the basics. */ - munit_assert(0 != 1); - - /* There is also the more verbose, though slightly more descriptive - munit_assert_true/false: */ - munit_assert_false(0); - - /* You can also call munit_error and munit_errorf yourself. We - * won't do it is used to indicate a failure, but here is what it - * would look like: */ - /* munit_error("FAIL"); */ - /* munit_errorf("Goodbye, cruel %s", "world"); */ - - /* There are macros for comparing lots of types. */ - munit_assert_char('a', ==, 'a'); - - /* Sure, you could just assert('a' == 'a'), but if you did that, a - * failed assertion would just say something like "assertion failed: - * val_uchar == 'b'". µnit will tell you the actual values, so a - * failure here would result in something like "assertion failed: - * val_uchar == 'b' ('X' == 'b')." */ - munit_assert_uchar(val_uchar, ==, 'b'); - - /* Obviously we can handle values larger than 'char' and 'uchar'. - * There are versions for char, short, int, long, long long, - * int8/16/32/64_t, as well as the unsigned versions of them all. */ - munit_assert_short(42, <, val_short); - - /* There is also support for size_t. - * - * The longest word in English without repeating any letters is - * "uncopyrightables", which has uncopyrightable (and - * dermatoglyphics, which is the study of fingerprints) beat by a - * character */ - munit_assert_size(strlen("uncopyrightables"), >, strlen("dermatoglyphics")); - - /* Of course there is also support for doubles and floats. */ - munit_assert_double(pi, ==, 3.141592654); - - /* If you want to compare two doubles for equality, you might want - * to consider using munit_assert_double_equal. It compares two - * doubles for equality within a precison of 1.0 x 10^-(precision). - * Note that precision (the third argument to the macro) needs to be - * fully evaluated to an integer by the preprocessor so µnit doesn't - * have to depend pow, which is often in libm not libc. */ - munit_assert_double_equal(3.141592654, 3.141592653589793, 9); - - /* And if you want to check strings for equality (or inequality), - * there is munit_assert_string_equal/not_equal. - * - * "stewardesses" is the longest word you can type on a QWERTY - * keyboard with only one hand, which makes it loads of fun to type. - * If I'm going to have to type a string repeatedly, let's make it a - * good one! */ - munit_assert_string_equal(stewardesses, "stewardesses"); - - /* A personal favorite macro which is fantastic if you're working - * with binary data, is the one which naïvely checks two blobs of - * memory for equality. If this fails it will tell you the offset - * of the first differing byte. */ - munit_assert_memory_equal(7, stewardesses, "steward"); - - /* You can also make sure that two blobs differ *somewhere*: */ - munit_assert_memory_not_equal(8, stewardesses, "steward"); - - /* There are equal/not_equal macros for pointers, too: */ - most_fun_word_to_type = stewardesses; - munit_assert_ptr_equal(most_fun_word_to_type, stewardesses); - - /* And null/not_null */ - munit_assert_null(NULL); - munit_assert_not_null(most_fun_word_to_type); - - /* Lets verify that the data parameter is what we expected. We'll - * see where this comes from in a bit. - * - * Note that the casting isn't usually required; if you give this - * function a real pointer (instead of a number like 0xdeadbeef) it - * would work as expected. */ - munit_assert_ptr_equal(data, (void*)(uintptr_t)0xdeadbeef); - - return MUNIT_OK; -} - -static MunitResult -test_rand(const MunitParameter params[], void* user_data) { - int random_int; - double random_dbl; - munit_uint8_t data[5]; - - (void) params; - (void) user_data; - - /* One thing missing from a lot of unit testing frameworks is a - * random number generator. You can't just use srand/rand because - * the implementation varies across different platforms, and it's - * important to be able to look at the seed used in a failing test - * to see if you can reproduce it. Some randomness is a fantastic - * thing to have in your tests, I don't know why more people don't - * do it... - * - * µnit's PRNG is re-seeded with the same value for each iteration - * of each test. The seed is retrieved from the MUNIT_SEED - * envirnment variable or, if none is provided, one will be - * (pseudo-)randomly generated. */ - - /* If you need an integer in a given range */ - random_int = munit_rand_int_range(128, 4096); - munit_assert_int(random_int, >=, 128); - munit_assert_int(random_int, <=, 4096); - - /* Or maybe you want a double, between 0 and 1: */ - random_dbl = munit_rand_double(); - munit_assert_double(random_dbl, >=, 0.0); - munit_assert_double(random_dbl, <=, 1.0); - - /* Of course, you want to be able to reproduce bugs discovered - * during testing, so every time the tests are run they print the - * random seed used. When you want to reproduce a result, just put - * that random seed in the MUNIT_SEED environment variable; it even - * works on different platforms. - * - * If you want this to pass, use 0xdeadbeef as the random seed and - * uncomment the next line of code. Note that the PRNG is not - * re-seeded between iterations of the same test, so this will only - * work on the first iteration. */ - /* munit_assert_uint32(munit_rand_uint32(), ==, 1306447409); */ - - /* You can also get blobs of random memory: */ - munit_rand_memory(sizeof(data), data); - - return MUNIT_OK; -} - -/* This test case shows how to accept parameters. We'll see how to - * specify them soon. - * - * By default, every possible variation of a parameterized test is - * run, but you can specify parameters manually if you want to only - * run specific test(s), or you can pass the --single argument to the - * CLI to have the harness simply choose one variation at random - * instead of running them all. */ -static MunitResult -test_parameters(const MunitParameter params[], void* user_data) { - const char* foo; - const char* bar; - - (void) user_data; - - /* The "foo" parameter is specified as one of the following values: - * "one", "two", or "three". */ - foo = munit_parameters_get(params, "foo"); - /* Similarly, "bar" is one of "four", "five", or "six". */ - bar = munit_parameters_get(params, "bar"); - /* "baz" is a bit more complicated. We don't actually specify a - * list of valid values, so by default NULL is passed. However, the - * CLI will accept any value. This is a good way to have a value - * that is usually selected randomly by the test, but can be - * overridden on the command line if desired. */ - /* const char* baz = munit_parameters_get(params, "baz"); */ - - /* Notice that we're returning MUNIT_FAIL instead of writing an - * error message. Error messages are generally preferable, since - * they make it easier to diagnose the issue, but this is an - * option. - * - * Possible values are: - * - MUNIT_OK: Sucess - * - MUNIT_FAIL: Failure - * - MUNIT_SKIP: The test was skipped; usually this happens when a - * particular feature isn't in use. For example, if you're - * writing a test which uses a Wayland-only feature, but your - * application is running on X11. - * - MUNIT_ERROR: The test failed, but not because of anything you - * wanted to test. For example, maybe your test downloads a - * remote resource and tries to parse it, but the network was - * down. - */ - - if (strcmp(foo, "one") != 0 && - strcmp(foo, "two") != 0 && - strcmp(foo, "three") != 0) - return MUNIT_FAIL; - - if (strcmp(bar, "red") != 0 && - strcmp(bar, "green") != 0 && - strcmp(bar, "blue") != 0) - return MUNIT_FAIL; - - return MUNIT_OK; -} - -/* The setup function, if you provide one, for a test will be run - * before the test, and the return value will be passed as the sole - * parameter to the test function. */ -static void* -test_compare_setup(const MunitParameter params[], void* user_data) { - (void) params; - - munit_assert_string_equal(user_data, "µnit"); - return (void*) (uintptr_t) 0xdeadbeef; -} - -/* To clean up after a test, you can use a tear down function. The - * fixture argument is the value returned by the setup function - * above. */ -static void -test_compare_tear_down(void* fixture) { - munit_assert_ptr_equal(fixture, (void*)(uintptr_t)0xdeadbeef); -} - -static char* foo_params[] = { - (char*) "one", (char*) "two", (char*) "three", NULL -}; - -static char* bar_params[] = { - (char*) "red", (char*) "green", (char*) "blue", NULL -}; - -static MunitParameterEnum test_params[] = { - { (char*) "foo", foo_params }, - { (char*) "bar", bar_params }, - { (char*) "baz", NULL }, - { NULL, NULL }, -}; - -/* Creating a test suite is pretty simple. First, you'll need an - * array of tests: */ -static MunitTest test_suite_tests[] = { - { - /* The name is just a unique human-readable way to identify the - * test. You can use it to run a specific test if you want, but - * usually it's mostly decorative. */ - (char*) "/example/compare", - /* You probably won't be surprised to learn that the tests are - * functions. */ - test_compare, - /* If you want, you can supply a function to set up a fixture. If - * you supply NULL, the user_data parameter from munit_suite_main - * will be used directly. If, however, you provide a callback - * here the user_data parameter will be passed to this callback, - * and the return value from this callback will be passed to the - * test function. - * - * For our example we don't really need a fixture, but lets - * provide one anyways. */ - test_compare_setup, - /* If you passed a callback for the fixture setup function, you - * may want to pass a corresponding callback here to reverse the - * operation. */ - test_compare_tear_down, - /* Finally, there is a bitmask for options you can pass here. You - * can provide either MUNIT_TEST_OPTION_NONE or 0 here to use the - * defaults. */ - MUNIT_TEST_OPTION_NONE, - NULL - }, - /* Usually this is written in a much more compact format; all these - * comments kind of ruin that, though. Here is how you'll usually - * see entries written: */ - { (char*) "/example/rand", test_rand, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }, - /* To tell the test runner when the array is over, just add a NULL - * entry at the end. */ - { (char*) "/example/parameters", test_parameters, NULL, NULL, MUNIT_TEST_OPTION_NONE, test_params }, - { NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL } -}; - -/* If you wanted to have your test suite run other test suites you - * could declare an array of them. Of course each sub-suite can - * contain more suites, etc. */ -/* static const MunitSuite other_suites[] = { */ -/* { "/second", test_suite_tests, NULL, 1, MUNIT_SUITE_OPTION_NONE }, */ -/* { NULL, NULL, NULL, 0, MUNIT_SUITE_OPTION_NONE } */ -/* }; */ - -/* Now we'll actually declare the test suite. You could do this in - * the main function, or on the heap, or whatever you want. */ -static const MunitSuite test_suite = { - /* This string will be prepended to all test names in this suite; - * for example, "/example/rand" will become "/µnit/example/rand". - * Note that, while it doesn't really matter for the top-level - * suite, NULL signal the end of an array of tests; you should use - * an empty string ("") instead. */ - (char*) "", - /* The first parameter is the array of test suites. */ - test_suite_tests, - /* In addition to containing test cases, suites can contain other - * test suites. This isn't necessary in this example, but it can be - * a great help to projects with lots of tests by making it easier - * to spread the tests across many files. This is where you would - * put "other_suites" (which is commented out above). */ - NULL, - /* An interesting feature of µnit is that it supports automatically - * running multiple iterations of the tests. This is usually only - * interesting if you make use of the PRNG to randomize your tests - * cases a bit, or if you are doing performance testing and want to - * average multiple runs. 0 is an alias for 1. */ - 1, - /* Just like MUNIT_TEST_OPTION_NONE, you can provide - * MUNIT_SUITE_OPTION_NONE or 0 to use the default settings. */ - MUNIT_SUITE_OPTION_NONE -}; - -/* This is only necessary for EXIT_SUCCESS and EXIT_FAILURE, which you - * *should* be using but probably aren't (no, zero and non-zero don't - * always mean success and failure). I guess my point is that nothing - * about µnit requires it. */ -#include - -int main(int argc, char* argv[MUNIT_ARRAY_PARAM(argc + 1)]) { - /* Finally, we'll actually run our test suite! That second argument - * is the user_data parameter which will be passed either to the - * test or (if provided) the fixture setup function. */ - return munit_suite_main(&test_suite, (void*) "µnit", argc, argv); -} diff --git a/lib/munit/meson.build b/lib/munit/meson.build deleted file mode 100644 index c15b405a..00000000 --- a/lib/munit/meson.build +++ /dev/null @@ -1,37 +0,0 @@ -project('munit', 'c') - -conf_data = configuration_data() -conf_data.set('version', '0.2.0') - -add_project_arguments('-std=c99', language : 'c') - -cc = meson.get_compiler('c') - -root_include = include_directories('.') - -munit = library('munit', - ['munit.c'], - install: meson.is_subproject()) - -if meson.is_subproject() - munit_dep = declare_dependency( - include_directories : root_include, - link_with : munit) -else - # standalone install - install_headers('munit.h') - - pkg = import('pkgconfig') - pkg.generate(name: 'munit', - description: 'µnit Testing Library for C', - version: conf_data.get('version'), - libraries: munit) - - # compile the demo project - munit_example_src = files('example.c') - munit_example = executable('munit_example', munit_example_src, - include_directories: root_include, - link_with: munit) - - test('munit example test', munit_example) -endif diff --git a/lib/munit/munit.c b/lib/munit/munit.c deleted file mode 100644 index 8765557e..00000000 --- a/lib/munit/munit.c +++ /dev/null @@ -1,2055 +0,0 @@ -/* Copyright (c) 2013-2018 Evan Nemerson - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/*** Configuration ***/ - -/* This is just where the output from the test goes. It's really just - * meant to let you choose stdout or stderr, but if anyone really want - * to direct it to a file let me know, it would be fairly easy to - * support. */ -#if !defined(MUNIT_OUTPUT_FILE) -# define MUNIT_OUTPUT_FILE stdout -#endif - -/* This is a bit more useful; it tells µnit how to format the seconds in - * timed tests. If your tests run for longer you might want to reduce - * it, and if your computer is really fast and your tests are tiny you - * can increase it. */ -#if !defined(MUNIT_TEST_TIME_FORMAT) -# define MUNIT_TEST_TIME_FORMAT "0.8f" -#endif - -/* If you have long test names you might want to consider bumping - * this. The result information takes 43 characters. */ -#if !defined(MUNIT_TEST_NAME_LEN) -# define MUNIT_TEST_NAME_LEN 37 -#endif - -/* If you don't like the timing information, you can disable it by - * defining MUNIT_DISABLE_TIMING. */ -#if !defined(MUNIT_DISABLE_TIMING) -# define MUNIT_ENABLE_TIMING -#endif - -/*** End configuration ***/ - -#if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE < 200809L) -# undef _POSIX_C_SOURCE -#endif -#if !defined(_POSIX_C_SOURCE) -# define _POSIX_C_SOURCE 200809L -#endif - -/* Solaris freaks out if you try to use a POSIX or SUS standard without - * the "right" C standard. */ -#if defined(_XOPEN_SOURCE) -# undef _XOPEN_SOURCE -#endif - -#if defined(__STDC_VERSION__) -# if __STDC_VERSION__ >= 201112L -# define _XOPEN_SOURCE 700 -# elif __STDC_VERSION__ >= 199901L -# define _XOPEN_SOURCE 600 -# endif -#endif - -/* Because, according to Microsoft, POSIX is deprecated. You've got - * to appreciate the chutzpah. */ -#if defined(_MSC_VER) && !defined(_CRT_NONSTDC_NO_DEPRECATE) -# define _CRT_NONSTDC_NO_DEPRECATE -#endif - -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) -# include -#elif defined(_WIN32) -/* https://msdn.microsoft.com/en-us/library/tf4dy80a.aspx */ -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#if !defined(MUNIT_NO_NL_LANGINFO) && !defined(_WIN32) -#define MUNIT_NL_LANGINFO -#include -#include -#include -#endif - -#if !defined(_WIN32) -# include -# include -# include -#else -# include -# include -# include -# if !defined(STDERR_FILENO) -# define STDERR_FILENO _fileno(stderr) -# endif -#endif - -#include "munit.h" - -#define MUNIT_STRINGIFY(x) #x -#define MUNIT_XSTRINGIFY(x) MUNIT_STRINGIFY(x) - -#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__) -# define MUNIT_THREAD_LOCAL __thread -#elif (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201102L)) || defined(_Thread_local) -# define MUNIT_THREAD_LOCAL _Thread_local -#elif defined(_WIN32) -# define MUNIT_THREAD_LOCAL __declspec(thread) -#endif - -/* MSVC 12.0 will emit a warning at /W4 for code like 'do { ... } - * while (0)', or 'do { ... } while (true)'. I'm pretty sure nobody - * at Microsoft compiles with /W4. */ -#if defined(_MSC_VER) && (_MSC_VER <= 1800) -#pragma warning(disable: 4127) -#endif - -#if defined(_WIN32) || defined(__EMSCRIPTEN__) -# define MUNIT_NO_FORK -#endif - -#if defined(__EMSCRIPTEN__) -# define MUNIT_NO_BUFFER -#endif - -/*** Logging ***/ - -static MunitLogLevel munit_log_level_visible = MUNIT_LOG_INFO; -static MunitLogLevel munit_log_level_fatal = MUNIT_LOG_ERROR; - -#if defined(MUNIT_THREAD_LOCAL) -static MUNIT_THREAD_LOCAL bool munit_error_jmp_buf_valid = false; -static MUNIT_THREAD_LOCAL jmp_buf munit_error_jmp_buf; -#endif - -/* At certain warning levels, mingw will trigger warnings about - * suggesting the format attribute, which we've explicity *not* set - * because it will then choke on our attempts to use the MS-specific - * I64 modifier for size_t (which we have to use since MSVC doesn't - * support the C99 z modifier). */ - -#if defined(__MINGW32__) || defined(__MINGW64__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wsuggest-attribute=format" -#endif - -MUNIT_PRINTF(5,0) -static void -munit_logf_exv(MunitLogLevel level, FILE* fp, const char* filename, int line, const char* format, va_list ap) { - if (level < munit_log_level_visible) - return; - - switch (level) { - case MUNIT_LOG_DEBUG: - fputs("Debug", fp); - break; - case MUNIT_LOG_INFO: - fputs("Info", fp); - break; - case MUNIT_LOG_WARNING: - fputs("Warning", fp); - break; - case MUNIT_LOG_ERROR: - fputs("Error", fp); - break; - default: - munit_logf_ex(MUNIT_LOG_ERROR, filename, line, "Invalid log level (%d)", level); - return; - } - - fputs(": ", fp); - if (filename != NULL) - fprintf(fp, "%s:%d: ", filename, line); - vfprintf(fp, format, ap); - fputc('\n', fp); -} - -MUNIT_PRINTF(3,4) -static void -munit_logf_internal(MunitLogLevel level, FILE* fp, const char* format, ...) { - va_list ap; - - va_start(ap, format); - munit_logf_exv(level, fp, NULL, 0, format, ap); - va_end(ap); -} - -static void -munit_log_internal(MunitLogLevel level, FILE* fp, const char* message) { - munit_logf_internal(level, fp, "%s", message); -} - -void -munit_logf_ex(MunitLogLevel level, const char* filename, int line, const char* format, ...) { - va_list ap; - - va_start(ap, format); - munit_logf_exv(level, stderr, filename, line, format, ap); - va_end(ap); - - if (level >= munit_log_level_fatal) { -#if defined(MUNIT_THREAD_LOCAL) - if (munit_error_jmp_buf_valid) - longjmp(munit_error_jmp_buf, 1); -#endif - abort(); - } -} - -void -munit_errorf_ex(const char* filename, int line, const char* format, ...) { - va_list ap; - - va_start(ap, format); - munit_logf_exv(MUNIT_LOG_ERROR, stderr, filename, line, format, ap); - va_end(ap); - -#if defined(MUNIT_THREAD_LOCAL) - if (munit_error_jmp_buf_valid) - longjmp(munit_error_jmp_buf, 1); -#endif - abort(); -} - -#if defined(__MINGW32__) || defined(__MINGW64__) -#pragma GCC diagnostic pop -#endif - -#if !defined(MUNIT_STRERROR_LEN) -# define MUNIT_STRERROR_LEN 80 -#endif - -static void -munit_log_errno(MunitLogLevel level, FILE* fp, const char* msg) { -#if defined(MUNIT_NO_STRERROR_R) || (defined(__MINGW32__) && !defined(MINGW_HAS_SECURE_API)) - munit_logf_internal(level, fp, "%s: %s (%d)", msg, strerror(errno), errno); -#else - char munit_error_str[MUNIT_STRERROR_LEN]; - munit_error_str[0] = '\0'; - -#if !defined(_WIN32) - strerror_r(errno, munit_error_str, MUNIT_STRERROR_LEN); -#else - strerror_s(munit_error_str, MUNIT_STRERROR_LEN, errno); -#endif - - munit_logf_internal(level, fp, "%s: %s (%d)", msg, munit_error_str, errno); -#endif -} - -/*** Memory allocation ***/ - -void* -munit_malloc_ex(const char* filename, int line, size_t size) { - void* ptr; - - if (size == 0) - return NULL; - - ptr = calloc(1, size); - if (MUNIT_UNLIKELY(ptr == NULL)) { - munit_logf_ex(MUNIT_LOG_ERROR, filename, line, "Failed to allocate %" MUNIT_SIZE_MODIFIER "u bytes.", size); - } - - return ptr; -} - -/*** Timer code ***/ - -#if defined(MUNIT_ENABLE_TIMING) - -#define psnip_uint64_t munit_uint64_t -#define psnip_uint32_t munit_uint32_t - -/* Code copied from portable-snippets - * . If you need to - * change something, please do it there so we can keep the code in - * sync. */ - -/* Clocks (v1) - * Portable Snippets - https://gitub.com/nemequ/portable-snippets - * Created by Evan Nemerson - * - * To the extent possible under law, the authors have waived all - * copyright and related or neighboring rights to this code. For - * details, see the Creative Commons Zero 1.0 Universal license at - * https://creativecommons.org/publicdomain/zero/1.0/ - */ - -#if !defined(PSNIP_CLOCK_H) -#define PSNIP_CLOCK_H - -#if !defined(psnip_uint64_t) -# include "../exact-int/exact-int.h" -#endif - -#if !defined(PSNIP_CLOCK_STATIC_INLINE) -# if defined(__GNUC__) -# define PSNIP_CLOCK__COMPILER_ATTRIBUTES __attribute__((__unused__)) -# else -# define PSNIP_CLOCK__COMPILER_ATTRIBUTES -# endif - -# define PSNIP_CLOCK__FUNCTION PSNIP_CLOCK__COMPILER_ATTRIBUTES static -#endif - -enum PsnipClockType { - /* This clock provides the current time, in units since 1970-01-01 - * 00:00:00 UTC not including leap seconds. In other words, UNIX - * time. Keep in mind that this clock doesn't account for leap - * seconds, and can go backwards (think NTP adjustments). */ - PSNIP_CLOCK_TYPE_WALL = 1, - /* The CPU time is a clock which increases only when the current - * process is active (i.e., it doesn't increment while blocking on - * I/O). */ - PSNIP_CLOCK_TYPE_CPU = 2, - /* Monotonic time is always running (unlike CPU time), but it only - ever moves forward unless you reboot the system. Things like NTP - adjustments have no effect on this clock. */ - PSNIP_CLOCK_TYPE_MONOTONIC = 3 -}; - -struct PsnipClockTimespec { - psnip_uint64_t seconds; - psnip_uint64_t nanoseconds; -}; - -/* Methods we support: */ - -#define PSNIP_CLOCK_METHOD_CLOCK_GETTIME 1 -#define PSNIP_CLOCK_METHOD_TIME 2 -#define PSNIP_CLOCK_METHOD_GETTIMEOFDAY 3 -#define PSNIP_CLOCK_METHOD_QUERYPERFORMANCECOUNTER 4 -#define PSNIP_CLOCK_METHOD_MACH_ABSOLUTE_TIME 5 -#define PSNIP_CLOCK_METHOD_CLOCK 6 -#define PSNIP_CLOCK_METHOD_GETPROCESSTIMES 7 -#define PSNIP_CLOCK_METHOD_GETRUSAGE 8 -#define PSNIP_CLOCK_METHOD_GETSYSTEMTIMEPRECISEASFILETIME 9 -#define PSNIP_CLOCK_METHOD_GETTICKCOUNT64 10 - -#include - -#if defined(HEDLEY_UNREACHABLE) -# define PSNIP_CLOCK_UNREACHABLE() HEDLEY_UNREACHABLE() -#else -# define PSNIP_CLOCK_UNREACHABLE() assert(0) -#endif - -/* Choose an implementation */ - -/* #undef PSNIP_CLOCK_WALL_METHOD */ -/* #undef PSNIP_CLOCK_CPU_METHOD */ -/* #undef PSNIP_CLOCK_MONOTONIC_METHOD */ - -/* We want to be able to detect the libc implementation, so we include - ( isn't available everywhere). */ - -#if defined(__unix__) || defined(__unix) || defined(__linux__) -# include -# include -#endif - -#if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0) -/* These are known to work without librt. If you know of others - * please let us know so we can add them. */ -# if \ - (defined(__GLIBC__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 17))) || \ - (defined(__FreeBSD__)) -# define PSNIP_CLOCK_HAVE_CLOCK_GETTIME -# elif !defined(PSNIP_CLOCK_NO_LIBRT) -# define PSNIP_CLOCK_HAVE_CLOCK_GETTIME -# endif -#endif - -#if defined(_WIN32) -# if !defined(PSNIP_CLOCK_CPU_METHOD) -# define PSNIP_CLOCK_CPU_METHOD PSNIP_CLOCK_METHOD_GETPROCESSTIMES -# endif -# if !defined(PSNIP_CLOCK_MONOTONIC_METHOD) -# define PSNIP_CLOCK_MONOTONIC_METHOD PSNIP_CLOCK_METHOD_QUERYPERFORMANCECOUNTER -# endif -#endif - -#if defined(__MACH__) && !defined(__gnu_hurd__) -# if !defined(PSNIP_CLOCK_MONOTONIC_METHOD) -# define PSNIP_CLOCK_MONOTONIC_METHOD PSNIP_CLOCK_METHOD_MACH_ABSOLUTE_TIME -# endif -#endif - -#if defined(PSNIP_CLOCK_HAVE_CLOCK_GETTIME) -# include -# if !defined(PSNIP_CLOCK_WALL_METHOD) -# if defined(CLOCK_REALTIME_PRECISE) -# define PSNIP_CLOCK_WALL_METHOD PSNIP_CLOCK_METHOD_CLOCK_GETTIME -# define PSNIP_CLOCK_CLOCK_GETTIME_WALL CLOCK_REALTIME_PRECISE -# elif !defined(__sun) -# define PSNIP_CLOCK_WALL_METHOD PSNIP_CLOCK_METHOD_CLOCK_GETTIME -# define PSNIP_CLOCK_CLOCK_GETTIME_WALL CLOCK_REALTIME -# endif -# endif -# if !defined(PSNIP_CLOCK_CPU_METHOD) -# if defined(_POSIX_CPUTIME) || defined(CLOCK_PROCESS_CPUTIME_ID) -# define PSNIP_CLOCK_CPU_METHOD PSNIP_CLOCK_METHOD_CLOCK_GETTIME -# define PSNIP_CLOCK_CLOCK_GETTIME_CPU CLOCK_PROCESS_CPUTIME_ID -# elif defined(CLOCK_VIRTUAL) -# define PSNIP_CLOCK_CPU_METHOD PSNIP_CLOCK_METHOD_CLOCK_GETTIME -# define PSNIP_CLOCK_CLOCK_GETTIME_CPU CLOCK_VIRTUAL -# endif -# endif -# if !defined(PSNIP_CLOCK_MONOTONIC_METHOD) -# if defined(CLOCK_MONOTONIC_RAW) -# define PSNIP_CLOCK_MONOTONIC_METHOD PSNIP_CLOCK_METHOD_CLOCK_GETTIME -# define PSNIP_CLOCK_CLOCK_GETTIME_MONOTONIC CLOCK_MONOTONIC -# elif defined(CLOCK_MONOTONIC_PRECISE) -# define PSNIP_CLOCK_MONOTONIC_METHOD PSNIP_CLOCK_METHOD_CLOCK_GETTIME -# define PSNIP_CLOCK_CLOCK_GETTIME_MONOTONIC CLOCK_MONOTONIC_PRECISE -# elif defined(_POSIX_MONOTONIC_CLOCK) || defined(CLOCK_MONOTONIC) -# define PSNIP_CLOCK_MONOTONIC_METHOD PSNIP_CLOCK_METHOD_CLOCK_GETTIME -# define PSNIP_CLOCK_CLOCK_GETTIME_MONOTONIC CLOCK_MONOTONIC -# endif -# endif -#endif - -#if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 200112L) -# if !defined(PSNIP_CLOCK_WALL_METHOD) -# define PSNIP_CLOCK_WALL_METHOD PSNIP_CLOCK_METHOD_GETTIMEOFDAY -# endif -#endif - -#if !defined(PSNIP_CLOCK_WALL_METHOD) -# define PSNIP_CLOCK_WALL_METHOD PSNIP_CLOCK_METHOD_TIME -#endif - -#if !defined(PSNIP_CLOCK_CPU_METHOD) -# define PSNIP_CLOCK_CPU_METHOD PSNIP_CLOCK_METHOD_CLOCK -#endif - -/* Primarily here for testing. */ -#if !defined(PSNIP_CLOCK_MONOTONIC_METHOD) && defined(PSNIP_CLOCK_REQUIRE_MONOTONIC) -# error No monotonic clock found. -#endif - -/* Implementations */ - -#if \ - (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME)) || \ - (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME)) || \ - (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME)) || \ - (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_CLOCK)) || \ - (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_CLOCK)) || \ - (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_CLOCK)) || \ - (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_TIME)) || \ - (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_TIME)) || \ - (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_TIME)) -# include -#endif - -#if \ - (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_GETTIMEOFDAY)) || \ - (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_GETTIMEOFDAY)) || \ - (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_GETTIMEOFDAY)) -# include -#endif - -#if \ - (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_GETPROCESSTIMES)) || \ - (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_GETPROCESSTIMES)) || \ - (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_GETPROCESSTIMES)) || \ - (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_GETTICKCOUNT64)) || \ - (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_GETTICKCOUNT64)) || \ - (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_GETTICKCOUNT64)) -# include -#endif - -#if \ - (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_GETRUSAGE)) || \ - (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_GETRUSAGE)) || \ - (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_GETRUSAGE)) -# include -# include -#endif - -#if \ - (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_MACH_ABSOLUTE_TIME)) || \ - (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_MACH_ABSOLUTE_TIME)) || \ - (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_MACH_ABSOLUTE_TIME)) -# include -# include -# include -#endif - -/*** Implementations ***/ - -#define PSNIP_CLOCK_NSEC_PER_SEC ((psnip_uint32_t) (1000000000ULL)) - -#if \ - (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME)) || \ - (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME)) || \ - (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME)) -PSNIP_CLOCK__FUNCTION psnip_uint32_t -psnip_clock__clock_getres (clockid_t clk_id) { - struct timespec res; - int r; - - r = clock_getres(clk_id, &res); - if (r != 0) - return 0; - - return (psnip_uint32_t) (PSNIP_CLOCK_NSEC_PER_SEC / res.tv_nsec); -} - -PSNIP_CLOCK__FUNCTION int -psnip_clock__clock_gettime (clockid_t clk_id, struct PsnipClockTimespec* res) { - struct timespec ts; - - if (clock_gettime(clk_id, &ts) != 0) - return -10; - - res->seconds = (psnip_uint64_t) (ts.tv_sec); - res->nanoseconds = (psnip_uint64_t) (ts.tv_nsec); - - return 0; -} -#endif - -PSNIP_CLOCK__FUNCTION psnip_uint32_t -psnip_clock_wall_get_precision (void) { -#if !defined(PSNIP_CLOCK_WALL_METHOD) - return 0; -#elif defined(PSNIP_CLOCK_WALL_METHOD) && PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME - return psnip_clock__clock_getres(PSNIP_CLOCK_CLOCK_GETTIME_WALL); -#elif defined(PSNIP_CLOCK_WALL_METHOD) && PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_GETTIMEOFDAY - return 1000000; -#elif defined(PSNIP_CLOCK_WALL_METHOD) && PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_TIME - return 1; -#else - return 0; -#endif -} - -PSNIP_CLOCK__FUNCTION int -psnip_clock_wall_get_time (struct PsnipClockTimespec* res) { - (void) res; - -#if !defined(PSNIP_CLOCK_WALL_METHOD) - return -2; -#elif defined(PSNIP_CLOCK_WALL_METHOD) && PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME - return psnip_clock__clock_gettime(PSNIP_CLOCK_CLOCK_GETTIME_WALL, res); -#elif defined(PSNIP_CLOCK_WALL_METHOD) && PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_TIME - res->seconds = time(NULL); - res->nanoseconds = 0; -#elif defined(PSNIP_CLOCK_WALL_METHOD) && PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_GETTIMEOFDAY - struct timeval tv; - - if (gettimeofday(&tv, NULL) != 0) - return -6; - - res->seconds = tv.tv_sec; - res->nanoseconds = tv.tv_usec * 1000; -#else - return -2; -#endif - - return 0; -} - -PSNIP_CLOCK__FUNCTION psnip_uint32_t -psnip_clock_cpu_get_precision (void) { -#if !defined(PSNIP_CLOCK_CPU_METHOD) - return 0; -#elif defined(PSNIP_CLOCK_CPU_METHOD) && PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME - return psnip_clock__clock_getres(PSNIP_CLOCK_CLOCK_GETTIME_CPU); -#elif defined(PSNIP_CLOCK_CPU_METHOD) && PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_CLOCK - return CLOCKS_PER_SEC; -#elif defined(PSNIP_CLOCK_CPU_METHOD) && PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_GETPROCESSTIMES - return PSNIP_CLOCK_NSEC_PER_SEC / 100; -#else - return 0; -#endif -} - -PSNIP_CLOCK__FUNCTION int -psnip_clock_cpu_get_time (struct PsnipClockTimespec* res) { -#if !defined(PSNIP_CLOCK_CPU_METHOD) - (void) res; - return -2; -#elif defined(PSNIP_CLOCK_CPU_METHOD) && PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME - return psnip_clock__clock_gettime(PSNIP_CLOCK_CLOCK_GETTIME_CPU, res); -#elif defined(PSNIP_CLOCK_CPU_METHOD) && PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_CLOCK - clock_t t = clock(); - if (t == ((clock_t) -1)) - return -5; - res->seconds = t / CLOCKS_PER_SEC; - res->nanoseconds = (t % CLOCKS_PER_SEC) * (PSNIP_CLOCK_NSEC_PER_SEC / CLOCKS_PER_SEC); -#elif defined(PSNIP_CLOCK_CPU_METHOD) && PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_GETPROCESSTIMES - FILETIME CreationTime, ExitTime, KernelTime, UserTime; - LARGE_INTEGER date, adjust; - - if (!GetProcessTimes(GetCurrentProcess(), &CreationTime, &ExitTime, &KernelTime, &UserTime)) - return -7; - - /* http://www.frenk.com/2009/12/convert-filetime-to-unix-timestamp/ */ - date.HighPart = UserTime.dwHighDateTime; - date.LowPart = UserTime.dwLowDateTime; - adjust.QuadPart = 11644473600000 * 10000; - date.QuadPart -= adjust.QuadPart; - - res->seconds = date.QuadPart / 10000000; - res->nanoseconds = (date.QuadPart % 10000000) * (PSNIP_CLOCK_NSEC_PER_SEC / 100); -#elif PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_GETRUSAGE - struct rusage usage; - if (getrusage(RUSAGE_SELF, &usage) != 0) - return -8; - - res->seconds = usage.ru_utime.tv_sec; - res->nanoseconds = tv.tv_usec * 1000; -#else - (void) res; - return -2; -#endif - - return 0; -} - -PSNIP_CLOCK__FUNCTION psnip_uint32_t -psnip_clock_monotonic_get_precision (void) { -#if !defined(PSNIP_CLOCK_MONOTONIC_METHOD) - return 0; -#elif defined(PSNIP_CLOCK_MONOTONIC_METHOD) && PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME - return psnip_clock__clock_getres(PSNIP_CLOCK_CLOCK_GETTIME_MONOTONIC); -#elif defined(PSNIP_CLOCK_MONOTONIC_METHOD) && PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_MACH_ABSOLUTE_TIME - static mach_timebase_info_data_t tbi = { 0,0 }; - if (tbi.denom == 0) - mach_timebase_info(&tbi); - return (psnip_uint32_t) (tbi.numer / tbi.denom); -#elif defined(PSNIP_CLOCK_MONOTONIC_METHOD) && PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_GETTICKCOUNT64 - return 1000; -#elif defined(PSNIP_CLOCK_MONOTONIC_METHOD) && PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_QUERYPERFORMANCECOUNTER - LARGE_INTEGER Frequency; - QueryPerformanceFrequency(&Frequency); - return (psnip_uint32_t) ((Frequency.QuadPart > PSNIP_CLOCK_NSEC_PER_SEC) ? PSNIP_CLOCK_NSEC_PER_SEC : Frequency.QuadPart); -#else - return 0; -#endif -} - -PSNIP_CLOCK__FUNCTION int -psnip_clock_monotonic_get_time (struct PsnipClockTimespec* res) { -#if !defined(PSNIP_CLOCK_MONOTONIC_METHOD) - (void) res; - return -2; -#elif defined(PSNIP_CLOCK_MONOTONIC_METHOD) && PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME - return psnip_clock__clock_gettime(PSNIP_CLOCK_CLOCK_GETTIME_MONOTONIC, res); -#elif defined(PSNIP_CLOCK_MONOTONIC_METHOD) && PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_MACH_ABSOLUTE_TIME - psnip_uint64_t nsec = mach_absolute_time(); - static mach_timebase_info_data_t tbi = { 0,0 }; - if (tbi.denom == 0) - mach_timebase_info(&tbi); - nsec *= ((psnip_uint64_t) tbi.numer) / ((psnip_uint64_t) tbi.denom); - res->seconds = nsec / PSNIP_CLOCK_NSEC_PER_SEC; - res->nanoseconds = nsec % PSNIP_CLOCK_NSEC_PER_SEC; -#elif defined(PSNIP_CLOCK_MONOTONIC_METHOD) && PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_QUERYPERFORMANCECOUNTER - LARGE_INTEGER t, f; - if (QueryPerformanceCounter(&t) == 0) - return -12; - - QueryPerformanceFrequency(&f); - res->seconds = t.QuadPart / f.QuadPart; - res->nanoseconds = t.QuadPart % f.QuadPart; - if (f.QuadPart > PSNIP_CLOCK_NSEC_PER_SEC) - res->nanoseconds /= f.QuadPart / PSNIP_CLOCK_NSEC_PER_SEC; - else - res->nanoseconds *= PSNIP_CLOCK_NSEC_PER_SEC / f.QuadPart; -#elif defined(PSNIP_CLOCK_MONOTONIC_METHOD) && PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_GETTICKCOUNT64 - const ULONGLONG msec = GetTickCount64(); - res->seconds = msec / 1000; - res->nanoseconds = sec % 1000; -#else - return -2; -#endif - - return 0; -} - -/* Returns the number of ticks per second for the specified clock. - * For example, a clock with millisecond precision would return 1000, - * and a clock with 1 second (such as the time() function) would - * return 1. - * - * If the requested clock isn't available, it will return 0. - * Hopefully this will be rare, but if it happens to you please let us - * know so we can work on finding a way to support your system. - * - * Note that different clocks on the same system often have a - * different precisions. - */ -PSNIP_CLOCK__FUNCTION psnip_uint32_t -psnip_clock_get_precision (enum PsnipClockType clock_type) { - switch (clock_type) { - case PSNIP_CLOCK_TYPE_MONOTONIC: - return psnip_clock_monotonic_get_precision (); - case PSNIP_CLOCK_TYPE_CPU: - return psnip_clock_cpu_get_precision (); - case PSNIP_CLOCK_TYPE_WALL: - return psnip_clock_wall_get_precision (); - } - - PSNIP_CLOCK_UNREACHABLE(); - return 0; -} - -/* Set the provided timespec to the requested time. Returns 0 on - * success, or a negative value on failure. */ -PSNIP_CLOCK__FUNCTION int -psnip_clock_get_time (enum PsnipClockType clock_type, struct PsnipClockTimespec* res) { - assert(res != NULL); - - switch (clock_type) { - case PSNIP_CLOCK_TYPE_MONOTONIC: - return psnip_clock_monotonic_get_time (res); - case PSNIP_CLOCK_TYPE_CPU: - return psnip_clock_cpu_get_time (res); - case PSNIP_CLOCK_TYPE_WALL: - return psnip_clock_wall_get_time (res); - } - - return -1; -} - -#endif /* !defined(PSNIP_CLOCK_H) */ - -static psnip_uint64_t -munit_clock_get_elapsed(struct PsnipClockTimespec* start, struct PsnipClockTimespec* end) { - psnip_uint64_t r = (end->seconds - start->seconds) * PSNIP_CLOCK_NSEC_PER_SEC; - if (end->nanoseconds < start->nanoseconds) { - r -= (start->nanoseconds - end->nanoseconds); - } else { - r += (end->nanoseconds - start->nanoseconds); - } - return r; -} - -#else -# include -#endif /* defined(MUNIT_ENABLE_TIMING) */ - -/*** PRNG stuff ***/ - -/* This is (unless I screwed up, which is entirely possible) the - * version of PCG with 32-bit state. It was chosen because it has a - * small enough state that we should reliably be able to use CAS - * instead of requiring a lock for thread-safety. - * - * If I did screw up, I probably will not bother changing it unless - * there is a significant bias. It's really not important this be - * particularly strong, as long as it is fairly random it's much more - * important that it be reproducible, so bug reports have a better - * chance of being reproducible. */ - -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && !defined(__STDC_NO_ATOMICS__) && !defined(__EMSCRIPTEN__) && (!defined(__GNUC_MINOR__) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ > 8)) -# define HAVE_STDATOMIC -#elif defined(__clang__) -# if __has_extension(c_atomic) -# define HAVE_CLANG_ATOMICS -# endif -#endif - -/* Workaround for http://llvm.org/bugs/show_bug.cgi?id=26911 */ -#if defined(__clang__) && defined(_WIN32) -# undef HAVE_STDATOMIC -# if defined(__c2__) -# undef HAVE_CLANG_ATOMICS -# endif -#endif - -#if defined(_OPENMP) -# define ATOMIC_UINT32_T uint32_t -# define ATOMIC_UINT32_INIT(x) (x) -#elif defined(HAVE_STDATOMIC) -# include -# define ATOMIC_UINT32_T _Atomic uint32_t -# define ATOMIC_UINT32_INIT(x) ATOMIC_VAR_INIT(x) -#elif defined(HAVE_CLANG_ATOMICS) -# define ATOMIC_UINT32_T _Atomic uint32_t -# define ATOMIC_UINT32_INIT(x) (x) -#elif defined(_WIN32) -# define ATOMIC_UINT32_T volatile LONG -# define ATOMIC_UINT32_INIT(x) (x) -#else -# define ATOMIC_UINT32_T volatile uint32_t -# define ATOMIC_UINT32_INIT(x) (x) -#endif - -static ATOMIC_UINT32_T munit_rand_state = ATOMIC_UINT32_INIT(42); - -#if defined(_OPENMP) -static inline void -munit_atomic_store(ATOMIC_UINT32_T* dest, ATOMIC_UINT32_T value) { -#pragma omp critical (munit_atomics) - *dest = value; -} - -static inline uint32_t -munit_atomic_load(ATOMIC_UINT32_T* src) { - int ret; -#pragma omp critical (munit_atomics) - ret = *src; - return ret; -} - -static inline uint32_t -munit_atomic_cas(ATOMIC_UINT32_T* dest, ATOMIC_UINT32_T* expected, ATOMIC_UINT32_T desired) { - bool ret; - -#pragma omp critical (munit_atomics) - { - if (*dest == *expected) { - *dest = desired; - ret = true; - } else { - ret = false; - } - } - - return ret; -} -#elif defined(HAVE_STDATOMIC) -# define munit_atomic_store(dest, value) atomic_store(dest, value) -# define munit_atomic_load(src) atomic_load(src) -# define munit_atomic_cas(dest, expected, value) atomic_compare_exchange_weak(dest, expected, value) -#elif defined(HAVE_CLANG_ATOMICS) -# define munit_atomic_store(dest, value) __c11_atomic_store(dest, value, __ATOMIC_SEQ_CST) -# define munit_atomic_load(src) __c11_atomic_load(src, __ATOMIC_SEQ_CST) -# define munit_atomic_cas(dest, expected, value) __c11_atomic_compare_exchange_weak(dest, expected, value, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) -#elif defined(__GNUC__) && (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) -# define munit_atomic_store(dest, value) __atomic_store_n(dest, value, __ATOMIC_SEQ_CST) -# define munit_atomic_load(src) __atomic_load_n(src, __ATOMIC_SEQ_CST) -# define munit_atomic_cas(dest, expected, value) __atomic_compare_exchange_n(dest, expected, value, true, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) -#elif defined(__GNUC__) && (__GNUC__ >= 4) -# define munit_atomic_store(dest,value) do { *(dest) = (value); } while (0) -# define munit_atomic_load(src) (*(src)) -# define munit_atomic_cas(dest, expected, value) __sync_bool_compare_and_swap(dest, *expected, value) -#elif defined(_WIN32) /* Untested */ -# define munit_atomic_store(dest,value) do { *(dest) = (value); } while (0) -# define munit_atomic_load(src) (*(src)) -# define munit_atomic_cas(dest, expected, value) InterlockedCompareExchange((dest), (value), *(expected)) -#else -# warning No atomic implementation, PRNG will not be thread-safe -# define munit_atomic_store(dest, value) do { *(dest) = (value); } while (0) -# define munit_atomic_load(src) (*(src)) -static inline bool -munit_atomic_cas(ATOMIC_UINT32_T* dest, ATOMIC_UINT32_T* expected, ATOMIC_UINT32_T desired) { - if (*dest == *expected) { - *dest = desired; - return true; - } else { - return false; - } -} -#endif - -#define MUNIT_PRNG_MULTIPLIER (747796405U) -#define MUNIT_PRNG_INCREMENT (1729U) - -static munit_uint32_t -munit_rand_next_state(munit_uint32_t state) { - return state * MUNIT_PRNG_MULTIPLIER + MUNIT_PRNG_INCREMENT; -} - -static munit_uint32_t -munit_rand_from_state(munit_uint32_t state) { - munit_uint32_t res = ((state >> ((state >> 28) + 4)) ^ state) * (277803737U); - res ^= res >> 22; - return res; -} - -void -munit_rand_seed(munit_uint32_t seed) { - munit_uint32_t state = munit_rand_next_state(seed + MUNIT_PRNG_INCREMENT); - munit_atomic_store(&munit_rand_state, state); -} - -static munit_uint32_t -munit_rand_generate_seed(void) { - munit_uint32_t seed, state; -#if defined(MUNIT_ENABLE_TIMING) - struct PsnipClockTimespec wc = { 0,0 }; - - psnip_clock_get_time(PSNIP_CLOCK_TYPE_WALL, &wc); - seed = (munit_uint32_t) wc.nanoseconds; -#else - seed = (munit_uint32_t) time(NULL); -#endif - - state = munit_rand_next_state(seed + MUNIT_PRNG_INCREMENT); - return munit_rand_from_state(state); -} - -static munit_uint32_t -munit_rand_state_uint32(munit_uint32_t* state) { - const munit_uint32_t old = *state; - *state = munit_rand_next_state(old); - return munit_rand_from_state(old); -} - -munit_uint32_t -munit_rand_uint32(void) { - munit_uint32_t old, state; - - do { - old = munit_atomic_load(&munit_rand_state); - state = munit_rand_next_state(old); - } while (!munit_atomic_cas(&munit_rand_state, &old, state)); - - return munit_rand_from_state(old); -} - -static void -munit_rand_state_memory(munit_uint32_t* state, size_t size, munit_uint8_t data[MUNIT_ARRAY_PARAM(size)]) { - size_t members_remaining = size / sizeof(munit_uint32_t); - size_t bytes_remaining = size % sizeof(munit_uint32_t); - munit_uint8_t* b = data; - munit_uint32_t rv; - while (members_remaining-- > 0) { - rv = munit_rand_state_uint32(state); - memcpy(b, &rv, sizeof(munit_uint32_t)); - b += sizeof(munit_uint32_t); - } - if (bytes_remaining != 0) { - rv = munit_rand_state_uint32(state); - memcpy(b, &rv, bytes_remaining); - } -} - -void -munit_rand_memory(size_t size, munit_uint8_t data[MUNIT_ARRAY_PARAM(size)]) { - munit_uint32_t old, state; - - do { - state = old = munit_atomic_load(&munit_rand_state); - munit_rand_state_memory(&state, size, data); - } while (!munit_atomic_cas(&munit_rand_state, &old, state)); -} - -static munit_uint32_t -munit_rand_state_at_most(munit_uint32_t* state, munit_uint32_t salt, munit_uint32_t max) { - /* We want (UINT32_MAX + 1) % max, which in unsigned arithmetic is the same - * as (UINT32_MAX + 1 - max) % max = -max % max. We compute -max using not - * to avoid compiler warnings. - */ - const munit_uint32_t min = (~max + 1U) % max; - munit_uint32_t x; - - if (max == (~((munit_uint32_t) 0U))) - return munit_rand_state_uint32(state) ^ salt; - - max++; - - do { - x = munit_rand_state_uint32(state) ^ salt; - } while (x < min); - - return x % max; -} - -static munit_uint32_t -munit_rand_at_most(munit_uint32_t salt, munit_uint32_t max) { - munit_uint32_t old, state; - munit_uint32_t retval; - - do { - state = old = munit_atomic_load(&munit_rand_state); - retval = munit_rand_state_at_most(&state, salt, max); - } while (!munit_atomic_cas(&munit_rand_state, &old, state)); - - return retval; -} - -int -munit_rand_int_range(int min, int max) { - munit_uint64_t range = (munit_uint64_t) max - (munit_uint64_t) min; - - if (min > max) - return munit_rand_int_range(max, min); - - if (range > (~((munit_uint32_t) 0U))) - range = (~((munit_uint32_t) 0U)); - - return min + munit_rand_at_most(0, (munit_uint32_t) range); -} - -double -munit_rand_double(void) { - munit_uint32_t old, state; - double retval = 0.0; - - do { - state = old = munit_atomic_load(&munit_rand_state); - - /* See http://mumble.net/~campbell/tmp/random_real.c for how to do - * this right. Patches welcome if you feel that this is too - * biased. */ - retval = munit_rand_state_uint32(&state) / ((~((munit_uint32_t) 0U)) + 1.0); - } while (!munit_atomic_cas(&munit_rand_state, &old, state)); - - return retval; -} - -/*** Test suite handling ***/ - -typedef struct { - unsigned int successful; - unsigned int skipped; - unsigned int failed; - unsigned int errored; -#if defined(MUNIT_ENABLE_TIMING) - munit_uint64_t cpu_clock; - munit_uint64_t wall_clock; -#endif -} MunitReport; - -typedef struct { - const char* prefix; - const MunitSuite* suite; - const char** tests; - munit_uint32_t seed; - unsigned int iterations; - MunitParameter* parameters; - bool single_parameter_mode; - void* user_data; - MunitReport report; - bool colorize; - bool fork; - bool show_stderr; - bool fatal_failures; -} MunitTestRunner; - -const char* -munit_parameters_get(const MunitParameter params[], const char* key) { - const MunitParameter* param; - - for (param = params ; param != NULL && param->name != NULL ; param++) - if (strcmp(param->name, key) == 0) - return param->value; - return NULL; -} - -#if defined(MUNIT_ENABLE_TIMING) -static void -munit_print_time(FILE* fp, munit_uint64_t nanoseconds) { - fprintf(fp, "%" MUNIT_TEST_TIME_FORMAT, ((double) nanoseconds) / ((double) PSNIP_CLOCK_NSEC_PER_SEC)); -} -#endif - -/* Add a paramter to an array of parameters. */ -static MunitResult -munit_parameters_add(size_t* params_size, MunitParameter* params[MUNIT_ARRAY_PARAM(*params_size)], char* name, char* value) { - *params = realloc(*params, sizeof(MunitParameter) * (*params_size + 2)); - if (*params == NULL) - return MUNIT_ERROR; - - (*params)[*params_size].name = name; - (*params)[*params_size].value = value; - (*params_size)++; - (*params)[*params_size].name = NULL; - (*params)[*params_size].value = NULL; - - return MUNIT_OK; -} - -/* Concatenate two strings, but just return one of the components - * unaltered if the other is NULL or "". */ -static char* -munit_maybe_concat(size_t* len, char* prefix, char* suffix) { - char* res; - size_t res_l; - const size_t prefix_l = prefix != NULL ? strlen(prefix) : 0; - const size_t suffix_l = suffix != NULL ? strlen(suffix) : 0; - if (prefix_l == 0 && suffix_l == 0) { - res = NULL; - res_l = 0; - } else if (prefix_l == 0 && suffix_l != 0) { - res = suffix; - res_l = suffix_l; - } else if (prefix_l != 0 && suffix_l == 0) { - res = prefix; - res_l = prefix_l; - } else { - res_l = prefix_l + suffix_l; - res = malloc(res_l + 1); - memcpy(res, prefix, prefix_l); - memcpy(res + prefix_l, suffix, suffix_l); - res[res_l] = 0; - } - - if (len != NULL) - *len = res_l; - - return res; -} - -/* Possbily free a string returned by munit_maybe_concat. */ -static void -munit_maybe_free_concat(char* s, const char* prefix, const char* suffix) { - if (prefix != s && suffix != s) - free(s); -} - -/* Cheap string hash function, just used to salt the PRNG. */ -static munit_uint32_t -munit_str_hash(const char* name) { - const char *p; - munit_uint32_t h = 5381U; - - for (p = name; *p != '\0'; p++) - h = (h << 5) + h + *p; - - return h; -} - -static void -munit_splice(int from, int to) { - munit_uint8_t buf[1024]; -#if !defined(_WIN32) - ssize_t len; - ssize_t bytes_written; - ssize_t write_res; -#else - int len; - int bytes_written; - int write_res; -#endif - do { - len = read(from, buf, sizeof(buf)); - if (len > 0) { - bytes_written = 0; - do { - write_res = write(to, buf + bytes_written, len - bytes_written); - if (write_res < 0) - break; - bytes_written += write_res; - } while (bytes_written < len); - } - else - break; - } while (true); -} - -/* This is the part that should be handled in the child process */ -static MunitResult -munit_test_runner_exec(MunitTestRunner* runner, const MunitTest* test, const MunitParameter params[], MunitReport* report) { - unsigned int iterations = runner->iterations; - MunitResult result = MUNIT_FAIL; -#if defined(MUNIT_ENABLE_TIMING) - struct PsnipClockTimespec wall_clock_begin = { 0,0 }, wall_clock_end = { 0,0 }; - struct PsnipClockTimespec cpu_clock_begin = { 0,0 }, cpu_clock_end = { 0,0 }; -#endif - unsigned int i = 0; - - if ((test->options & MUNIT_TEST_OPTION_SINGLE_ITERATION) == MUNIT_TEST_OPTION_SINGLE_ITERATION) - iterations = 1; - else if (iterations == 0) - iterations = runner->suite->iterations; - - munit_rand_seed(runner->seed); - - do { - void* data = (test->setup == NULL) ? runner->user_data : test->setup(params, runner->user_data); - -#if defined(MUNIT_ENABLE_TIMING) - psnip_clock_get_time(PSNIP_CLOCK_TYPE_WALL, &wall_clock_begin); - psnip_clock_get_time(PSNIP_CLOCK_TYPE_CPU, &cpu_clock_begin); -#endif - - result = test->test(params, data); - -#if defined(MUNIT_ENABLE_TIMING) - psnip_clock_get_time(PSNIP_CLOCK_TYPE_WALL, &wall_clock_end); - psnip_clock_get_time(PSNIP_CLOCK_TYPE_CPU, &cpu_clock_end); -#endif - - if (test->tear_down != NULL) - test->tear_down(data); - - if (MUNIT_LIKELY(result == MUNIT_OK)) { - report->successful++; -#if defined(MUNIT_ENABLE_TIMING) - report->wall_clock += munit_clock_get_elapsed(&wall_clock_begin, &wall_clock_end); - report->cpu_clock += munit_clock_get_elapsed(&cpu_clock_begin, &cpu_clock_end); -#endif - } else { - switch ((int) result) { - case MUNIT_SKIP: - report->skipped++; - break; - case MUNIT_FAIL: - report->failed++; - break; - case MUNIT_ERROR: - report->errored++; - break; - default: - break; - } - break; - } - } while (++i < iterations); - - return result; -} - -#if defined(MUNIT_EMOTICON) -# define MUNIT_RESULT_STRING_OK ":)" -# define MUNIT_RESULT_STRING_SKIP ":|" -# define MUNIT_RESULT_STRING_FAIL ":(" -# define MUNIT_RESULT_STRING_ERROR ":o" -# define MUNIT_RESULT_STRING_TODO ":/" -#else -# define MUNIT_RESULT_STRING_OK "OK " -# define MUNIT_RESULT_STRING_SKIP "SKIP " -# define MUNIT_RESULT_STRING_FAIL "FAIL " -# define MUNIT_RESULT_STRING_ERROR "ERROR" -# define MUNIT_RESULT_STRING_TODO "TODO " -#endif - -static void -munit_test_runner_print_color(const MunitTestRunner* runner, const char* string, char color) { - if (runner->colorize) - fprintf(MUNIT_OUTPUT_FILE, "\x1b[3%cm%s\x1b[39m", color, string); - else - fputs(string, MUNIT_OUTPUT_FILE); -} - -#if !defined(MUNIT_NO_BUFFER) -static int -munit_replace_stderr(FILE* stderr_buf) { - if (stderr_buf != NULL) { - const int orig_stderr = dup(STDERR_FILENO); - - int errfd = fileno(stderr_buf); - if (MUNIT_UNLIKELY(errfd == -1)) { - exit(EXIT_FAILURE); - } - - dup2(errfd, STDERR_FILENO); - - return orig_stderr; - } - - return -1; -} - -static void -munit_restore_stderr(int orig_stderr) { - if (orig_stderr != -1) { - dup2(orig_stderr, STDERR_FILENO); - close(orig_stderr); - } -} -#endif /* !defined(MUNIT_NO_BUFFER) */ - -/* Run a test with the specified parameters. */ -static void -munit_test_runner_run_test_with_params(MunitTestRunner* runner, const MunitTest* test, const MunitParameter params[]) { - MunitResult result = MUNIT_OK; - MunitReport report = { - 0, 0, 0, 0, -#if defined(MUNIT_ENABLE_TIMING) - 0, 0 -#endif - }; - unsigned int output_l; - bool first; - const MunitParameter* param; - FILE* stderr_buf; -#if !defined(MUNIT_NO_FORK) - int pipefd[2]; - pid_t fork_pid; - int orig_stderr; - ssize_t bytes_written = 0; - ssize_t write_res; - ssize_t bytes_read = 0; - ssize_t read_res; - int status = 0; - pid_t changed_pid; -#endif - - if (params != NULL) { - output_l = 2; - fputs(" ", MUNIT_OUTPUT_FILE); - first = true; - for (param = params ; param != NULL && param->name != NULL ; param++) { - if (!first) { - fputs(", ", MUNIT_OUTPUT_FILE); - output_l += 2; - } else { - first = false; - } - - output_l += fprintf(MUNIT_OUTPUT_FILE, "%s=%s", param->name, param->value); - } - while (output_l++ < MUNIT_TEST_NAME_LEN) { - fputc(' ', MUNIT_OUTPUT_FILE); - } - } - - fflush(MUNIT_OUTPUT_FILE); - - stderr_buf = NULL; -#if !defined(_WIN32) || defined(__MINGW32__) - stderr_buf = tmpfile(); -#else - tmpfile_s(&stderr_buf); -#endif - if (stderr_buf == NULL) { - munit_log_errno(MUNIT_LOG_ERROR, stderr, "unable to create buffer for stderr"); - result = MUNIT_ERROR; - goto print_result; - } - -#if !defined(MUNIT_NO_FORK) - if (runner->fork) { - pipefd[0] = -1; - pipefd[1] = -1; - if (pipe(pipefd) != 0) { - munit_log_errno(MUNIT_LOG_ERROR, stderr, "unable to create pipe"); - result = MUNIT_ERROR; - goto print_result; - } - - fork_pid = fork(); - if (fork_pid == 0) { - close(pipefd[0]); - - orig_stderr = munit_replace_stderr(stderr_buf); - munit_test_runner_exec(runner, test, params, &report); - - /* Note that we don't restore stderr. This is so we can buffer - * things written to stderr later on (such as by - * asan/tsan/ubsan, valgrind, etc.) */ - close(orig_stderr); - - do { - write_res = write(pipefd[1], ((munit_uint8_t*) (&report)) + bytes_written, sizeof(report) - bytes_written); - if (write_res < 0) { - if (stderr_buf != NULL) { - munit_log_errno(MUNIT_LOG_ERROR, stderr, "unable to write to pipe"); - } - exit(EXIT_FAILURE); - } - bytes_written += write_res; - } while ((size_t) bytes_written < sizeof(report)); - - if (stderr_buf != NULL) - fclose(stderr_buf); - close(pipefd[1]); - - exit(EXIT_SUCCESS); - } else if (fork_pid == -1) { - close(pipefd[0]); - close(pipefd[1]); - if (stderr_buf != NULL) { - munit_log_errno(MUNIT_LOG_ERROR, stderr, "unable to fork"); - } - report.errored++; - result = MUNIT_ERROR; - } else { - close(pipefd[1]); - do { - read_res = read(pipefd[0], ((munit_uint8_t*) (&report)) + bytes_read, sizeof(report) - bytes_read); - if (read_res < 1) - break; - bytes_read += read_res; - } while (bytes_read < (ssize_t) sizeof(report)); - - changed_pid = waitpid(fork_pid, &status, 0); - - if (MUNIT_LIKELY(changed_pid == fork_pid) && MUNIT_LIKELY(WIFEXITED(status))) { - if (bytes_read != sizeof(report)) { - munit_logf_internal(MUNIT_LOG_ERROR, stderr_buf, "child exited unexpectedly with status %d", WEXITSTATUS(status)); - report.errored++; - } else if (WEXITSTATUS(status) != EXIT_SUCCESS) { - munit_logf_internal(MUNIT_LOG_ERROR, stderr_buf, "child exited with status %d", WEXITSTATUS(status)); - report.errored++; - } - } else { - if (WIFSIGNALED(status)) { -#if defined(_XOPEN_VERSION) && (_XOPEN_VERSION >= 700) - munit_logf_internal(MUNIT_LOG_ERROR, stderr_buf, "child killed by signal %d (%s)", WTERMSIG(status), strsignal(WTERMSIG(status))); -#else - munit_logf_internal(MUNIT_LOG_ERROR, stderr_buf, "child killed by signal %d", WTERMSIG(status)); -#endif - } else if (WIFSTOPPED(status)) { - munit_logf_internal(MUNIT_LOG_ERROR, stderr_buf, "child stopped by signal %d", WSTOPSIG(status)); - } - report.errored++; - } - - close(pipefd[0]); - waitpid(fork_pid, NULL, 0); - } - } else -#endif - { -#if !defined(MUNIT_NO_BUFFER) - const volatile int orig_stderr = munit_replace_stderr(stderr_buf); -#endif - -#if defined(MUNIT_THREAD_LOCAL) - if (MUNIT_UNLIKELY(setjmp(munit_error_jmp_buf) != 0)) { - result = MUNIT_FAIL; - report.failed++; - } else { - munit_error_jmp_buf_valid = true; - result = munit_test_runner_exec(runner, test, params, &report); - } -#else - result = munit_test_runner_exec(runner, test, params, &report); -#endif - -#if !defined(MUNIT_NO_BUFFER) - munit_restore_stderr(orig_stderr); -#endif - - /* Here just so that the label is used on Windows and we don't get - * a warning */ - goto print_result; - } - - print_result: - - fputs("[ ", MUNIT_OUTPUT_FILE); - if ((test->options & MUNIT_TEST_OPTION_TODO) == MUNIT_TEST_OPTION_TODO) { - if (report.failed != 0 || report.errored != 0 || report.skipped != 0) { - munit_test_runner_print_color(runner, MUNIT_RESULT_STRING_TODO, '3'); - result = MUNIT_OK; - } else { - munit_test_runner_print_color(runner, MUNIT_RESULT_STRING_ERROR, '1'); - if (MUNIT_LIKELY(stderr_buf != NULL)) - munit_log_internal(MUNIT_LOG_ERROR, stderr_buf, "Test marked TODO, but was successful."); - runner->report.failed++; - result = MUNIT_ERROR; - } - } else if (report.failed > 0) { - munit_test_runner_print_color(runner, MUNIT_RESULT_STRING_FAIL, '1'); - runner->report.failed++; - result = MUNIT_FAIL; - } else if (report.errored > 0) { - munit_test_runner_print_color(runner, MUNIT_RESULT_STRING_ERROR, '1'); - runner->report.errored++; - result = MUNIT_ERROR; - } else if (report.skipped > 0) { - munit_test_runner_print_color(runner, MUNIT_RESULT_STRING_SKIP, '3'); - runner->report.skipped++; - result = MUNIT_SKIP; - } else if (report.successful > 1) { - munit_test_runner_print_color(runner, MUNIT_RESULT_STRING_OK, '2'); -#if defined(MUNIT_ENABLE_TIMING) - fputs(" ] [ ", MUNIT_OUTPUT_FILE); - munit_print_time(MUNIT_OUTPUT_FILE, report.wall_clock / report.successful); - fputs(" / ", MUNIT_OUTPUT_FILE); - munit_print_time(MUNIT_OUTPUT_FILE, report.cpu_clock / report.successful); - fprintf(MUNIT_OUTPUT_FILE, " CPU ]\n %-" MUNIT_XSTRINGIFY(MUNIT_TEST_NAME_LEN) "s Total: [ ", ""); - munit_print_time(MUNIT_OUTPUT_FILE, report.wall_clock); - fputs(" / ", MUNIT_OUTPUT_FILE); - munit_print_time(MUNIT_OUTPUT_FILE, report.cpu_clock); - fputs(" CPU", MUNIT_OUTPUT_FILE); -#endif - runner->report.successful++; - result = MUNIT_OK; - } else if (report.successful > 0) { - munit_test_runner_print_color(runner, MUNIT_RESULT_STRING_OK, '2'); -#if defined(MUNIT_ENABLE_TIMING) - fputs(" ] [ ", MUNIT_OUTPUT_FILE); - munit_print_time(MUNIT_OUTPUT_FILE, report.wall_clock); - fputs(" / ", MUNIT_OUTPUT_FILE); - munit_print_time(MUNIT_OUTPUT_FILE, report.cpu_clock); - fputs(" CPU", MUNIT_OUTPUT_FILE); -#endif - runner->report.successful++; - result = MUNIT_OK; - } - fputs(" ]\n", MUNIT_OUTPUT_FILE); - - if (stderr_buf != NULL) { - if (result == MUNIT_FAIL || result == MUNIT_ERROR || runner->show_stderr) { - fflush(MUNIT_OUTPUT_FILE); - - rewind(stderr_buf); - munit_splice(fileno(stderr_buf), STDERR_FILENO); - - fflush(stderr); - } - - fclose(stderr_buf); - } -} - -static void -munit_test_runner_run_test_wild(MunitTestRunner* runner, - const MunitTest* test, - const char* test_name, - MunitParameter* params, - MunitParameter* p) { - const MunitParameterEnum* pe; - char** values; - MunitParameter* next; - - for (pe = test->parameters ; pe != NULL && pe->name != NULL ; pe++) { - if (p->name == pe->name) - break; - } - - if (pe == NULL) - return; - - for (values = pe->values ; *values != NULL ; values++) { - next = p + 1; - p->value = *values; - if (next->name == NULL) { - munit_test_runner_run_test_with_params(runner, test, params); - } else { - munit_test_runner_run_test_wild(runner, test, test_name, params, next); - } - if (runner->fatal_failures && (runner->report.failed != 0 || runner->report.errored != 0)) - break; - } -} - -/* Run a single test, with every combination of parameters - * requested. */ -static void -munit_test_runner_run_test(MunitTestRunner* runner, - const MunitTest* test, - const char* prefix) { - char* test_name = munit_maybe_concat(NULL, (char*) prefix, (char*) test->name); - /* The array of parameters to pass to - * munit_test_runner_run_test_with_params */ - MunitParameter* params = NULL; - size_t params_l = 0; - /* Wildcard parameters are parameters which have possible values - * specified in the test, but no specific value was passed to the - * CLI. That means we want to run the test once for every - * possible combination of parameter values or, if --single was - * passed to the CLI, a single time with a random set of - * parameters. */ - MunitParameter* wild_params = NULL; - size_t wild_params_l = 0; - const MunitParameterEnum* pe; - const MunitParameter* cli_p; - bool filled; - unsigned int possible; - char** vals; - size_t first_wild; - const MunitParameter* wp; - int pidx; - - munit_rand_seed(runner->seed); - - fprintf(MUNIT_OUTPUT_FILE, "%-" MUNIT_XSTRINGIFY(MUNIT_TEST_NAME_LEN) "s", test_name); - - if (test->parameters == NULL) { - /* No parameters. Simple, nice. */ - munit_test_runner_run_test_with_params(runner, test, NULL); - } else { - fputc('\n', MUNIT_OUTPUT_FILE); - - for (pe = test->parameters ; pe != NULL && pe->name != NULL ; pe++) { - /* Did we received a value for this parameter from the CLI? */ - filled = false; - for (cli_p = runner->parameters ; cli_p != NULL && cli_p->name != NULL ; cli_p++) { - if (strcmp(cli_p->name, pe->name) == 0) { - if (MUNIT_UNLIKELY(munit_parameters_add(¶ms_l, ¶ms, pe->name, cli_p->value) != MUNIT_OK)) - goto cleanup; - filled = true; - break; - } - } - if (filled) - continue; - - /* Nothing from CLI, is the enum NULL/empty? We're not a - * fuzzer… */ - if (pe->values == NULL || pe->values[0] == NULL) - continue; - - /* If --single was passed to the CLI, choose a value from the - * list of possibilities randomly. */ - if (runner->single_parameter_mode) { - possible = 0; - for (vals = pe->values ; *vals != NULL ; vals++) - possible++; - /* We want the tests to be reproducible, even if you're only - * running a single test, but we don't want every test with - * the same number of parameters to choose the same parameter - * number, so use the test name as a primitive salt. */ - pidx = munit_rand_at_most(munit_str_hash(test_name), possible - 1); - if (MUNIT_UNLIKELY(munit_parameters_add(¶ms_l, ¶ms, pe->name, pe->values[pidx]) != MUNIT_OK)) - goto cleanup; - } else { - /* We want to try every permutation. Put in a placeholder - * entry, we'll iterate through them later. */ - if (MUNIT_UNLIKELY(munit_parameters_add(&wild_params_l, &wild_params, pe->name, NULL) != MUNIT_OK)) - goto cleanup; - } - } - - if (wild_params_l != 0) { - first_wild = params_l; - for (wp = wild_params ; wp != NULL && wp->name != NULL ; wp++) { - for (pe = test->parameters ; pe != NULL && pe->name != NULL && pe->values != NULL ; pe++) { - if (strcmp(wp->name, pe->name) == 0) { - if (MUNIT_UNLIKELY(munit_parameters_add(¶ms_l, ¶ms, pe->name, pe->values[0]) != MUNIT_OK)) - goto cleanup; - } - } - } - - munit_test_runner_run_test_wild(runner, test, test_name, params, params + first_wild); - } else { - munit_test_runner_run_test_with_params(runner, test, params); - } - - cleanup: - free(params); - free(wild_params); - } - - munit_maybe_free_concat(test_name, prefix, test->name); -} - -/* Recurse through the suite and run all the tests. If a list of - * tests to run was provied on the command line, run only those - * tests. */ -static void -munit_test_runner_run_suite(MunitTestRunner* runner, - const MunitSuite* suite, - const char* prefix) { - size_t pre_l; - char* pre = munit_maybe_concat(&pre_l, (char*) prefix, (char*) suite->prefix); - const MunitTest* test; - const char** test_name; - const MunitSuite* child_suite; - - /* Run the tests. */ - for (test = suite->tests ; test != NULL && test->test != NULL ; test++) { - if (runner->tests != NULL) { /* Specific tests were requested on the CLI */ - for (test_name = runner->tests ; test_name != NULL && *test_name != NULL ; test_name++) { - if ((pre_l == 0 || strncmp(pre, *test_name, pre_l) == 0) && - strncmp(test->name, *test_name + pre_l, strlen(*test_name + pre_l)) == 0) { - munit_test_runner_run_test(runner, test, pre); - if (runner->fatal_failures && (runner->report.failed != 0 || runner->report.errored != 0)) - goto cleanup; - } - } - } else { /* Run all tests */ - munit_test_runner_run_test(runner, test, pre); - } - } - - if (runner->fatal_failures && (runner->report.failed != 0 || runner->report.errored != 0)) - goto cleanup; - - /* Run any child suites. */ - for (child_suite = suite->suites ; child_suite != NULL && child_suite->prefix != NULL ; child_suite++) { - munit_test_runner_run_suite(runner, child_suite, pre); - } - - cleanup: - - munit_maybe_free_concat(pre, prefix, suite->prefix); -} - -static void -munit_test_runner_run(MunitTestRunner* runner) { - munit_test_runner_run_suite(runner, runner->suite, NULL); -} - -static void -munit_print_help(int argc, char* const argv[MUNIT_ARRAY_PARAM(argc + 1)], void* user_data, const MunitArgument arguments[]) { - const MunitArgument* arg; - (void) argc; - - printf("USAGE: %s [OPTIONS...] [TEST...]\n\n", argv[0]); - puts(" --seed SEED\n" - " Value used to seed the PRNG. Must be a 32-bit integer in decimal\n" - " notation with no separators (commas, decimals, spaces, etc.), or\n" - " hexidecimal prefixed by \"0x\".\n" - " --iterations N\n" - " Run each test N times. 0 means the default number.\n" - " --param name value\n" - " A parameter key/value pair which will be passed to any test with\n" - " takes a parameter of that name. If not provided, the test will be\n" - " run once for each possible parameter value.\n" - " --list Write a list of all available tests.\n" - " --list-params\n" - " Write a list of all available tests and their possible parameters.\n" - " --single Run each parameterized test in a single configuration instead of\n" - " every possible combination\n" - " --log-visible debug|info|warning|error\n" - " --log-fatal debug|info|warning|error\n" - " Set the level at which messages of different severities are visible,\n" - " or cause the test to terminate.\n" -#if !defined(MUNIT_NO_FORK) - " --no-fork Do not execute tests in a child process. If this option is supplied\n" - " and a test crashes (including by failing an assertion), no further\n" - " tests will be performed.\n" -#endif - " --fatal-failures\n" - " Stop executing tests as soon as a failure is found.\n" - " --show-stderr\n" - " Show data written to stderr by the tests, even if the test succeeds.\n" - " --color auto|always|never\n" - " Colorize (or don't) the output.\n" - /* 12345678901234567890123456789012345678901234567890123456789012345678901234567890 */ - " --help Print this help message and exit.\n"); -#if defined(MUNIT_NL_LANGINFO) - setlocale(LC_ALL, ""); - fputs((strcasecmp("UTF-8", nl_langinfo(CODESET)) == 0) ? "µnit" : "munit", stdout); -#else - puts("munit"); -#endif - printf(" %d.%d.%d\n" - "Full documentation at: https://nemequ.github.io/munit/\n", - (MUNIT_CURRENT_VERSION >> 16) & 0xff, - (MUNIT_CURRENT_VERSION >> 8) & 0xff, - (MUNIT_CURRENT_VERSION >> 0) & 0xff); - for (arg = arguments ; arg != NULL && arg->name != NULL ; arg++) - arg->write_help(arg, user_data); -} - -static const MunitArgument* -munit_arguments_find(const MunitArgument arguments[], const char* name) { - const MunitArgument* arg; - - for (arg = arguments ; arg != NULL && arg->name != NULL ; arg++) - if (strcmp(arg->name, name) == 0) - return arg; - - return NULL; -} - -static void -munit_suite_list_tests(const MunitSuite* suite, bool show_params, const char* prefix) { - size_t pre_l; - char* pre = munit_maybe_concat(&pre_l, (char*) prefix, (char*) suite->prefix); - const MunitTest* test; - const MunitParameterEnum* params; - bool first; - char** val; - const MunitSuite* child_suite; - - for (test = suite->tests ; - test != NULL && test->name != NULL ; - test++) { - if (pre != NULL) - fputs(pre, stdout); - puts(test->name); - - if (show_params) { - for (params = test->parameters ; - params != NULL && params->name != NULL ; - params++) { - fprintf(stdout, " - %s: ", params->name); - if (params->values == NULL) { - puts("Any"); - } else { - first = true; - for (val = params->values ; - *val != NULL ; - val++ ) { - if(!first) { - fputs(", ", stdout); - } else { - first = false; - } - fputs(*val, stdout); - } - putc('\n', stdout); - } - } - } - } - - for (child_suite = suite->suites ; child_suite != NULL && child_suite->prefix != NULL ; child_suite++) { - munit_suite_list_tests(child_suite, show_params, pre); - } - - munit_maybe_free_concat(pre, prefix, suite->prefix); -} - -static bool -munit_stream_supports_ansi(FILE *stream) { -#if !defined(_WIN32) - return isatty(fileno(stream)); -#else - -#if !defined(__MINGW32__) - size_t ansicon_size = 0; -#endif - - if (isatty(fileno(stream))) { -#if !defined(__MINGW32__) - getenv_s(&ansicon_size, NULL, 0, "ANSICON"); - return ansicon_size != 0; -#else - return getenv("ANSICON") != NULL; -#endif - } - return false; -#endif -} - -int -munit_suite_main_custom(const MunitSuite* suite, void* user_data, - int argc, char* const argv[MUNIT_ARRAY_PARAM(argc + 1)], - const MunitArgument arguments[]) { - int result = EXIT_FAILURE; - MunitTestRunner runner; - size_t parameters_size = 0; - size_t tests_size = 0; - int arg; - - char* envptr; - unsigned long ts; - char* endptr; - unsigned long long iterations; - MunitLogLevel level; - const MunitArgument* argument; - const char** runner_tests; - unsigned int tests_run; - unsigned int tests_total; - - runner.prefix = NULL; - runner.suite = NULL; - runner.tests = NULL; - runner.seed = 0; - runner.iterations = 0; - runner.parameters = NULL; - runner.single_parameter_mode = false; - runner.user_data = NULL; - - runner.report.successful = 0; - runner.report.skipped = 0; - runner.report.failed = 0; - runner.report.errored = 0; -#if defined(MUNIT_ENABLE_TIMING) - runner.report.cpu_clock = 0; - runner.report.wall_clock = 0; -#endif - - runner.colorize = false; -#if !defined(_WIN32) - runner.fork = true; -#else - runner.fork = false; -#endif - runner.show_stderr = false; - runner.fatal_failures = false; - runner.suite = suite; - runner.user_data = user_data; - runner.seed = munit_rand_generate_seed(); - runner.colorize = munit_stream_supports_ansi(MUNIT_OUTPUT_FILE); - - for (arg = 1 ; arg < argc ; arg++) { - if (strncmp("--", argv[arg], 2) == 0) { - if (strcmp("seed", argv[arg] + 2) == 0) { - if (arg + 1 >= argc) { - munit_logf_internal(MUNIT_LOG_ERROR, stderr, "%s requires an argument", argv[arg]); - goto cleanup; - } - - envptr = argv[arg + 1]; - ts = strtoul(argv[arg + 1], &envptr, 0); - if (*envptr != '\0' || ts > (~((munit_uint32_t) 0U))) { - munit_logf_internal(MUNIT_LOG_ERROR, stderr, "invalid value ('%s') passed to %s", argv[arg + 1], argv[arg]); - goto cleanup; - } - runner.seed = (munit_uint32_t) ts; - - arg++; - } else if (strcmp("iterations", argv[arg] + 2) == 0) { - if (arg + 1 >= argc) { - munit_logf_internal(MUNIT_LOG_ERROR, stderr, "%s requires an argument", argv[arg]); - goto cleanup; - } - - endptr = argv[arg + 1]; - iterations = strtoul(argv[arg + 1], &endptr, 0); - if (*endptr != '\0' || iterations > UINT_MAX) { - munit_logf_internal(MUNIT_LOG_ERROR, stderr, "invalid value ('%s') passed to %s", argv[arg + 1], argv[arg]); - goto cleanup; - } - - runner.iterations = (unsigned int) iterations; - - arg++; - } else if (strcmp("param", argv[arg] + 2) == 0) { - if (arg + 2 >= argc) { - munit_logf_internal(MUNIT_LOG_ERROR, stderr, "%s requires two arguments", argv[arg]); - goto cleanup; - } - - runner.parameters = realloc(runner.parameters, sizeof(MunitParameter) * (parameters_size + 2)); - if (runner.parameters == NULL) { - munit_log_internal(MUNIT_LOG_ERROR, stderr, "failed to allocate memory"); - goto cleanup; - } - runner.parameters[parameters_size].name = (char*) argv[arg + 1]; - runner.parameters[parameters_size].value = (char*) argv[arg + 2]; - parameters_size++; - runner.parameters[parameters_size].name = NULL; - runner.parameters[parameters_size].value = NULL; - arg += 2; - } else if (strcmp("color", argv[arg] + 2) == 0) { - if (arg + 1 >= argc) { - munit_logf_internal(MUNIT_LOG_ERROR, stderr, "%s requires an argument", argv[arg]); - goto cleanup; - } - - if (strcmp(argv[arg + 1], "always") == 0) - runner.colorize = true; - else if (strcmp(argv[arg + 1], "never") == 0) - runner.colorize = false; - else if (strcmp(argv[arg + 1], "auto") == 0) - runner.colorize = munit_stream_supports_ansi(MUNIT_OUTPUT_FILE); - else { - munit_logf_internal(MUNIT_LOG_ERROR, stderr, "invalid value ('%s') passed to %s", argv[arg + 1], argv[arg]); - goto cleanup; - } - - arg++; - } else if (strcmp("help", argv[arg] + 2) == 0) { - munit_print_help(argc, argv, user_data, arguments); - result = EXIT_SUCCESS; - goto cleanup; - } else if (strcmp("single", argv[arg] + 2) == 0) { - runner.single_parameter_mode = true; - } else if (strcmp("show-stderr", argv[arg] + 2) == 0) { - runner.show_stderr = true; -#if !defined(_WIN32) - } else if (strcmp("no-fork", argv[arg] + 2) == 0) { - runner.fork = false; -#endif - } else if (strcmp("fatal-failures", argv[arg] + 2) == 0) { - runner.fatal_failures = true; - } else if (strcmp("log-visible", argv[arg] + 2) == 0 || - strcmp("log-fatal", argv[arg] + 2) == 0) { - if (arg + 1 >= argc) { - munit_logf_internal(MUNIT_LOG_ERROR, stderr, "%s requires an argument", argv[arg]); - goto cleanup; - } - - if (strcmp(argv[arg + 1], "debug") == 0) - level = MUNIT_LOG_DEBUG; - else if (strcmp(argv[arg + 1], "info") == 0) - level = MUNIT_LOG_INFO; - else if (strcmp(argv[arg + 1], "warning") == 0) - level = MUNIT_LOG_WARNING; - else if (strcmp(argv[arg + 1], "error") == 0) - level = MUNIT_LOG_ERROR; - else { - munit_logf_internal(MUNIT_LOG_ERROR, stderr, "invalid value ('%s') passed to %s", argv[arg + 1], argv[arg]); - goto cleanup; - } - - if (strcmp("log-visible", argv[arg] + 2) == 0) - munit_log_level_visible = level; - else - munit_log_level_fatal = level; - - arg++; - } else if (strcmp("list", argv[arg] + 2) == 0) { - munit_suite_list_tests(suite, false, NULL); - result = EXIT_SUCCESS; - goto cleanup; - } else if (strcmp("list-params", argv[arg] + 2) == 0) { - munit_suite_list_tests(suite, true, NULL); - result = EXIT_SUCCESS; - goto cleanup; - } else { - argument = munit_arguments_find(arguments, argv[arg] + 2); - if (argument == NULL) { - munit_logf_internal(MUNIT_LOG_ERROR, stderr, "unknown argument ('%s')", argv[arg]); - goto cleanup; - } - - if (!argument->parse_argument(suite, user_data, &arg, argc, argv)) - goto cleanup; - } - } else { - runner_tests = realloc((void*) runner.tests, sizeof(char*) * (tests_size + 2)); - if (runner_tests == NULL) { - munit_log_internal(MUNIT_LOG_ERROR, stderr, "failed to allocate memory"); - goto cleanup; - } - runner.tests = runner_tests; - runner.tests[tests_size++] = argv[arg]; - runner.tests[tests_size] = NULL; - } - } - - fflush(stderr); - fprintf(MUNIT_OUTPUT_FILE, "Running test suite with seed 0x%08" PRIx32 "...\n", runner.seed); - - munit_test_runner_run(&runner); - - tests_run = runner.report.successful + runner.report.failed + runner.report.errored; - tests_total = tests_run + runner.report.skipped; - if (tests_run == 0) { - fprintf(stderr, "No tests run, %d (100%%) skipped.\n", runner.report.skipped); - } else { - fprintf(MUNIT_OUTPUT_FILE, "%d of %d (%0.0f%%) tests successful, %d (%0.0f%%) test skipped.\n", - runner.report.successful, tests_run, - (((double) runner.report.successful) / ((double) tests_run)) * 100.0, - runner.report.skipped, - (((double) runner.report.skipped) / ((double) tests_total)) * 100.0); - } - - if (runner.report.failed == 0 && runner.report.errored == 0) { - result = EXIT_SUCCESS; - } - - cleanup: - free(runner.parameters); - free((void*) runner.tests); - - return result; -} - -int -munit_suite_main(const MunitSuite* suite, void* user_data, - int argc, char* const argv[MUNIT_ARRAY_PARAM(argc + 1)]) { - return munit_suite_main_custom(suite, user_data, argc, argv, NULL); -} diff --git a/lib/munit/munit.h b/lib/munit/munit.h deleted file mode 100644 index 1d5672c3..00000000 --- a/lib/munit/munit.h +++ /dev/null @@ -1,535 +0,0 @@ -/* µnit Testing Framework - * Copyright (c) 2013-2017 Evan Nemerson - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#if !defined(MUNIT_H) -#define MUNIT_H - -#include -#include - -#define MUNIT_VERSION(major, minor, revision) \ - (((major) << 16) | ((minor) << 8) | (revision)) - -#define MUNIT_CURRENT_VERSION MUNIT_VERSION(0, 4, 1) - -#if defined(_MSC_VER) && (_MSC_VER < 1600) -# define munit_int8_t __int8 -# define munit_uint8_t unsigned __int8 -# define munit_int16_t __int16 -# define munit_uint16_t unsigned __int16 -# define munit_int32_t __int32 -# define munit_uint32_t unsigned __int32 -# define munit_int64_t __int64 -# define munit_uint64_t unsigned __int64 -#else -# include -# define munit_int8_t int8_t -# define munit_uint8_t uint8_t -# define munit_int16_t int16_t -# define munit_uint16_t uint16_t -# define munit_int32_t int32_t -# define munit_uint32_t uint32_t -# define munit_int64_t int64_t -# define munit_uint64_t uint64_t -#endif - -#if defined(_MSC_VER) && (_MSC_VER < 1800) -# if !defined(PRIi8) -# define PRIi8 "i" -# endif -# if !defined(PRIi16) -# define PRIi16 "i" -# endif -# if !defined(PRIi32) -# define PRIi32 "i" -# endif -# if !defined(PRIi64) -# define PRIi64 "I64i" -# endif -# if !defined(PRId8) -# define PRId8 "d" -# endif -# if !defined(PRId16) -# define PRId16 "d" -# endif -# if !defined(PRId32) -# define PRId32 "d" -# endif -# if !defined(PRId64) -# define PRId64 "I64d" -# endif -# if !defined(PRIx8) -# define PRIx8 "x" -# endif -# if !defined(PRIx16) -# define PRIx16 "x" -# endif -# if !defined(PRIx32) -# define PRIx32 "x" -# endif -# if !defined(PRIx64) -# define PRIx64 "I64x" -# endif -# if !defined(PRIu8) -# define PRIu8 "u" -# endif -# if !defined(PRIu16) -# define PRIu16 "u" -# endif -# if !defined(PRIu32) -# define PRIu32 "u" -# endif -# if !defined(PRIu64) -# define PRIu64 "I64u" -# endif -# if !defined(bool) -# define bool int -# endif -# if !defined(true) -# define true (!0) -# endif -# if !defined(false) -# define false (!!0) -# endif -#else -# include -# include -#endif - -#if defined(__cplusplus) -extern "C" { -#endif - -#if defined(__GNUC__) -# define MUNIT_LIKELY(expr) (__builtin_expect ((expr), 1)) -# define MUNIT_UNLIKELY(expr) (__builtin_expect ((expr), 0)) -# define MUNIT_UNUSED __attribute__((__unused__)) -#else -# define MUNIT_LIKELY(expr) (expr) -# define MUNIT_UNLIKELY(expr) (expr) -# define MUNIT_UNUSED -#endif - -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__PGI) -# define MUNIT_ARRAY_PARAM(name) name -#else -# define MUNIT_ARRAY_PARAM(name) -#endif - -#if !defined(_WIN32) -# define MUNIT_SIZE_MODIFIER "z" -# define MUNIT_CHAR_MODIFIER "hh" -# define MUNIT_SHORT_MODIFIER "h" -#else -# if defined(_M_X64) || defined(__amd64__) -# define MUNIT_SIZE_MODIFIER "I64" -# else -# define MUNIT_SIZE_MODIFIER "" -# endif -# define MUNIT_CHAR_MODIFIER "" -# define MUNIT_SHORT_MODIFIER "" -#endif - -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L -# define MUNIT_NO_RETURN _Noreturn -#elif defined(__GNUC__) -# define MUNIT_NO_RETURN __attribute__((__noreturn__)) -#elif defined(_MSC_VER) -# define MUNIT_NO_RETURN __declspec(noreturn) -#else -# define MUNIT_NO_RETURN -#endif - -#if defined(_MSC_VER) && (_MSC_VER >= 1500) -# define MUNIT__PUSH_DISABLE_MSVC_C4127 __pragma(warning(push)) __pragma(warning(disable:4127)) -# define MUNIT__POP_DISABLE_MSVC_C4127 __pragma(warning(pop)) -#else -# define MUNIT__PUSH_DISABLE_MSVC_C4127 -# define MUNIT__POP_DISABLE_MSVC_C4127 -#endif - -typedef enum { - MUNIT_LOG_DEBUG, - MUNIT_LOG_INFO, - MUNIT_LOG_WARNING, - MUNIT_LOG_ERROR -} MunitLogLevel; - -#if defined(__GNUC__) && !defined(__MINGW32__) -# define MUNIT_PRINTF(string_index, first_to_check) __attribute__((format (printf, string_index, first_to_check))) -#else -# define MUNIT_PRINTF(string_index, first_to_check) -#endif - -MUNIT_PRINTF(4, 5) -void munit_logf_ex(MunitLogLevel level, const char* filename, int line, const char* format, ...); - -#define munit_logf(level, format, ...) \ - munit_logf_ex(level, __FILE__, __LINE__, format, __VA_ARGS__) - -#define munit_log(level, msg) \ - munit_logf(level, "%s", msg) - -MUNIT_NO_RETURN -MUNIT_PRINTF(3, 4) -void munit_errorf_ex(const char* filename, int line, const char* format, ...); - -#define munit_errorf(format, ...) \ - munit_errorf_ex(__FILE__, __LINE__, format, __VA_ARGS__) - -#define munit_error(msg) \ - munit_errorf("%s", msg) - -#define munit_assert(expr) \ - do { \ - if (!MUNIT_LIKELY(expr)) { \ - munit_error("assertion failed: " #expr); \ - } \ - MUNIT__PUSH_DISABLE_MSVC_C4127 \ - } while (0) \ - MUNIT__POP_DISABLE_MSVC_C4127 - -#define munit_assert_true(expr) \ - do { \ - if (!MUNIT_LIKELY(expr)) { \ - munit_error("assertion failed: " #expr " is not true"); \ - } \ - MUNIT__PUSH_DISABLE_MSVC_C4127 \ - } while (0) \ - MUNIT__POP_DISABLE_MSVC_C4127 - -#define munit_assert_false(expr) \ - do { \ - if (!MUNIT_LIKELY(!(expr))) { \ - munit_error("assertion failed: " #expr " is not false"); \ - } \ - MUNIT__PUSH_DISABLE_MSVC_C4127 \ - } while (0) \ - MUNIT__POP_DISABLE_MSVC_C4127 - -#define munit_assert_type_full(prefix, suffix, T, fmt, a, op, b) \ - do { \ - T munit_tmp_a_ = (a); \ - T munit_tmp_b_ = (b); \ - if (!(munit_tmp_a_ op munit_tmp_b_)) { \ - munit_errorf("assertion failed: %s %s %s (" prefix "%" fmt suffix " %s " prefix "%" fmt suffix ")", \ - #a, #op, #b, munit_tmp_a_, #op, munit_tmp_b_); \ - } \ - MUNIT__PUSH_DISABLE_MSVC_C4127 \ - } while (0) \ - MUNIT__POP_DISABLE_MSVC_C4127 - -#define munit_assert_type(T, fmt, a, op, b) \ - munit_assert_type_full("", "", T, fmt, a, op, b) - -#define munit_assert_char(a, op, b) \ - munit_assert_type_full("'\\x", "'", char, "02" MUNIT_CHAR_MODIFIER "x", a, op, b) -#define munit_assert_uchar(a, op, b) \ - munit_assert_type_full("'\\x", "'", unsigned char, "02" MUNIT_CHAR_MODIFIER "x", a, op, b) -#define munit_assert_short(a, op, b) \ - munit_assert_type(short, MUNIT_SHORT_MODIFIER "d", a, op, b) -#define munit_assert_ushort(a, op, b) \ - munit_assert_type(unsigned short, MUNIT_SHORT_MODIFIER "u", a, op, b) -#define munit_assert_int(a, op, b) \ - munit_assert_type(int, "d", a, op, b) -#define munit_assert_uint(a, op, b) \ - munit_assert_type(unsigned int, "u", a, op, b) -#define munit_assert_long(a, op, b) \ - munit_assert_type(long int, "ld", a, op, b) -#define munit_assert_ulong(a, op, b) \ - munit_assert_type(unsigned long int, "lu", a, op, b) -#define munit_assert_llong(a, op, b) \ - munit_assert_type(long long int, "lld", a, op, b) -#define munit_assert_ullong(a, op, b) \ - munit_assert_type(unsigned long long int, "llu", a, op, b) - -#define munit_assert_size(a, op, b) \ - munit_assert_type(size_t, MUNIT_SIZE_MODIFIER "u", a, op, b) - -#define munit_assert_float(a, op, b) \ - munit_assert_type(float, "f", a, op, b) -#define munit_assert_double(a, op, b) \ - munit_assert_type(double, "g", a, op, b) -#define munit_assert_ptr(a, op, b) \ - munit_assert_type(const void*, "p", a, op, b) - -#define munit_assert_int8(a, op, b) \ - munit_assert_type(munit_int8_t, PRIi8, a, op, b) -#define munit_assert_uint8(a, op, b) \ - munit_assert_type(munit_uint8_t, PRIu8, a, op, b) -#define munit_assert_int16(a, op, b) \ - munit_assert_type(munit_int16_t, PRIi16, a, op, b) -#define munit_assert_uint16(a, op, b) \ - munit_assert_type(munit_uint16_t, PRIu16, a, op, b) -#define munit_assert_int32(a, op, b) \ - munit_assert_type(munit_int32_t, PRIi32, a, op, b) -#define munit_assert_uint32(a, op, b) \ - munit_assert_type(munit_uint32_t, PRIu32, a, op, b) -#define munit_assert_int64(a, op, b) \ - munit_assert_type(munit_int64_t, PRIi64, a, op, b) -#define munit_assert_uint64(a, op, b) \ - munit_assert_type(munit_uint64_t, PRIu64, a, op, b) - -#define munit_assert_double_equal(a, b, precision) \ - do { \ - const double munit_tmp_a_ = (a); \ - const double munit_tmp_b_ = (b); \ - const double munit_tmp_diff_ = ((munit_tmp_a_ - munit_tmp_b_) < 0) ? \ - -(munit_tmp_a_ - munit_tmp_b_) : \ - (munit_tmp_a_ - munit_tmp_b_); \ - if (MUNIT_UNLIKELY(munit_tmp_diff_ > 1e-##precision)) { \ - munit_errorf("assertion failed: %s == %s (%0." #precision "g == %0." #precision "g)", \ - #a, #b, munit_tmp_a_, munit_tmp_b_); \ - } \ - MUNIT__PUSH_DISABLE_MSVC_C4127 \ - } while (0) \ - MUNIT__POP_DISABLE_MSVC_C4127 - -#include -#define munit_assert_string_equal(a, b) \ - do { \ - const char* munit_tmp_a_ = a; \ - const char* munit_tmp_b_ = b; \ - if (MUNIT_UNLIKELY(strcmp(munit_tmp_a_, munit_tmp_b_) != 0)) { \ - munit_errorf("assertion failed: string %s == %s (\"%s\" == \"%s\")", \ - #a, #b, munit_tmp_a_, munit_tmp_b_); \ - } \ - MUNIT__PUSH_DISABLE_MSVC_C4127 \ - } while (0) \ - MUNIT__POP_DISABLE_MSVC_C4127 - -#define munit_assert_string_not_equal(a, b) \ - do { \ - const char* munit_tmp_a_ = a; \ - const char* munit_tmp_b_ = b; \ - if (MUNIT_UNLIKELY(strcmp(munit_tmp_a_, munit_tmp_b_) == 0)) { \ - munit_errorf("assertion failed: string %s != %s (\"%s\" == \"%s\")", \ - #a, #b, munit_tmp_a_, munit_tmp_b_); \ - } \ - MUNIT__PUSH_DISABLE_MSVC_C4127 \ - } while (0) \ - MUNIT__POP_DISABLE_MSVC_C4127 - -#define munit_assert_memory_equal(size, a, b) \ - do { \ - const unsigned char* munit_tmp_a_ = (const unsigned char*) (a); \ - const unsigned char* munit_tmp_b_ = (const unsigned char*) (b); \ - const size_t munit_tmp_size_ = (size); \ - if (MUNIT_UNLIKELY(memcmp(munit_tmp_a_, munit_tmp_b_, munit_tmp_size_)) != 0) { \ - size_t munit_tmp_pos_; \ - for (munit_tmp_pos_ = 0 ; munit_tmp_pos_ < munit_tmp_size_ ; munit_tmp_pos_++) { \ - if (munit_tmp_a_[munit_tmp_pos_] != munit_tmp_b_[munit_tmp_pos_]) { \ - munit_errorf("assertion failed: memory %s == %s, at offset %" MUNIT_SIZE_MODIFIER "u", \ - #a, #b, munit_tmp_pos_); \ - break; \ - } \ - } \ - } \ - MUNIT__PUSH_DISABLE_MSVC_C4127 \ - } while (0) \ - MUNIT__POP_DISABLE_MSVC_C4127 - -#define munit_assert_memory_not_equal(size, a, b) \ - do { \ - const unsigned char* munit_tmp_a_ = (const unsigned char*) (a); \ - const unsigned char* munit_tmp_b_ = (const unsigned char*) (b); \ - const size_t munit_tmp_size_ = (size); \ - if (MUNIT_UNLIKELY(memcmp(munit_tmp_a_, munit_tmp_b_, munit_tmp_size_)) == 0) { \ - munit_errorf("assertion failed: memory %s != %s (%zu bytes)", \ - #a, #b, munit_tmp_size_); \ - } \ - MUNIT__PUSH_DISABLE_MSVC_C4127 \ - } while (0) \ - MUNIT__POP_DISABLE_MSVC_C4127 - -#define munit_assert_ptr_equal(a, b) \ - munit_assert_ptr(a, ==, b) -#define munit_assert_ptr_not_equal(a, b) \ - munit_assert_ptr(a, !=, b) -#define munit_assert_null(ptr) \ - munit_assert_ptr(ptr, ==, NULL) -#define munit_assert_not_null(ptr) \ - munit_assert_ptr(ptr, !=, NULL) -#define munit_assert_ptr_null(ptr) \ - munit_assert_ptr(ptr, ==, NULL) -#define munit_assert_ptr_not_null(ptr) \ - munit_assert_ptr(ptr, !=, NULL) - -/*** Memory allocation ***/ - -void* munit_malloc_ex(const char* filename, int line, size_t size); - -#define munit_malloc(size) \ - munit_malloc_ex(__FILE__, __LINE__, (size)) - -#define munit_new(type) \ - ((type*) munit_malloc(sizeof(type))) - -#define munit_calloc(nmemb, size) \ - munit_malloc((nmemb) * (size)) - -#define munit_newa(type, nmemb) \ - ((type*) munit_calloc((nmemb), sizeof(type))) - -/*** Random number generation ***/ - -void munit_rand_seed(munit_uint32_t seed); -munit_uint32_t munit_rand_uint32(void); -int munit_rand_int_range(int min, int max); -double munit_rand_double(void); -void munit_rand_memory(size_t size, munit_uint8_t buffer[MUNIT_ARRAY_PARAM(size)]); - -/*** Tests and Suites ***/ - -typedef enum { - /* Test successful */ - MUNIT_OK, - /* Test failed */ - MUNIT_FAIL, - /* Test was skipped */ - MUNIT_SKIP, - /* Test failed due to circumstances not intended to be tested - * (things like network errors, invalid parameter value, failure to - * allocate memory in the test harness, etc.). */ - MUNIT_ERROR -} MunitResult; - -typedef struct { - char* name; - char** values; -} MunitParameterEnum; - -typedef struct { - char* name; - char* value; -} MunitParameter; - -const char* munit_parameters_get(const MunitParameter params[], const char* key); - -typedef enum { - MUNIT_TEST_OPTION_NONE = 0, - MUNIT_TEST_OPTION_SINGLE_ITERATION = 1 << 0, - MUNIT_TEST_OPTION_TODO = 1 << 1 -} MunitTestOptions; - -typedef MunitResult (* MunitTestFunc)(const MunitParameter params[], void* user_data_or_fixture); -typedef void* (* MunitTestSetup)(const MunitParameter params[], void* user_data); -typedef void (* MunitTestTearDown)(void* fixture); - -typedef struct { - char* name; - MunitTestFunc test; - MunitTestSetup setup; - MunitTestTearDown tear_down; - MunitTestOptions options; - MunitParameterEnum* parameters; -} MunitTest; - -typedef enum { - MUNIT_SUITE_OPTION_NONE = 0 -} MunitSuiteOptions; - -typedef struct MunitSuite_ MunitSuite; - -struct MunitSuite_ { - char* prefix; - MunitTest* tests; - MunitSuite* suites; - unsigned int iterations; - MunitSuiteOptions options; -}; - -int munit_suite_main(const MunitSuite* suite, void* user_data, int argc, char* const argv[MUNIT_ARRAY_PARAM(argc + 1)]); - -/* Note: I'm not very happy with this API; it's likely to change if I - * figure out something better. Suggestions welcome. */ - -typedef struct MunitArgument_ MunitArgument; - -struct MunitArgument_ { - char* name; - bool (* parse_argument)(const MunitSuite* suite, void* user_data, int* arg, int argc, char* const argv[MUNIT_ARRAY_PARAM(argc + 1)]); - void (* write_help)(const MunitArgument* argument, void* user_data); -}; - -int munit_suite_main_custom(const MunitSuite* suite, - void* user_data, - int argc, char* const argv[MUNIT_ARRAY_PARAM(argc + 1)], - const MunitArgument arguments[]); - -#if defined(MUNIT_ENABLE_ASSERT_ALIASES) - -#define assert_true(expr) munit_assert_true(expr) -#define assert_false(expr) munit_assert_false(expr) -#define assert_char(a, op, b) munit_assert_char(a, op, b) -#define assert_uchar(a, op, b) munit_assert_uchar(a, op, b) -#define assert_short(a, op, b) munit_assert_short(a, op, b) -#define assert_ushort(a, op, b) munit_assert_ushort(a, op, b) -#define assert_int(a, op, b) munit_assert_int(a, op, b) -#define assert_uint(a, op, b) munit_assert_uint(a, op, b) -#define assert_long(a, op, b) munit_assert_long(a, op, b) -#define assert_ulong(a, op, b) munit_assert_ulong(a, op, b) -#define assert_llong(a, op, b) munit_assert_llong(a, op, b) -#define assert_ullong(a, op, b) munit_assert_ullong(a, op, b) -#define assert_size(a, op, b) munit_assert_size(a, op, b) -#define assert_float(a, op, b) munit_assert_float(a, op, b) -#define assert_double(a, op, b) munit_assert_double(a, op, b) -#define assert_ptr(a, op, b) munit_assert_ptr(a, op, b) - -#define assert_int8(a, op, b) munit_assert_int8(a, op, b) -#define assert_uint8(a, op, b) munit_assert_uint8(a, op, b) -#define assert_int16(a, op, b) munit_assert_int16(a, op, b) -#define assert_uint16(a, op, b) munit_assert_uint16(a, op, b) -#define assert_int32(a, op, b) munit_assert_int32(a, op, b) -#define assert_uint32(a, op, b) munit_assert_uint32(a, op, b) -#define assert_int64(a, op, b) munit_assert_int64(a, op, b) -#define assert_uint64(a, op, b) munit_assert_uint64(a, op, b) - -#define assert_double_equal(a, b, precision) munit_assert_double_equal(a, b, precision) -#define assert_string_equal(a, b) munit_assert_string_equal(a, b) -#define assert_string_not_equal(a, b) munit_assert_string_not_equal(a, b) -#define assert_memory_equal(size, a, b) munit_assert_memory_equal(size, a, b) -#define assert_memory_not_equal(size, a, b) munit_assert_memory_not_equal(size, a, b) -#define assert_ptr_equal(a, b) munit_assert_ptr_equal(a, b) -#define assert_ptr_not_equal(a, b) munit_assert_ptr_not_equal(a, b) -#define assert_ptr_null(ptr) munit_assert_null_equal(ptr) -#define assert_ptr_not_null(ptr) munit_assert_not_null(ptr) - -#define assert_null(ptr) munit_assert_null(ptr) -#define assert_not_null(ptr) munit_assert_not_null(ptr) - -#endif /* defined(MUNIT_ENABLE_ASSERT_ALIASES) */ - -#if defined(__cplusplus) -} -#endif - -#endif /* !defined(MUNIT_H) */ - -#if defined(MUNIT_ENABLE_ASSERT_ALIASES) -# if defined(assert) -# undef assert -# endif -# define assert(expr) munit_assert(expr) -#endif diff --git a/t/base64_tests.c b/t/base64_tests.c index 26431f5c..72d03856 100644 --- a/t/base64_tests.c +++ b/t/base64_tests.c @@ -1,40 +1,44 @@ #include +#include "t.h" #include "tests.h" -#include "tests_macros.h" #include "ft_base64.h" +#include "libft.h" -TEST_RESULT should_init_base64_ctx(TEST_PARAMS, TEST_DATA) +static int init_ctx() { - UNUSED(test_params); - UNUSED(test_data); t_base64_ctx ctx; char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\ abcdefghijklmnopqrstuvwxyz0123456789+/"; ft_base64_init(&ctx); - munit_assert_true(ctx.input_fd == STDIN_FILENO); - munit_assert_true(ctx.output_fd == STDOUT_FILENO); + _is(ctx.input_fd == STDIN_FILENO); + _is(ctx.output_fd == STDOUT_FILENO); - munit_assert_string_equal(alphabet, (char *)ctx.alphabet); + _is(ft_strcmp(alphabet, (char *)ctx.alphabet) == 0); - return MUNIT_OK; + _end("init ctx"); } -TEST_RESULT should_transform_base64_block(TEST_PARAMS, TEST_DATA) +static int transform_block() { - UNUSED(test_params); - UNUSED(test_data); - t_base64_ctx ctx; t_byte1 buff[FT_BASE64_DECODE_BLOCK_SIZE]; ft_base64_init(&ctx); ft_base64_encode_transform(&ctx, (t_byte1 *)"Man", buff); - munit_assert_string_equal((char *)buff, "TWFu"); + _is(ft_strcmp((char *)buff, "TWFu") == 0); ft_base64_encode_transform(&ctx, (t_byte1 *)"LOL", buff); - munit_assert_string_equal((char *)buff, "TE9M"); - return MUNIT_OK; + _is(ft_strcmp((char *)buff, "TE9M") == 0); + + _end("transform block"); +} + +int base64_tests(void) +{ + _should(init_ctx); + _should(transform_block); + return 0; } \ No newline at end of file diff --git a/t/md5_tests.c b/t/md5_tests.c index 00840cc8..63e3e10c 100644 --- a/t/md5_tests.c +++ b/t/md5_tests.c @@ -10,35 +10,29 @@ /* */ /* ************************************************************************** */ -#include "tests.h" -#include "tests_macros.h" +#include "t.h" #include "ft_md5.h" #include "libft.h" -TEST_RESULT should_init_md5_ctx(TEST_PARAMS, TEST_DATA) +static int init_ctx() { - UNUSED(test_params); - UNUSED(test_data); t_md5_ctx ctx; ft_md5_init(&ctx); - munit_assert_uint(ctx.a, ==, 0x67452301); - munit_assert_uint(ctx.b, ==, 0xefcdab89); - munit_assert_uint(ctx.c, ==, 0x98badcfe); - munit_assert_uint(ctx.d, ==, 0x10325476); - munit_assert_true(ctx.bit_len == 0); - for (int i = 0; i < 64; i++) - munit_assert_uchar(ctx.block[i], ==, 0); + _is(ctx.a == 0x67452301); + _is(ctx.b == 0xefcdab89); + _is(ctx.c == 0x98badcfe); + _is(ctx.d == 0x10325476); + _is(ctx.bit_len == 0); + for (int i = 0; i < FT_MD5_BLOCK_SIZE; i++) + _is(ctx.block[i] == 0); - return MUNIT_OK; + _end("init ctx"); } -TEST_RESULT md5_decode_string_to_int(TEST_PARAMS, TEST_DATA) +static int decode_string_to_int() { - UNUSED(test_params); - UNUSED(test_data); - t_byte1 block[FT_MD5_BLOCK_SIZE]; t_byte4 words[FT_MD5_WORDS_COUNT]; @@ -49,17 +43,15 @@ TEST_RESULT md5_decode_string_to_int(TEST_PARAMS, TEST_DATA) ft_md5_decode(words, block); - munit_assert_true((words[0] & 0xff) == 97); - munit_assert_true(((words[2] >> 8) & 0xff) == 98); - munit_assert_true(((words[15] >> 24) & 0xff) == 99); + _is((words[0] & 0xff) == 97); + _is(((words[2] >> 8) & 0xff) == 98); + _is(((words[15] >> 24) & 0xff) == 99); - return MUNIT_OK; + _end("decode string to int"); } -TEST_RESULT md5_update_change_count(TEST_PARAMS, TEST_DATA) +static int update_change_count() { - UNUSED(test_params); - UNUSED(test_data); t_md5_ctx ctx; char message[] = "hello, World!"; t_byte8 size = ft_strlen(message); @@ -67,16 +59,13 @@ TEST_RESULT md5_update_change_count(TEST_PARAMS, TEST_DATA) ft_md5_init(&ctx); ft_md5_update(&ctx, (t_byte1 *)message, size); - munit_assert_true(size * 8 == ctx.bit_len); + _is(size * 8 == ctx.bit_len); - return MUNIT_OK; + _end("update change count"); } -TEST_RESULT md5_encode_bits_to_string(TEST_PARAMS, TEST_DATA) +static int encode_bits_to_string() { - UNUSED(test_params); - UNUSED(test_data); - t_byte8 len; t_byte1 bits[FT_MD5_MESSAGE_LENGTH_BYTE]; @@ -94,18 +83,15 @@ TEST_RESULT md5_encode_bits_to_string(TEST_PARAMS, TEST_DATA) ft_md5_encode_len(bits, len); - munit_assert_true(bits[7] == (t_byte1)((len >> 56) & 0xff)); - munit_assert_true(bits[0] == (t_byte1)(len & 0xff)); - munit_assert_true(bits[1] == (t_byte1)((len >> 8) & 0xff)); + _is(bits[7] == (t_byte1)((len >> 56) & 0xff)); + _is(bits[0] == (t_byte1)(len & 0xff)); + _is(bits[1] == (t_byte1)((len >> 8) & 0xff)); - return MUNIT_OK; + _end("encode bits to string"); } -TEST_RESULT md5_encode_register(TEST_PARAMS, TEST_DATA) +static int encode_register() { - UNUSED(test_params); - UNUSED(test_data); - t_byte1 digest_part[4]; t_byte4 reg; @@ -119,19 +105,16 @@ TEST_RESULT md5_encode_register(TEST_PARAMS, TEST_DATA) ft_md5_encode_register(digest_part, reg); - munit_assert_true(digest_part[0] == (t_byte1)(reg & 0xff)); - munit_assert_true(digest_part[1] == (t_byte1)((reg >> 8) & 0xff)); - munit_assert_true(digest_part[2] == (t_byte1)((reg >> 16) & 0xff)); - munit_assert_true(digest_part[3] == (t_byte1)((reg >> 24) & 0xff)); + _is(digest_part[0] == (t_byte1)(reg & 0xff)); + _is(digest_part[1] == (t_byte1)((reg >> 8) & 0xff)); + _is(digest_part[2] == (t_byte1)((reg >> 16) & 0xff)); + _is(digest_part[3] == (t_byte1)((reg >> 24) & 0xff)); - return MUNIT_OK; + _end("encode register"); } -TEST_RESULT md5_create_digest(TEST_PARAMS, TEST_DATA) +static int create_digest() { - UNUSED(test_params); - UNUSED(test_data); - t_md5_ctx ctx; t_byte1 digest[FT_MD5_DIGEST_LENGTH_BYTE]; t_byte1 digest_string[FT_MD5_STRING_SIZE_BYTE]; @@ -146,33 +129,30 @@ TEST_RESULT md5_create_digest(TEST_PARAMS, TEST_DATA) ft_md5_final(digest, &ctx); ft_md5_digest_string(digest, digest_string); - munit_assert_string_equal((const char *)digest_string, - "d41d8cd98f00b204e9800998ecf8427e"); + _is(ft_strcmp((const char *)digest_string, + "d41d8cd98f00b204e9800998ecf8427e") == 0); ft_md5_init(&ctx); ft_md5_update(&ctx, case2, ft_strlen((const char *)case2)); ft_md5_final(digest, &ctx); ft_md5_digest_string(digest, digest_string); - munit_assert_string_equal((const char *)digest_string, - "0cc175b9c0f1b6a831c399e269772661"); + _is(ft_strcmp((const char *)digest_string, + "0cc175b9c0f1b6a831c399e269772661") == 0); ft_md5_init(&ctx); ft_md5_update(&ctx, case7, ft_strlen((const char *)case7)); ft_md5_final(digest, &ctx); ft_md5_digest_string(digest, digest_string); - munit_assert_string_equal((const char *)digest_string, - "2580a0aff7ef5e80f6b5432666530926"); + _is(ft_strcmp((const char *)digest_string, + "2580a0aff7ef5e80f6b5432666530926") == 0); - return MUNIT_OK; + _end("create digest"); } -TEST_RESULT md5_create_string(TEST_PARAMS, TEST_DATA) +static int create_digest_string() { - UNUSED(test_params); - UNUSED(test_data); - t_byte1 digest[FT_MD5_DIGEST_LENGTH_BYTE]; t_byte1 digest_string[FT_MD5_STRING_SIZE_BYTE]; t_byte4 a; @@ -193,7 +173,20 @@ TEST_RESULT md5_create_string(TEST_PARAMS, TEST_DATA) ft_md5_digest_string(digest, digest_string); - munit_assert_string_equal((const char *)digest_string, "d41d8cd98f00b204e9800998ecf8427e"); + _is(ft_strcmp((const char *)digest_string, + "d41d8cd98f00b204e9800998ecf8427e") == 0); - return MUNIT_OK; + _end("create digest string"); } + +int md5_tests() +{ + _should(init_ctx); + _should(decode_string_to_int); + _should(update_change_count); + _should(encode_bits_to_string); + _should(encode_register); + _should(create_digest); + _should(create_digest_string); + return 0; +} \ No newline at end of file diff --git a/t/sha_tests.c b/t/sha_tests.c index d840d3a0..3132b6b1 100644 --- a/t/sha_tests.c +++ b/t/sha_tests.c @@ -10,62 +10,54 @@ /* */ /* ************************************************************************** */ -#include "tests.h" -#include "tests_macros.h" +#include "t.h" #include "ft_sha.h" #include "libft.h" -TEST_RESULT should_init_ctx_sha256(TEST_PARAMS, TEST_DATA) +static int init_sha256_ctx() { - UNUSED(test_params); - UNUSED(test_data); t_sha256_ctx ctx; ft_sha256_init(&ctx); - munit_assert_uint(ctx.a, ==, 0x6a09e667); - munit_assert_uint(ctx.b, ==, 0xbb67ae85); - munit_assert_uint(ctx.c, ==, 0x3c6ef372); - munit_assert_uint(ctx.d, ==, 0xa54ff53a); - munit_assert_uint(ctx.e, ==, 0x510e527f); - munit_assert_uint(ctx.f, ==, 0x9b05688c); - munit_assert_uint(ctx.g, ==, 0x1f83d9ab); - munit_assert_uint(ctx.h, ==, 0x5be0cd19); - munit_assert_true(ctx.bit_len == 0); + _is(ctx.a == 0x6a09e667); + _is(ctx.b == 0xbb67ae85); + _is(ctx.c == 0x3c6ef372); + _is(ctx.d == 0xa54ff53a); + _is(ctx.e == 0x510e527f); + _is(ctx.f == 0x9b05688c); + _is(ctx.g == 0x1f83d9ab); + _is(ctx.h == 0x5be0cd19); + _is(ctx.bit_len == 0); for (int i = 0; i < 64; i++) - munit_assert_uchar(ctx.block[i], ==, 0); + _is(ctx.block[i] == 0); - return MUNIT_OK; + _end("init sha256 ctx"); } -TEST_RESULT should_init_ctx_sha224(TEST_PARAMS, TEST_DATA) +static int init_sha224_ctx() { - UNUSED(test_data); - UNUSED(test_params); t_sha256_ctx ctx; ft_sha224_init(&ctx); - munit_assert_uint(ctx.a, ==, 0xc1059ed8); - munit_assert_uint(ctx.b, ==, 0x367cd507); - munit_assert_uint(ctx.c, ==, 0x3070dd17); - munit_assert_uint(ctx.d, ==, 0xf70e5939); - munit_assert_uint(ctx.e, ==, 0xffc00b31); - munit_assert_uint(ctx.f, ==, 0x68581511); - munit_assert_uint(ctx.g, ==, 0x64f98fa7); - munit_assert_uint(ctx.h, ==, 0xbefa4fa4); - munit_assert_true(ctx.bit_len == 0); + _is(ctx.a == 0xc1059ed8); + _is(ctx.b == 0x367cd507); + _is(ctx.c == 0x3070dd17); + _is(ctx.d == 0xf70e5939); + _is(ctx.e == 0xffc00b31); + _is(ctx.f == 0x68581511); + _is(ctx.g == 0x64f98fa7); + _is(ctx.h == 0xbefa4fa4); + _is(ctx.bit_len == 0); for (int i = 0; i < 64; i++) - munit_assert_uchar(ctx.block[i], ==, 0); + _is(ctx.block[i] == 0); - return MUNIT_OK; + _end("init sha224 ctx"); } -TEST_RESULT decode_string_to_int_sha256(TEST_PARAMS, TEST_DATA) +static int decode_string_to_int_sha256() { - UNUSED(test_params); - UNUSED(test_data); - t_byte1 block[FT_SHA256_BLOCK_SIZE]; t_byte4 words[FT_SHA256_WORDS_COUNT]; @@ -76,16 +68,13 @@ TEST_RESULT decode_string_to_int_sha256(TEST_PARAMS, TEST_DATA) ft_sha256_decode(words, block); - munit_assert_uint(words[0], ==, 0x61626300); + _is(words[0] == 0x61626300); - return MUNIT_OK; + _end("decode string to int sha256"); } -TEST_RESULT encode_len_to_string_sha256(TEST_PARAMS, TEST_DATA) +static int encode_len_to_string_sha256() { - UNUSED(test_params); - UNUSED(test_data); - t_byte8 len; t_byte1 bits[FT_SHA256_MESSAGE_LENGTH_BYTE]; @@ -103,18 +92,15 @@ TEST_RESULT encode_len_to_string_sha256(TEST_PARAMS, TEST_DATA) ft_sha256_encode_len(bits, len); - munit_assert_uchar(bits[0], ==, (t_byte1)((len >> 56) & 0xff)); - munit_assert_uchar(bits[7], ==, (t_byte1)(len & 0xff)); - munit_assert_uchar(bits[6], ==, (t_byte1)((len >> 8) & 0xff)); + _is(bits[0] == (t_byte1)((len >> 56) & 0xff)); + _is(bits[7] == (t_byte1)(len & 0xff)); + _is(bits[6] == (t_byte1)((len >> 8) & 0xff)); - return MUNIT_OK; + _end("encode len to string sha256"); } -TEST_RESULT encode_register_to_string_sha256(TEST_PARAMS, TEST_DATA) +static int encode_register_to_string_sha256() { - UNUSED(test_params); - UNUSED(test_data); - t_byte1 digest_part[4]; t_byte4 reg; @@ -122,44 +108,38 @@ TEST_RESULT encode_register_to_string_sha256(TEST_PARAMS, TEST_DATA) ft_sha256_encode_register(digest_part, reg); - munit_assert_uchar(digest_part[0], ==, 0xba); - munit_assert_uchar(digest_part[1], ==, 0x78); - munit_assert_uchar(digest_part[2], ==, 0x16); - munit_assert_uchar(digest_part[3], ==, 0xbf); + _is(digest_part[0] == 0xba); + _is(digest_part[1] == 0x78); + _is(digest_part[2] == 0x16); + _is(digest_part[3] == 0xbf); - return MUNIT_OK; + _end("encode register to string sha256"); } -TEST_RESULT update_bit_count_sha256(TEST_PARAMS, TEST_DATA) +static int update_bit_count_sha256() { - UNUSED(test_data); - UNUSED(test_params); - t_sha256_ctx ctx; t_byte1 message[] = "abc"; ft_sha256_init(&ctx); ft_sha256_update(&ctx, message, sizeof(message)); - munit_assert_uint(ctx.bit_len, ==, sizeof(message) * 8); + _is(ctx.bit_len == sizeof(message) * 8); - return MUNIT_OK; + _end("update bit count sha256"); } -TEST_RESULT fill_buffer_sha256(TEST_PARAMS, TEST_DATA) +static int fill_buffer_sha256() { - UNUSED(test_data); - UNUSED(test_params); - t_sha256_ctx ctx; t_byte1 message[] = "abc"; ft_sha256_init(&ctx); ft_sha256_update(&ctx, message, sizeof(message)); - munit_assert_string_equal((const char *)message, (const char *)ctx.block); + _is(ft_strcmp((const char *)message, (const char *)ctx.block) == 0); - return MUNIT_OK; + _end("fill buffer sha256"); } static void block_with_right_padding @@ -174,17 +154,15 @@ static void block_with_right_padding padding[message_len] = 0x80; } -TEST_RESULT add_right_padding_sha256(TEST_PARAMS, TEST_DATA) +static int add_right_padding_sha256() { - UNUSED(test_data); - UNUSED(test_params); - t_sha256_ctx ctx; t_byte1 message[] = "abc"; t_byte8 buff_index; t_byte8 padding_len; t_byte1 padding[FT_SHA256_BLOCK_SIZE]; t_byte1 block_with_message_and_pading[FT_SHA256_BLOCK_SIZE]; + int i; ft_sha256_init(&ctx); ft_sha256_update(&ctx, message, sizeof(message)); @@ -195,17 +173,17 @@ TEST_RESULT add_right_padding_sha256(TEST_PARAMS, TEST_DATA) block_with_right_padding(message, sizeof(message), block_with_message_and_pading); - munit_assert_memory_equal(FT_SHA256_BLOCK_SIZE, ctx.block, - block_with_message_and_pading); - return MUNIT_OK; + i = 0; + + _is(ft_memcmp(ctx.block, block_with_message_and_pading, + FT_SHA256_BLOCK_SIZE) == 0); + + _end("add right padding sha256"); } -TEST_RESULT compute_digest_sha256(TEST_PARAMS, TEST_DATA) +static int compute_digest_sha256() { - UNUSED(test_data); - UNUSED(test_params); - t_byte1 message[] = "abc"; t_sha256_ctx ctx; t_byte1 digest[FT_SHA256_DIGEST_LENGTH_BYTE]; @@ -214,24 +192,20 @@ TEST_RESULT compute_digest_sha256(TEST_PARAMS, TEST_DATA) ft_sha256_update(&ctx, message, ft_strlen((const char *)message)); ft_sha256_final(digest, &ctx); + _is(ctx.a == 0xba7816bf); + _is(ctx.b == 0x8f01cfea); + _is(ctx.c == 0x414140de); + _is(ctx.d == 0x5dae2223); + _is(ctx.e == 0xb00361a3); + _is(ctx.f == 0x96177a9c); + _is(ctx.g == 0xb410ff61); + _is(ctx.h == 0xf20015ad); - munit_assert_uint32(ctx.a, ==, 0xba7816bf); - munit_assert_uint32(ctx.b, ==, 0x8f01cfea); - munit_assert_uint32(ctx.c, ==, 0x414140de); - munit_assert_uint32(ctx.d, ==, 0x5dae2223); - munit_assert_uint32(ctx.e, ==, 0xb00361a3); - munit_assert_uint32(ctx.f, ==, 0x96177a9c); - munit_assert_uint32(ctx.g, ==, 0xb410ff61); - munit_assert_uint32(ctx.h, ==, 0xf20015ad); - - return MUNIT_OK; + _end("compute digest sha256"); } -TEST_RESULT compute_digest_sha224(TEST_PARAMS, TEST_DATA) +static int compute_digest_sha224() { - UNUSED(test_data); - UNUSED(test_params); - t_byte1 message[] = "abc"; t_sha256_ctx ctx; t_byte1 digest[FT_SHA256_DIGEST_LENGTH_BYTE]; @@ -240,22 +214,19 @@ TEST_RESULT compute_digest_sha224(TEST_PARAMS, TEST_DATA) ft_sha224_update(&ctx, message, ft_strlen((const char *)message)); ft_sha224_final(digest, &ctx); - munit_assert_uint32(ctx.a, ==, 0x23097d22); - munit_assert_uint32(ctx.b, ==, 0x3405d822); - munit_assert_uint32(ctx.c, ==, 0x8642a477); - munit_assert_uint32(ctx.d, ==, 0xbda255b3); - munit_assert_uint32(ctx.e, ==, 0x2aadbce4); - munit_assert_uint32(ctx.f, ==, 0xbda0b3f7); - munit_assert_uint32(ctx.g, ==, 0xe36c9da7); + _is(ctx.a == 0x23097d22); + _is(ctx.b == 0x3405d822); + _is(ctx.c == 0x8642a477); + _is(ctx.d == 0xbda255b3); + _is(ctx.e == 0x2aadbce4); + _is(ctx.f == 0xbda0b3f7); + _is(ctx.g == 0xe36c9da7); - return MUNIT_OK; + _end("computee digst sha224"); } -TEST_RESULT create_digest_string_sha256(TEST_PARAMS, TEST_DATA) +static int create_digest_string_sha256() { - UNUSED(test_data); - UNUSED(test_params); - t_byte1 message[] = "abc"; t_byte1 message_digest[] = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"; @@ -268,17 +239,14 @@ TEST_RESULT create_digest_string_sha256(TEST_PARAMS, TEST_DATA) ft_sha256_final(digest, &ctx); ft_sha256_digest_string(digest, digest_string); - munit_assert_string_equal((const char *)message_digest, - (const char *)digest_string); + _is(ft_strcmp((const char *)message_digest, + (const char *)digest_string) == 0); - return MUNIT_OK; + _end("create digest string sha256"); } -TEST_RESULT create_digest_string_sha224(TEST_PARAMS, TEST_DATA) +static int create_digest_string_sha224() { - UNUSED(test_data); - UNUSED(test_params); - t_byte1 message[] = "abc"; t_byte1 message_digest[] = "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7"; @@ -291,8 +259,26 @@ TEST_RESULT create_digest_string_sha224(TEST_PARAMS, TEST_DATA) ft_sha224_final(digest, &ctx); ft_sha224_digest_string(digest, digest_string); - munit_assert_string_equal((const char *)message_digest, - (const char *)digest_string); + _is(ft_strcmp((const char *)message_digest, + (const char *)digest_string) == 0); - return MUNIT_OK; + _end("create digest strinf sha224"); } + +int sha_tests() +{ + _should(init_sha256_ctx); + _should(init_sha224_ctx); + _should(decode_string_to_int_sha256); + _should(encode_len_to_string_sha256); + _should(encode_register_to_string_sha256); + _should(update_bit_count_sha256); + _should(fill_buffer_sha256); + _should(add_right_padding_sha256); + _should(compute_digest_sha256); + _should(compute_digest_sha224); + _should(create_digest_string_sha256); + _should(create_digest_string_sha224); + + return 0; +} \ No newline at end of file diff --git a/t/tests.c b/t/tests.c index 062b1f5d..e1707fbe 100644 --- a/t/tests.c +++ b/t/tests.c @@ -10,58 +10,24 @@ /* */ /* ************************************************************************** */ +#include "t.h" #include "tests.h" -#include "tests_macros.h" -MunitTest g_md5_tests[] = { - IT("/init_ctx", should_init_md5_ctx, NULL, NULL, 0, NULL), - IT("/updates_ctx_count", md5_update_change_count, NULL, NULL, 0, NULL), - IT("/decode_string_to_int", md5_decode_string_to_int, NULL, NULL, 0, NULL), - IT("/encode_to_string", md5_encode_bits_to_string, NULL, NULL, 0, NULL), - IT("/encode_register", md5_encode_register, NULL, NULL, 0, NULL), - IT("/creates_digest", md5_create_digest, NULL, NULL, 0, NULL), - IT("/creates_string", md5_create_string, NULL, NULL, 0, NULL), - END_IT -}; - -MunitTest g_sha_tests[] = { - IT("/init_ctx_256", should_init_ctx_sha256, NULL, NULL, 0, NULL), - IT("/init_ctx_224", should_init_ctx_sha224, NULL, NULL, 0, NULL), - IT("/decode_string", decode_string_to_int_sha256, NULL, NULL, 0, NULL), - IT("/encode_len", encode_len_to_string_sha256, NULL, NULL, 0, NULL), - IT("/enc_register", encode_register_to_string_sha256, NULL, NULL, 0, NULL), - IT("/update_bit_count", update_bit_count_sha256, NULL, NULL, 0, NULL), - IT("/fill_buffer", fill_buffer_sha256, NULL, NULL, 0, NULL), - IT("/add_right_padding", add_right_padding_sha256, NULL, NULL, 0, NULL), - IT("/compute_digest_256", compute_digest_sha256, NULL, NULL, 0, NULL), - IT("/compute_digest_224", compute_digest_sha224, NULL, NULL, 0, NULL), - IT("/creates_string_256", create_digest_string_sha256, NULL, NULL, 0, NULL), - IT("/creates_string_224", create_digest_string_sha224, NULL, NULL, 0, NULL), - END_IT -}; - -MunitTest g_base64_tests[] = { - IT("/init_ctx", should_init_base64_ctx, NULL, NULL, 0, NULL), - IT("/transform_block", should_transform_base64_block, NULL, NULL, 0, NULL), - END_IT -}; - -static const MunitSuite g_ft_ssl_suites[] = { - {(char *)"/md5_suite", g_md5_tests, NULL, 1, MUNIT_SUITE_OPTION_NONE}, - {(char *)"/sha_suite", g_sha_tests, NULL, 1, MUNIT_SUITE_OPTION_NONE}, - {(char *)"/base64_suite", g_base64_tests, NULL, 1, MUNIT_SUITE_OPTION_NONE}, - {NULL, NULL, NULL, 0, MUNIT_SUITE_OPTION_NONE} -}; - -static const MunitSuite g_main_suite = { - (char *)"/ft_ssl", - NULL, - (MunitSuite *)g_ft_ssl_suites, - 1, - MUNIT_SUITE_OPTION_NONE -}; - -int main(int argc, char **argv) +int all_tests() { - return (munit_suite_main(&g_main_suite, NULL, argc, argv)); + _verify("md5:", md5_tests); + _verify("sha:", sha_tests); + _verify("base64:", base64_tests); + return 0; +} + +int main() +{ + int result; + + result = all_tests(); + if (result == 0) + printf("PASSED\n"); + + return result != 0; }