Skip to content
Snippets Groups Projects
  • Jonathan Schöbel's avatar
    47407f2d
    look for duplicate tags in Validator · 47407f2d
    Jonathan Schöbel authored
    When a tag is made known to the Validator, which it already knows, the
    old id is returned and nothing is added.
    As this has to be checked by iterating over all known tags, a new helper
    function is written for both SH_Validator_check_tag and
    SH_Validator_register_tag: SH_Validator_get_tag.
    
    Because we want also to test this function, we have to include
    validator.c in the test file and override the static keyword by an empty
    macro. It isn't possible any more to check for correct overflowdetection
    by setting the index to UINT_MAX, because it will be iterated over all
    data, thus raising an SIGSEGV when doing so. This is solved by filling
    garbage unil UINT_MAX is really reached. As there would be an timeout
    and it would fill RAM with around 40 GB of garbage, UINT_MAX is
    overriden prior to inclusion of validator.c .
    47407f2d
    History
    look for duplicate tags in Validator
    Jonathan Schöbel authored
    When a tag is made known to the Validator, which it already knows, the
    old id is returned and nothing is added.
    As this has to be checked by iterating over all known tags, a new helper
    function is written for both SH_Validator_check_tag and
    SH_Validator_register_tag: SH_Validator_get_tag.
    
    Because we want also to test this function, we have to include
    validator.c in the test file and override the static keyword by an empty
    macro. It isn't possible any more to check for correct overflowdetection
    by setting the index to UINT_MAX, because it will be iterated over all
    data, thus raising an SIGSEGV when doing so. This is solved by filling
    garbage unil UINT_MAX is really reached. As there would be an timeout
    and it would fill RAM with around 40 GB of garbage, UINT_MAX is
    overriden prior to inclusion of validator.c .
test_validator.c 6.67 KiB
/*
 * test_validator.c
 *
 * Copyright 2022 Jonathan Schöbel <jonathan@Ubermos-2019>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 *
 *
 */


#include <check.h>
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

/* test static method */
#define static

/* lower UINT_MAX as we try to reach it */
#include <limits.h>
#define UINT_MAX 20

#include "macro.h"
#include "error.h"

/* C file is needed, because we wan't to override UINT_MAX and static */
#include "validator.c"


START_TEST(test_validator)
{
	struct SH_Error error;
	struct SH_Validator * validator;

	validator = SH_Validator_new (NULL);
	ck_assert_int_ne ((long int) validator, (long int) NULL);

	SH_Validator_free (validator, NULL);

	validator = SH_Validator_new (&error);
	ck_assert_int_ne ((long int) validator, (long int) NULL);
	ck_assert_int_eq (error.type, SUCCESS);

	SH_Validator_free (validator, &error);
	ck_assert_int_eq (error.type, SUCCESS);
}
END_TEST

