Skip to content
Snippets Groups Projects
  • Jonathan Schöbel's avatar
    a0c9bb25
    Validator: restructured internal data · a0c9bb25
    Jonathan Schöbel authored
    The Validator saves the tags as an array. Now also another information
    is added, which slots aren't used currently to spare expensive calls to
    realloc. This led to a mere reimplementation of the functions. Tags
    can't be deleted by now, but the adding function supports reusing empty
    slots. Also the reading functions have to determine, whether a slot can
    be read or is empty.
    The tests were adjusted, but are buggy, so they should be rewritten in
    the future.
    
    Additionaly some annotations for splint were added.
    a0c9bb25
    History
    Validator: restructured internal data
    Jonathan Schöbel authored
    The Validator saves the tags as an array. Now also another information
    is added, which slots aren't used currently to spare expensive calls to
    realloc. This led to a mere reimplementation of the functions. Tags
    can't be deleted by now, but the adding function supports reusing empty
    slots. Also the reading functions have to determine, whether a slot can
    be read or is empty.
    The tests were adjusted, but are buggy, so they should be rewritten in
    the future.
    
    Additionaly some annotations for splint were added.
test_validator.c 6.93 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 SIZE_MAX as we try to reach it */
#include <limits.h>
#define SIZE_MAX 10 * sizeof (struct tag_info)

#include "macro.h"
#include "status.h"

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


START_TEST(test_validator)
{
	struct SH_Status status;
	struct SH_Validator * validator;

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

	SH_Validator_free (validator);

	status.status = UNDEFINED;
	validator = SH_Validator_new (&status);
	ck_assert_int_ne ((long int) validator, (long int) NULL);
	ck_assert_int_eq (status.status, SUCCESS);

	SH_Validator_free (validator);
}
END_TEST

START_TEST(test_validator_tag)
{
	struct SH_Status status;
	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 tag;
	Tag 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[1].data.id, tag);
	ck_assert_str_eq (validator->tags[1].data.name, tag1);

	tag_return = get_tag_id_by_name (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[1].data.id, tag);
	ck_assert_str_eq (validator->tags[1].data.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) SIZE_MAX))) + 5,
		       sizeof (char));

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

	free (tagN);

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

	ck_assert_int_eq (validator->tag_n, 9);

	tag_return = get_tag_id_by_name (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 = get_tag_id_by_name (validator, tag3);
	ck_assert_int_eq (tag_return, TAG_ERR);

	/* also free garbage created for overflow test */
	validator->tag_n = 9;

	/* 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);

	SH_Validator_free (validator);


	validator = SH_Validator_new (NULL);

	/* success with error */
	status.status = UNDEFINED;
	tag = SH_Validator_register_tag (validator, tag4, &status);
	ck_assert_int_eq (tag, 1);
	ck_assert_int_eq (status.status, SUCCESS);

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

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

	tag_return = get_tag_id_by_name (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) SIZE_MAX))) + 5,
		       sizeof (char));

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

	free (tagN);

	status.status = UNDEFINED;
	tag = SH_Validator_register_tag (validator, tag5, &status);
	ck_assert_int_eq (tag, TAG_ERR);
	ck_assert_int_eq (status.status, E_DOMAIN);

	ck_assert_int_eq (validator->tag_n, 9);

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

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

	status.status = UNDEFINED;
	tag = SH_Validator_register_tag (validator, tag6, &status);
	ck_assert_int_eq (tag, TAG_ERR);
	ck_assert_int_eq (status.status, E_DOMAIN);

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

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


	/* check tag */
	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);

	/* also free garbage created for overflow test */
	validator->tag_n = 9;

	SH_Validator_free (validator);
}
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;
}