START_TEST(test_validator_tag)
{
	struct SH_Error error;
	struct SH_Validator * validator;
	const char * tag1 = "html";
	const char * tag2 = "head";
	const char * tag3 = "body";
	const char * tag4 = "link";
	const char * tag5 = "main";
	const char * tag6 = "article";
	char * tagN;
	tag_t tag;
	tag_t tag_return;
	bool check;

	validator = SH_Validator_new (NULL);

	/* success without error */
	tag = SH_Validator_register_tag (validator, tag1, NULL);
	ck_assert_int_eq (tag, 1);

	ck_assert_int_eq (validator->tag_n, 1);
	ck_assert_int_eq (validator->last_tag, tag);

	ck_assert_int_eq (validator->tags[0].id, tag);
	ck_assert_str_eq (validator->tags[0].name, tag1);

	tag_return = SH_Validator_get_tag (validator, tag1);
	ck_assert_int_eq (tag_return, tag);

	/* retry without error */
	tag_return = SH_Validator_register_tag (validator, tag1, NULL);
	ck_assert_int_eq (tag_return, tag);

	ck_assert_int_eq (validator->tag_n, 1);
	ck_assert_int_eq (validator->last_tag, tag);

	ck_assert_int_eq (validator->tags[0].id, tag);
	ck_assert_str_eq (validator->tags[0].name, tag1);

	/* fail without error */
	/* make method fail by filling with garbage until
	 * upper boundary is reached */

	/* ensure enough space  inside string*/
	/* log10 +1 = number length */
	/* +3 "tag" */
	/* +1 NULL */
	/* = +5 */
	tagN = calloc (((int) floor (log10 ((double) UINT_MAX))) + 5,
		       sizeof (char));

	/* fill with garbage */
	while (validator->tag_n != UINT_MAX)
	{
		printf ("tag%d\n", validator->tag_n);
		sprintf (tagN, "tag%d", validator->tag_n);
		SH_Validator_register_tag (validator, tagN, NULL);
	}

	tag = SH_Validator_register_tag (validator, tag2, NULL);
	ck_assert_int_eq (tag, TAG_ERR);

	ck_assert_int_eq (validator->tag_n, UINT_MAX);
	ck_assert_int_eq (validator->last_tag, (tag_t) UINT_MAX);

	tag_return = SH_Validator_get_tag (validator, tag2);
	ck_assert_int_eq (tag_return, TAG_ERR);

	/* fail2 without error */
	validator->tag_n = 1;
	validator->last_tag = TAG_MAX;

	tag = SH_Validator_register_tag (validator, tag3, NULL);
	ck_assert_int_eq (tag, TAG_ERR);

	ck_assert_int_eq (validator->tag_n, 1);
	ck_assert_int_eq (validator->last_tag, TAG_MAX);

	tag_return = SH_Validator_get_tag (validator, tag3);
	ck_assert_int_eq (tag_return, TAG_ERR);

	/* success with error */
	validator->last_tag = 1;
	tag = SH_Validator_register_tag (validator, tag4, &error);
	ck_assert_int_eq (tag, 2);
	ck_assert_int_eq (error.type, SUCCESS);

	ck_assert_int_eq (validator->tag_n, 2);
	ck_assert_int_eq (validator->last_tag, tag);

	ck_assert_int_eq (validator->tags[1].id, tag);
	ck_assert_str_eq (validator->tags[1].name, tag4);

	tag_return = SH_Validator_get_tag (validator, tag4);
	ck_assert_int_eq (tag_return, tag);

	/* fail with error */
	/* make method fail by filling with garbage until
	 * upper boundary is reached */

	/* ensure enough space  inside string*/
	/* log10 +1 = number length */
	/* +3 "tag" */
	/* +1 NULL */
	/* = +5 */
	tagN = calloc (((int) floor (log10 ((double) UINT_MAX))) + 5,
		       sizeof (char));

	/* fill with garbage */
	while (validator->tag_n != UINT_MAX)
	{
		printf ("tag%d\n", validator->tag_n);
		sprintf (tagN, "tag%d", validator->tag_n);
		SH_Validator_register_tag (validator, tagN, NULL);
	}

	tag = SH_Validator_register_tag (validator, tag5, &error);
	ck_assert_int_eq (tag, TAG_ERR);
	ck_assert_int_eq (error.type, DOMAIN_ERROR);

	ck_assert_int_eq (validator->tag_n, UINT_MAX);
	ck_assert_int_eq (validator->last_tag, (tag_t) UINT_MAX);

	tag_return = SH_Validator_get_tag (validator, tag5);
	ck_assert_int_eq (tag_return, TAG_ERR);

	/* fail2 with error */
	validator->tag_n = 2;
	validator->last_tag = TAG_MAX;

	tag = SH_Validator_register_tag (validator, tag6, &error);
	ck_assert_int_eq (tag, TAG_ERR);
	ck_assert_int_eq (error.type, DOMAIN_ERROR);

	ck_assert_int_eq (validator->tag_n, 2);
	ck_assert_int_eq (validator->last_tag, TAG_MAX);

	tag_return = SH_Validator_get_tag (validator, tag6);
	ck_assert_int_eq (tag_return, TAG_ERR);


	/* check tag */
	check = SH_Validator_check_tag (validator, tag1);
	ck_assert_int_eq (check, TRUE);

	check = SH_Validator_check_tag (validator, tag2);
	ck_assert_int_eq (check, FALSE);

	check = SH_Validator_check_tag (validator, tag3);
	ck_assert_int_eq (check, FALSE);

	check = SH_Validator_check_tag (validator, tag4);
	ck_assert_int_eq (check, TRUE);

	check = SH_Validator_check_tag (validator, tag5);
	ck_assert_int_eq (check, FALSE);

	check = SH_Validator_check_tag (validator, tag6);
	ck_assert_int_eq (check, FALSE);


	SH_Validator_free (validator, NULL);
}
END_TEST

Suite * validator_suite (void)
{
	Suite *s;
	TCase *tc_core;

	s = suite_create ("Testsuite SeFHT Validator");

	/* Core test case */
	tc_core = tcase_create ("Core");

	tcase_add_test (tc_core, test_validator);
	tcase_add_test (tc_core, test_validator_tag);
	suite_add_tcase (s, tc_core);

	return s;
}

int main (int argc, char **argv)
{
	int number_failed;
	Suite *s;
	SRunner *sr;

	s = validator_suite ();
	sr = srunner_create (s);

	srunner_run_all (sr, CK_NORMAL);
	number_failed = srunner_ntests_failed (sr);
	srunner_free (sr);

	return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}