Enable gating for ding-libs by adding tests
Resolves: RHELMISC-3929
This commit is contained in:
parent
1319809255
commit
288517db7c
37
tests/sanity/Makefile
Normal file
37
tests/sanity/Makefile
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
tests: collection_ut.c collection_queue_ut.c collection_stack_ut.c \
|
||||||
|
dhash_ut_check.c ini_augment_ut_check.c ini_comment_ut.c \
|
||||||
|
ini_configmod_ut_check.c ini_parse_ut_check.c \
|
||||||
|
ini_validators_ut_check.c ini_valueobj_ut.c path_utils_ut.c \
|
||||||
|
ref_array_ut.c simplebuffer_ut.c
|
||||||
|
gcc collection_ut.c -lcollection -o collection_ut
|
||||||
|
gcc collection_queue_ut.c -lcollection -o collection_queue_ut
|
||||||
|
gcc collection_stack_ut.c -lcollection -o collection_stack_ut
|
||||||
|
gcc dhash_ut_check.c -ldhash -lcheck -o dhash_ut_check
|
||||||
|
gcc ini_augment_ut_check.c -lini_config -lcollection -lcheck -lref_array \
|
||||||
|
-o ini_augment_ut_check
|
||||||
|
gcc ini_comment_ut.c -lini_config -lcheck -o ini_comment_ut
|
||||||
|
gcc ini_configmod_ut_check.c -lbasicobjects -lcheck -lini_config \
|
||||||
|
-o ini_configmod_ut_check
|
||||||
|
gcc ini_parse_ut_check.c -lcheck -lini_config -o ini_parse_ut_check
|
||||||
|
gcc ini_validators_ut_check.c -lini_config -lcheck \
|
||||||
|
-o ini_validators_ut_check
|
||||||
|
gcc ini_valueobj_ut.c -lini_config -lbasicobjects -o ini_valueobj_ut
|
||||||
|
gcc path_utils_ut.c -lpath_utils -lcheck -o path_utils_ut
|
||||||
|
gcc ref_array_ut.c -lref_array -o ref_array_ut
|
||||||
|
gcc simplebuffer_ut.c -lbasicobjects -o simplebuffer_ut
|
||||||
|
|
||||||
|
run: tests
|
||||||
|
./collection_ut || exit 1
|
||||||
|
./collection_queue_ut || exit 2
|
||||||
|
./collection_stack_ut || exit 3
|
||||||
|
./dhash_ut_check || exit 4
|
||||||
|
./ini_augment_ut_check || exit 5
|
||||||
|
./ini_comment_ut || exit 6
|
||||||
|
./ini_configmod_ut_check || exit 7
|
||||||
|
./ini_parse_ut_check || exit 8
|
||||||
|
./ini_validators_ut_check || exit 9
|
||||||
|
./ini_valueobj_ut || exit 10
|
||||||
|
./path_utils_ut || exit 11
|
||||||
|
./ref_array_ut || exit 12
|
||||||
|
./simplebuffer_ut || exit 13
|
||||||
|
echo ALL TESTS PASSED
|
212
tests/sanity/collection_queue_ut.c
Normal file
212
tests/sanity/collection_queue_ut.c
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
/*
|
||||||
|
QUEUE INTERFACE
|
||||||
|
|
||||||
|
Queue unit test.
|
||||||
|
|
||||||
|
Copyright (C) Dmitri Pal <dpal@redhat.com> 2009
|
||||||
|
|
||||||
|
Collection Library is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Collection Library 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 Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with Collection Library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#define TRACE_HOME
|
||||||
|
#include "trace.h"
|
||||||
|
#include "collection_queue.h"
|
||||||
|
#include "collection_tools.h"
|
||||||
|
|
||||||
|
typedef int (*test_fn)(void);
|
||||||
|
|
||||||
|
int verbose = 0;
|
||||||
|
|
||||||
|
#define COLOUT(foo) \
|
||||||
|
do { \
|
||||||
|
if (verbose) foo; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
static int queue_test(void)
|
||||||
|
{
|
||||||
|
struct collection_item *queue = NULL;
|
||||||
|
char binary_dump[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||||
|
struct collection_item *item = NULL;
|
||||||
|
int i;
|
||||||
|
unsigned count;
|
||||||
|
int error = EOK;
|
||||||
|
|
||||||
|
TRACE_FLOW_STRING("queue_test","Entry.");
|
||||||
|
|
||||||
|
COLOUT(printf("\n\nQUEUE TEST!!!.\n\n\n"));
|
||||||
|
|
||||||
|
if((error = col_create_queue(&queue)) ||
|
||||||
|
(error = col_enqueue_str_property(queue, "item1","value 1" ,0)) ||
|
||||||
|
(error = col_enqueue_int_property(queue, "item2", -1)) ||
|
||||||
|
(error = col_enqueue_unsigned_property(queue, "item3", 1)) ||
|
||||||
|
(error = col_enqueue_long_property(queue, "item4", 100)) ||
|
||||||
|
(error = col_enqueue_ulong_property(queue, "item5", 1000)) ||
|
||||||
|
(error = col_enqueue_double_property(queue, "item6", 1.1)) ||
|
||||||
|
(error = col_enqueue_bool_property(queue, "item7", 1)) ||
|
||||||
|
(error = col_enqueue_binary_property(queue, "item8", binary_dump, sizeof(binary_dump)))) {
|
||||||
|
printf("Failed to enqueue property. Error %d\n", error);
|
||||||
|
col_destroy_collection(queue);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
COLOUT(col_debug_collection(queue,COL_TRAVERSE_DEFAULT));
|
||||||
|
|
||||||
|
error = col_get_collection_count(queue, &count);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to get count. Error %d\n", error);
|
||||||
|
col_destroy_collection(queue);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
count--;
|
||||||
|
|
||||||
|
COLOUT(printf("Rotate the queue.\n"));
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if ((error = col_dequeue_item(queue, &item)) ||
|
||||||
|
(error = col_enqueue_item(queue, item))) {
|
||||||
|
printf("Failed to dequeue or enqueue items. Error %d\n", error);
|
||||||
|
col_destroy_collection(queue);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
COLOUT(col_debug_collection(queue,COL_TRAVERSE_DEFAULT));
|
||||||
|
}
|
||||||
|
|
||||||
|
col_destroy_collection(queue);
|
||||||
|
TRACE_FLOW_NUMBER("queue_test. Returning", error);
|
||||||
|
|
||||||
|
COLOUT(printf("\n\nEND OF QUEUE TEST!!!.\n\n\n"));
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int empty_test(void)
|
||||||
|
{
|
||||||
|
struct collection_item *queue = NULL;
|
||||||
|
struct collection_item *item = NULL;
|
||||||
|
int i;
|
||||||
|
unsigned count;
|
||||||
|
int error = EOK;
|
||||||
|
|
||||||
|
TRACE_FLOW_STRING("empty_test","Entry.");
|
||||||
|
|
||||||
|
COLOUT(printf("\n\nEMPTY QUEUE TEST!!!.\n\n\n"));
|
||||||
|
|
||||||
|
if((error = col_create_queue(&queue)) ||
|
||||||
|
(error = col_enqueue_str_property(queue, "item1","value 1" ,0)) ||
|
||||||
|
(error = col_enqueue_int_property(queue, "item2", -1)) ||
|
||||||
|
(error = col_enqueue_unsigned_property(queue, "item3", 1))) {
|
||||||
|
printf("Failed to enqueue property. Error %d\n", error);
|
||||||
|
col_destroy_collection(queue);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
COLOUT(col_debug_collection(queue,COL_TRAVERSE_DEFAULT));
|
||||||
|
|
||||||
|
error = col_get_collection_count(queue, &count);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to get count. Error %d\n", error);
|
||||||
|
col_destroy_collection(queue);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
count--;
|
||||||
|
|
||||||
|
COLOUT(printf("Empty the queue.\n"));
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if ((error = col_dequeue_item(queue, &item))) {
|
||||||
|
printf("Failed to dequeue or enqueue items. Error %d\n", error);
|
||||||
|
col_destroy_collection(queue);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
col_delete_item(item);
|
||||||
|
|
||||||
|
COLOUT(col_debug_collection(queue,COL_TRAVERSE_DEFAULT));
|
||||||
|
}
|
||||||
|
|
||||||
|
COLOUT(printf("Add elements again.\n"));
|
||||||
|
if((error = col_enqueue_str_property(queue, "item1","value 1" ,0)) ||
|
||||||
|
(error = col_enqueue_int_property(queue, "item2", -1)) ||
|
||||||
|
(error = col_enqueue_unsigned_property(queue, "item3", 1))) {
|
||||||
|
printf("Failed to enqueue property. Error %d\n", error);
|
||||||
|
col_destroy_collection(queue);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
COLOUT(col_debug_collection(queue,COL_TRAVERSE_DEFAULT));
|
||||||
|
|
||||||
|
error = col_get_collection_count(queue, &count);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to get count. Error %d\n", error);
|
||||||
|
col_destroy_collection(queue);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
count--;
|
||||||
|
|
||||||
|
COLOUT(printf("Empty the queue again.\n"));
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if ((error = col_dequeue_item(queue, &item))) {
|
||||||
|
printf("Failed to dequeue or enqueue items. Error %d\n", error);
|
||||||
|
col_destroy_collection(queue);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
col_delete_item(item);
|
||||||
|
|
||||||
|
COLOUT(col_debug_collection(queue,COL_TRAVERSE_DEFAULT));
|
||||||
|
}
|
||||||
|
|
||||||
|
col_destroy_collection(queue);
|
||||||
|
|
||||||
|
TRACE_FLOW_NUMBER("empty_test. Returning", error);
|
||||||
|
|
||||||
|
COLOUT(printf("\n\nEND OF QUEUE TEST!!!.\n\n\n"));
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Main function of the unit test */
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int error = 0;
|
||||||
|
test_fn tests[] = { queue_test,
|
||||||
|
empty_test,
|
||||||
|
NULL };
|
||||||
|
test_fn t;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = 1;
|
||||||
|
|
||||||
|
printf("Start\n");
|
||||||
|
|
||||||
|
while ((t = tests[i++])) {
|
||||||
|
error = t();
|
||||||
|
if (error) {
|
||||||
|
printf("Failed!\n");
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Success!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
129
tests/sanity/collection_stack_ut.c
Normal file
129
tests/sanity/collection_stack_ut.c
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
STACK INTERFACE
|
||||||
|
|
||||||
|
Stack unit test.
|
||||||
|
|
||||||
|
Copyright (C) Dmitri Pal <dpal@redhat.com> 2009
|
||||||
|
|
||||||
|
Collection Library is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Collection Library 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 Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with Collection Library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#define TRACE_HOME
|
||||||
|
#include "trace.h"
|
||||||
|
#include "collection_stack.h"
|
||||||
|
#include "collection_tools.h"
|
||||||
|
|
||||||
|
typedef int (*test_fn)(void);
|
||||||
|
|
||||||
|
int verbose = 0;
|
||||||
|
|
||||||
|
#define COLOUT(foo) \
|
||||||
|
do { \
|
||||||
|
if (verbose) foo; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int stack_test(void)
|
||||||
|
{
|
||||||
|
struct collection_item *stack = NULL;
|
||||||
|
char binary_dump[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||||
|
struct collection_item *item1 = NULL;
|
||||||
|
struct collection_item *item2 = NULL;
|
||||||
|
|
||||||
|
int error = EOK;
|
||||||
|
|
||||||
|
TRACE_FLOW_STRING("stack_test", "Entry.");
|
||||||
|
|
||||||
|
COLOUT(printf("\n\nSTACK TEST!!!.\n\n\n"));
|
||||||
|
|
||||||
|
if ((error = col_create_stack(&stack)) ||
|
||||||
|
(error = col_push_str_property(stack, "item1", "value 1", 0)) ||
|
||||||
|
(error = col_push_int_property(stack, "item2", -1)) ||
|
||||||
|
(error = col_push_unsigned_property(stack, "item3", 1)) ||
|
||||||
|
(error = col_push_long_property(stack, "item4", 100)) ||
|
||||||
|
(error = col_push_ulong_property(stack, "item5", 1000)) ||
|
||||||
|
(error = col_push_double_property(stack, "item6", 1.1)) ||
|
||||||
|
(error = col_push_bool_property(stack, "item7", 1)) ||
|
||||||
|
(error = col_push_binary_property(stack, "item8", binary_dump, sizeof(binary_dump)))) {
|
||||||
|
printf("Failed to push property. Error %d\n", error);
|
||||||
|
col_destroy_collection(stack);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
COLOUT(col_debug_collection(stack, COL_TRAVERSE_DEFAULT));
|
||||||
|
|
||||||
|
COLOUT(printf("Swapping last two items by popping and pushing them back.\n"));
|
||||||
|
|
||||||
|
if ((error = col_pop_item(stack, &item1)) ||
|
||||||
|
(error = col_pop_item(stack, &item2))) {
|
||||||
|
printf("Failed to pop items. Error %d\n", error);
|
||||||
|
col_destroy_collection(stack);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
COLOUT(printf("\nPopped two last items.\n"));
|
||||||
|
COLOUT(col_debug_collection(stack, COL_TRAVERSE_DEFAULT));
|
||||||
|
|
||||||
|
COLOUT(printf("\nLast item.\n"));
|
||||||
|
COLOUT(col_debug_item(item1));
|
||||||
|
|
||||||
|
COLOUT(printf("\nPrevious item.\n"));
|
||||||
|
COLOUT(col_debug_item(item2));
|
||||||
|
|
||||||
|
if ((error = col_push_item(stack, item1)) ||
|
||||||
|
(error = col_push_item(stack, item2))) {
|
||||||
|
printf("Failed to pop or push items. Error %d\n", error);
|
||||||
|
col_destroy_collection(stack);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
COLOUT(printf("\n\nPushed two items again in reverse order.\n\n"));
|
||||||
|
|
||||||
|
COLOUT(col_debug_collection(stack, COL_TRAVERSE_DEFAULT));
|
||||||
|
col_destroy_collection(stack);
|
||||||
|
TRACE_FLOW_NUMBER("stack_test. Returning", error);
|
||||||
|
|
||||||
|
COLOUT(printf("\n\nEND OF STACK TEST!!!.\n\n"));
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Main function of the unit test */
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int error = 0;
|
||||||
|
test_fn tests[] = { stack_test,
|
||||||
|
NULL };
|
||||||
|
test_fn t;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = 1;
|
||||||
|
|
||||||
|
printf("Start\n");
|
||||||
|
|
||||||
|
while ((t = tests[i++])) {
|
||||||
|
error = t();
|
||||||
|
if (error) {
|
||||||
|
printf("Failed!\n");
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Success!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
2259
tests/sanity/collection_ut.c
Normal file
2259
tests/sanity/collection_ut.c
Normal file
File diff suppressed because it is too large
Load Diff
224
tests/sanity/dhash_ut_check.c
Normal file
224
tests/sanity/dhash_ut_check.c
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
/*
|
||||||
|
Authors:
|
||||||
|
Michal Zidek <mzidek@redhat.com>
|
||||||
|
|
||||||
|
Copyright (C) 2016 Red Hat
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <check.h>
|
||||||
|
|
||||||
|
/* #define TRACE_LEVEL 7 */
|
||||||
|
#define TRACE_HOME
|
||||||
|
#include "dhash.h"
|
||||||
|
|
||||||
|
#define HTABLE_SIZE 128
|
||||||
|
|
||||||
|
int verbose = 0;
|
||||||
|
|
||||||
|
/* There must be no warnings generated during this test
|
||||||
|
* without having to cast the key value. */
|
||||||
|
START_TEST(test_key_const_string)
|
||||||
|
{
|
||||||
|
hash_table_t *htable;
|
||||||
|
int ret;
|
||||||
|
hash_value_t ret_val;
|
||||||
|
hash_value_t enter_val1;
|
||||||
|
hash_value_t enter_val2;
|
||||||
|
hash_key_t key;
|
||||||
|
|
||||||
|
enter_val1.type = HASH_VALUE_INT;
|
||||||
|
enter_val1.i = 1;
|
||||||
|
enter_val2.type = HASH_VALUE_INT;
|
||||||
|
enter_val2.i = 2;
|
||||||
|
key.type = HASH_KEY_CONST_STRING;
|
||||||
|
key.c_str = "constant";
|
||||||
|
|
||||||
|
ret = hash_create(HTABLE_SIZE, &htable, NULL, NULL);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
|
||||||
|
/* The table is empty, lookup should return error */
|
||||||
|
ret = hash_lookup(htable, &key, &ret_val);
|
||||||
|
fail_unless(ret == HASH_ERROR_KEY_NOT_FOUND);
|
||||||
|
|
||||||
|
/* Deleting with non-existing key should return error */
|
||||||
|
ret = hash_delete(htable, &key);
|
||||||
|
fail_unless(ret == HASH_ERROR_KEY_NOT_FOUND);
|
||||||
|
|
||||||
|
ret = hash_enter(htable, &key, &enter_val1);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
|
||||||
|
hash_lookup(htable, &key, &ret_val);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
fail_unless(ret_val.i == 1);
|
||||||
|
|
||||||
|
/* Overwrite the entry */
|
||||||
|
ret = hash_enter(htable, &key, &enter_val2);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
|
||||||
|
hash_lookup(htable, &key, &ret_val);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
fail_unless(ret_val.i == 2);
|
||||||
|
|
||||||
|
ret = hash_delete(htable, &key);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
|
||||||
|
/* Delete again with the same key */
|
||||||
|
ret = hash_delete(htable, &key);
|
||||||
|
fail_unless(ret == HASH_ERROR_KEY_NOT_FOUND);
|
||||||
|
|
||||||
|
ret = hash_destroy(htable);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_key_string)
|
||||||
|
{
|
||||||
|
hash_table_t *htable;
|
||||||
|
int ret;
|
||||||
|
hash_value_t ret_val;
|
||||||
|
hash_value_t enter_val1;
|
||||||
|
hash_value_t enter_val2;
|
||||||
|
hash_key_t key;
|
||||||
|
char str[] = "non_constant";
|
||||||
|
|
||||||
|
enter_val1.type = HASH_VALUE_INT;
|
||||||
|
enter_val1.i = 1;
|
||||||
|
enter_val2.type = HASH_VALUE_INT;
|
||||||
|
enter_val2.i = 2;
|
||||||
|
key.type = HASH_KEY_STRING;
|
||||||
|
key.str = str;
|
||||||
|
|
||||||
|
ret = hash_create(HTABLE_SIZE, &htable, NULL, NULL);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
|
||||||
|
/* The table is empty, lookup should return error */
|
||||||
|
ret = hash_lookup(htable, &key, &ret_val);
|
||||||
|
fail_unless(ret == HASH_ERROR_KEY_NOT_FOUND);
|
||||||
|
|
||||||
|
/* Deleting with non-existing key should return error */
|
||||||
|
ret = hash_delete(htable, &key);
|
||||||
|
fail_unless(ret == HASH_ERROR_KEY_NOT_FOUND);
|
||||||
|
|
||||||
|
ret = hash_enter(htable, &key, &enter_val1);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
|
||||||
|
hash_lookup(htable, &key, &ret_val);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
fail_unless(ret_val.i == 1);
|
||||||
|
|
||||||
|
/* Overwrite the entry */
|
||||||
|
ret = hash_enter(htable, &key, &enter_val2);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
|
||||||
|
hash_lookup(htable, &key, &ret_val);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
fail_unless(ret_val.i == 2);
|
||||||
|
|
||||||
|
ret = hash_delete(htable, &key);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
|
||||||
|
/* Delete again with the same key */
|
||||||
|
ret = hash_delete(htable, &key);
|
||||||
|
fail_unless(ret == HASH_ERROR_KEY_NOT_FOUND);
|
||||||
|
|
||||||
|
|
||||||
|
ret = hash_destroy(htable);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_key_ulong)
|
||||||
|
{
|
||||||
|
hash_table_t *htable;
|
||||||
|
int ret;
|
||||||
|
hash_value_t ret_val;
|
||||||
|
hash_value_t enter_val1;
|
||||||
|
hash_value_t enter_val2;
|
||||||
|
hash_key_t key;
|
||||||
|
|
||||||
|
enter_val1.type = HASH_VALUE_INT;
|
||||||
|
enter_val1.i = 1;
|
||||||
|
enter_val2.type = HASH_VALUE_INT;
|
||||||
|
enter_val2.i = 2;
|
||||||
|
key.type = HASH_KEY_ULONG;
|
||||||
|
key.ul = 68ul;
|
||||||
|
|
||||||
|
ret = hash_create(HTABLE_SIZE, &htable, NULL, NULL);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
|
||||||
|
/* The table is empty, lookup should return error */
|
||||||
|
ret = hash_lookup(htable, &key, &ret_val);
|
||||||
|
fail_unless(ret == HASH_ERROR_KEY_NOT_FOUND);
|
||||||
|
|
||||||
|
/* Deleting with non-existing key should return error */
|
||||||
|
ret = hash_delete(htable, &key);
|
||||||
|
fail_unless(ret == HASH_ERROR_KEY_NOT_FOUND);
|
||||||
|
|
||||||
|
ret = hash_enter(htable, &key, &enter_val1);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
|
||||||
|
hash_lookup(htable, &key, &ret_val);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
fail_unless(ret_val.i == 1);
|
||||||
|
|
||||||
|
/* Overwrite the entry */
|
||||||
|
ret = hash_enter(htable, &key, &enter_val2);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
|
||||||
|
hash_lookup(htable, &key, &ret_val);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
fail_unless(ret_val.i == 2);
|
||||||
|
|
||||||
|
ret = hash_delete(htable, &key);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
|
||||||
|
/* Delete again with the same key */
|
||||||
|
ret = hash_delete(htable, &key);
|
||||||
|
fail_unless(ret == HASH_ERROR_KEY_NOT_FOUND);
|
||||||
|
|
||||||
|
ret = hash_destroy(htable);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
static Suite *dhash_suite(void)
|
||||||
|
{
|
||||||
|
Suite *s = suite_create("");
|
||||||
|
|
||||||
|
TCase *tc_basic = tcase_create("dhash API tests");
|
||||||
|
tcase_add_test(tc_basic, test_key_const_string);
|
||||||
|
tcase_add_test(tc_basic, test_key_string);
|
||||||
|
tcase_add_test(tc_basic, test_key_ulong);
|
||||||
|
suite_add_tcase(s, tc_basic);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
int number_failed;
|
||||||
|
|
||||||
|
Suite *s = dhash_suite();
|
||||||
|
SRunner *sr = srunner_create(s);
|
||||||
|
/* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */
|
||||||
|
srunner_run_all(sr, CK_ENV);
|
||||||
|
number_failed = srunner_ntests_failed(sr);
|
||||||
|
srunner_free(sr);
|
||||||
|
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
|
}
|
3
tests/sanity/ding-libs-tests.sh
Executable file
3
tests/sanity/ding-libs-tests.sh
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
make run
|
341
tests/sanity/ini_augment_ut_check.c
Normal file
341
tests/sanity/ini_augment_ut_check.c
Normal file
@ -0,0 +1,341 @@
|
|||||||
|
/*
|
||||||
|
INI LIBRARY
|
||||||
|
|
||||||
|
Check based unit test for ini_config_augment.
|
||||||
|
|
||||||
|
Copyright (C) Alexander Scheel <ascheel@redhat.com> 2017
|
||||||
|
|
||||||
|
INI Library is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
INI Library 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 Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with INI Library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <check.h>
|
||||||
|
|
||||||
|
/* #define TRACE_LEVEL 7 */
|
||||||
|
#define TRACE_HOME
|
||||||
|
#include "trace.h"
|
||||||
|
#include "ini_configobj.h"
|
||||||
|
//#include "ini_config_priv.h"
|
||||||
|
|
||||||
|
static int write_to_file(char *path, char *text)
|
||||||
|
{
|
||||||
|
FILE *f = fopen(path, "w");
|
||||||
|
int bytes = 0;
|
||||||
|
if (f == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
bytes = fprintf(f, "%s", text);
|
||||||
|
if (bytes != strlen(text)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int exists_array(const char *needle, char **haystack, uint32_t count)
|
||||||
|
{
|
||||||
|
uint32_t i = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
fprintf(stderr, "%s == %s?\n", needle, haystack[i]);
|
||||||
|
if (strcmp(needle, haystack[i]) == 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
START_TEST(test_ini_augment_merge_sections)
|
||||||
|
{
|
||||||
|
char base_path[PATH_MAX];
|
||||||
|
char augment_path[PATH_MAX];
|
||||||
|
|
||||||
|
char config_base[] =
|
||||||
|
"[section]\n"
|
||||||
|
"key1 = first\n"
|
||||||
|
"key2 = exists\n";
|
||||||
|
|
||||||
|
char config_augment[] =
|
||||||
|
"[section]\n"
|
||||||
|
"key1 = augment\n"
|
||||||
|
"key3 = exists\n";
|
||||||
|
|
||||||
|
const char *builddir;
|
||||||
|
|
||||||
|
uint32_t flags[3] = { INI_MS_DETECT , INI_MS_DETECT | INI_MS_PRESERVE,
|
||||||
|
INI_MS_DETECT | INI_MS_OVERWRITE };
|
||||||
|
|
||||||
|
int expected_attributes_counts[3] = { 3, 2, 2 };
|
||||||
|
const char *test_sections[3] = { "section", "section", "section" };
|
||||||
|
const char *test_attributes[3] = { "key3", "key1", "key1" };
|
||||||
|
const char *test_attribute_values[3] = {"exists", "first", "augment" };
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
int iter;
|
||||||
|
|
||||||
|
builddir = getenv("builddir");
|
||||||
|
if (builddir == NULL) {
|
||||||
|
builddir = ".";
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(base_path, PATH_MAX, "%s/tmp_augment_base.conf", builddir);
|
||||||
|
snprintf(augment_path, PATH_MAX, "%s/tmp_augment_augment.conf", builddir);
|
||||||
|
|
||||||
|
ret = write_to_file(base_path, config_base);
|
||||||
|
fail_unless(ret == 0, "Failed to write %s: ret %d.\n", base_path, ret);
|
||||||
|
|
||||||
|
write_to_file(augment_path, config_augment);
|
||||||
|
fail_unless(ret == 0, "Failed to write %s: ret %d.\n", augment_path, ret);
|
||||||
|
|
||||||
|
for (iter = 0; iter < 3; iter++) {
|
||||||
|
uint32_t merge_flags = flags[iter];
|
||||||
|
int expected_attributes_count = expected_attributes_counts[iter];
|
||||||
|
const char *test_section = test_sections[iter];
|
||||||
|
const char *test_attribute = test_attributes[iter];
|
||||||
|
const char *test_attribute_value = test_attribute_values[iter];
|
||||||
|
struct ini_cfgobj *in_cfg;
|
||||||
|
struct ini_cfgobj *result_cfg;
|
||||||
|
struct ini_cfgfile *file_ctx;
|
||||||
|
struct ref_array *error_list;
|
||||||
|
struct ref_array *success_list;
|
||||||
|
|
||||||
|
char **sections;
|
||||||
|
int sections_count;
|
||||||
|
|
||||||
|
char **attributes;
|
||||||
|
int attributes_count;
|
||||||
|
|
||||||
|
struct value_obj *val;
|
||||||
|
char *val_str;
|
||||||
|
|
||||||
|
/* Match only augment.conf */
|
||||||
|
const char *m_patterns[] = { "^tmp_augment_augment.conf$", NULL };
|
||||||
|
|
||||||
|
/* Match all sections */
|
||||||
|
const char *m_sections[] = { ".*", NULL };
|
||||||
|
|
||||||
|
/* Create config collection */
|
||||||
|
ret = ini_config_create(&in_cfg);
|
||||||
|
fail_unless(ret == EOK, "Failed to create collection. Error %d\n",
|
||||||
|
ret);
|
||||||
|
|
||||||
|
/* Open base.conf */
|
||||||
|
ret = ini_config_file_open(base_path, 0, &file_ctx);
|
||||||
|
fail_unless(ret == EOK, "Failed to open file. Error %d\n", ret);
|
||||||
|
|
||||||
|
/* Seed in_cfg with base.conf */
|
||||||
|
ret = ini_config_parse(file_ctx, 1, 0, 0, in_cfg);
|
||||||
|
fail_unless(ret == EOK, "Failed to parse file context. Error %d\n",
|
||||||
|
ret);
|
||||||
|
|
||||||
|
/* Update base.conf with augment.conf */
|
||||||
|
ret = ini_config_augment(in_cfg,
|
||||||
|
builddir,
|
||||||
|
m_patterns,
|
||||||
|
m_sections,
|
||||||
|
NULL,
|
||||||
|
INI_STOP_ON_NONE,
|
||||||
|
0,
|
||||||
|
INI_PARSE_NOSPACE|INI_PARSE_NOTAB,
|
||||||
|
merge_flags,
|
||||||
|
&result_cfg,
|
||||||
|
&error_list,
|
||||||
|
&success_list);
|
||||||
|
/* We always expect EEXIST due to DETECT being set. */
|
||||||
|
fail_unless(ret == EEXIST,
|
||||||
|
"Failed to augment context. Error %d\n", ret);
|
||||||
|
|
||||||
|
if (result_cfg) {
|
||||||
|
ini_config_destroy(in_cfg);
|
||||||
|
in_cfg = result_cfg;
|
||||||
|
result_cfg = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get a list of sections from the resulting cfg. */
|
||||||
|
sections = ini_get_section_list(in_cfg, §ions_count, &ret);
|
||||||
|
fail_unless(ret == EOK, "Failed to get section list. Error %d\n", ret);
|
||||||
|
|
||||||
|
/* Validate that the tested section exists. */
|
||||||
|
ret = exists_array(test_section, sections, sections_count);
|
||||||
|
fail_if(ret == 0, "Failed to find expected section.\n");
|
||||||
|
|
||||||
|
/* Get a list of attributes from the resulting cfg. */
|
||||||
|
attributes = ini_get_attribute_list(in_cfg, test_section,
|
||||||
|
&attributes_count,
|
||||||
|
&ret);
|
||||||
|
fail_unless(ret == EOK, "Failed to get attribute list. Error %d\n",
|
||||||
|
ret);
|
||||||
|
|
||||||
|
/* Validate that the expected number of attributes exist. This
|
||||||
|
* distinguishes MERGE from PRESERVE/OVERWRITE. */
|
||||||
|
fail_unless(expected_attributes_count == attributes_count,
|
||||||
|
"Expected %d attributes, but received %d.\n",
|
||||||
|
expected_attributes_count, attributes_count);
|
||||||
|
|
||||||
|
/* Validate that the test attribute exists. This distinguishes
|
||||||
|
* PRESERVE from OVERWRITE. */
|
||||||
|
ret = exists_array(test_attribute, attributes, attributes_count);
|
||||||
|
fail_if(ret == 0, "Failed to find expected attribute.\n");
|
||||||
|
|
||||||
|
ret = ini_get_config_valueobj(test_section, test_attribute, in_cfg,
|
||||||
|
0, &val);
|
||||||
|
fail_unless(ret == EOK, "Failed to load value object. Error %d\n",
|
||||||
|
ret);
|
||||||
|
|
||||||
|
val_str = ini_get_string_config_value(val, &ret);
|
||||||
|
fail_unless(ret == EOK, "Failed to get config value. Error %d\n", ret);
|
||||||
|
|
||||||
|
/* Validate the value of the test attribute. */
|
||||||
|
ret = strcmp(val_str, test_attribute_value);
|
||||||
|
|
||||||
|
fail_unless(ret == 0, "Attribute %s didn't have expected value of "
|
||||||
|
"(%s): saw %s\n", test_attribute, test_attribute_value,
|
||||||
|
val_str);
|
||||||
|
|
||||||
|
/* Cleanup */
|
||||||
|
free(val_str);
|
||||||
|
ini_free_attribute_list(attributes);
|
||||||
|
ini_free_section_list(sections);
|
||||||
|
ref_array_destroy(error_list);
|
||||||
|
ini_config_file_destroy(file_ctx);
|
||||||
|
ref_array_destroy(success_list);
|
||||||
|
ini_config_destroy(in_cfg);
|
||||||
|
ini_config_destroy(result_cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
remove(base_path);
|
||||||
|
remove(augment_path);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_ini_augment_empty_dir)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct ini_cfgobj *ini_cfg;
|
||||||
|
struct ini_cfgfile *file_ctx;
|
||||||
|
struct value_obj *vo;
|
||||||
|
const char *patterns[] = { ".*", NULL };
|
||||||
|
const char *sections[] = { ".*", NULL };
|
||||||
|
char **section_list;
|
||||||
|
char **attrs_list;
|
||||||
|
struct ini_cfgobj *result_cfg = NULL;
|
||||||
|
int size;
|
||||||
|
char empty_dir_path[PATH_MAX] = {0};
|
||||||
|
const char *builddir;
|
||||||
|
int32_t val;
|
||||||
|
char base_cfg[] =
|
||||||
|
"[section_one]\n"
|
||||||
|
"one = 1\n";
|
||||||
|
|
||||||
|
builddir = getenv("builddir");
|
||||||
|
if (builddir == NULL) {
|
||||||
|
builddir = ".";
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = snprintf(empty_dir_path, PATH_MAX, "%s/tmp_empty_dir", builddir);
|
||||||
|
fail_if(ret > PATH_MAX || ret < 0, "snprintf failed\n");
|
||||||
|
|
||||||
|
ret = ini_config_file_from_mem(base_cfg, strlen(base_cfg),
|
||||||
|
&file_ctx);
|
||||||
|
fail_unless(ret == EOK, "Failed to load config. Error %d.\n", ret);
|
||||||
|
|
||||||
|
ret = ini_config_create(&ini_cfg);
|
||||||
|
fail_unless(ret == EOK, "Failed to create config. Error %d.\n", ret);
|
||||||
|
ret = ini_config_parse(file_ctx, INI_STOP_ON_ERROR, INI_MV1S_ALLOW, 0,
|
||||||
|
ini_cfg);
|
||||||
|
fail_unless(ret == EOK, "Failed to parse configuration. Error %d.\n", ret);
|
||||||
|
|
||||||
|
/* Create an empty directory */
|
||||||
|
ret = mkdir(empty_dir_path, 0700);
|
||||||
|
if (ret == -1) {
|
||||||
|
ret = errno;
|
||||||
|
fail_if(ret != EEXIST,
|
||||||
|
"Failed to create empty directory. Error %d.\n", errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ini_config_augment(ini_cfg,
|
||||||
|
empty_dir_path,
|
||||||
|
patterns,
|
||||||
|
sections,
|
||||||
|
NULL,
|
||||||
|
INI_STOP_ON_ANY,
|
||||||
|
INI_MV1S_OVERWRITE,
|
||||||
|
INI_PARSE_NOWRAP,
|
||||||
|
INI_MV2S_OVERWRITE,
|
||||||
|
&result_cfg,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
fail_unless(ret == EOK);
|
||||||
|
|
||||||
|
/* If the snippet directory is empty, result_cfg should be the original
|
||||||
|
* ini_cfg and not NULL */
|
||||||
|
fail_if(result_cfg == NULL);
|
||||||
|
|
||||||
|
/* Now check if the content of result_cfg is what we expected */
|
||||||
|
section_list = ini_get_section_list(result_cfg, &size, NULL);
|
||||||
|
fail_unless(size == 1);
|
||||||
|
fail_unless(strcmp(section_list[0], "section_one") == 0);
|
||||||
|
|
||||||
|
attrs_list = ini_get_attribute_list(result_cfg, section_list[0],
|
||||||
|
&size, NULL);
|
||||||
|
fail_unless(size == 1);
|
||||||
|
fail_unless(strcmp(attrs_list[0], "one") == 0);
|
||||||
|
|
||||||
|
ret = ini_get_config_valueobj(section_list[0],
|
||||||
|
attrs_list[0],
|
||||||
|
result_cfg,
|
||||||
|
INI_GET_FIRST_VALUE,
|
||||||
|
&vo);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
|
||||||
|
val = ini_get_int32_config_value(vo, 1, 100, NULL);
|
||||||
|
fail_unless(val == 1, "Expected attribute value not found.\n");
|
||||||
|
|
||||||
|
ini_free_attribute_list(attrs_list);
|
||||||
|
ini_free_section_list(section_list);
|
||||||
|
ini_config_destroy(result_cfg);
|
||||||
|
ini_config_destroy(ini_cfg);
|
||||||
|
ini_config_file_destroy(file_ctx);
|
||||||
|
remove(empty_dir_path);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
static Suite *ini_augment_suite(void)
|
||||||
|
{
|
||||||
|
Suite *s = suite_create("ini_augment_suite");
|
||||||
|
|
||||||
|
TCase *tc_augment = tcase_create("ini_augment");
|
||||||
|
tcase_add_test(tc_augment, test_ini_augment_merge_sections);
|
||||||
|
tcase_add_test(tc_augment, test_ini_augment_empty_dir);
|
||||||
|
|
||||||
|
suite_add_tcase(s, tc_augment);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
int number_failed;
|
||||||
|
|
||||||
|
Suite *s = ini_augment_suite();
|
||||||
|
SRunner *sr = srunner_create(s);
|
||||||
|
srunner_run_all(sr, CK_ENV);
|
||||||
|
number_failed = srunner_ntests_failed(sr);
|
||||||
|
srunner_free(sr);
|
||||||
|
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
|
}
|
428
tests/sanity/ini_comment_ut.c
Normal file
428
tests/sanity/ini_comment_ut.c
Normal file
@ -0,0 +1,428 @@
|
|||||||
|
/*
|
||||||
|
INI LIBRARY
|
||||||
|
|
||||||
|
Unit test for the comment object.
|
||||||
|
|
||||||
|
Copyright (C) Dmitri Pal <dpal@redhat.com> 2010
|
||||||
|
|
||||||
|
INI Library is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
INI Library 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 Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with INI Library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#define TRACE_HOME
|
||||||
|
#include "trace.h"
|
||||||
|
#include "ini_comment.h"
|
||||||
|
|
||||||
|
int verbose = 0;
|
||||||
|
|
||||||
|
#define INIOUT(foo) \
|
||||||
|
do { \
|
||||||
|
if (verbose) foo; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
typedef int (*test_fn)(void);
|
||||||
|
|
||||||
|
static int file_test(void)
|
||||||
|
{
|
||||||
|
int error = EOK;
|
||||||
|
struct ini_comment *ic = NULL;
|
||||||
|
|
||||||
|
if ((error = ini_comment_create(&ic)) ||
|
||||||
|
(error = ini_comment_build(ic, ";Line 0")) ||
|
||||||
|
(error = ini_comment_build(ic, ";Line 1")) ||
|
||||||
|
(error = ini_comment_build(ic, ";Line 2"))) {
|
||||||
|
printf("Failed to create comment object %d\n",
|
||||||
|
error);
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
INIOUT(printf("<==== Comment ====>\n"));
|
||||||
|
INIOUT(ini_comment_print(ic, stdout));
|
||||||
|
INIOUT(printf("<=================>\n"));
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int construct_test(void)
|
||||||
|
{
|
||||||
|
int error = EOK;
|
||||||
|
struct ini_comment *ic = NULL;
|
||||||
|
const char *comments[] = { ";Line1", ";Line2", ";Line3", NULL };
|
||||||
|
|
||||||
|
error = ini_comment_construct(comments,
|
||||||
|
0,
|
||||||
|
&ic);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to create comment object %d\n",
|
||||||
|
error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
INIOUT(printf("<==== Constructed Comment 1 ====>\n"));
|
||||||
|
INIOUT(ini_comment_print(ic, stdout));
|
||||||
|
INIOUT(printf("<=================>\n"));
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
|
||||||
|
error = ini_comment_construct(comments,
|
||||||
|
2,
|
||||||
|
&ic);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to create comment object %d\n",
|
||||||
|
error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
INIOUT(printf("<==== Constructed Comment 2 ====>\n"));
|
||||||
|
INIOUT(ini_comment_print(ic, stdout));
|
||||||
|
INIOUT(printf("<=================>\n"));
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int alter_test(void)
|
||||||
|
{
|
||||||
|
int error = EOK;
|
||||||
|
struct ini_comment *ic = NULL;
|
||||||
|
uint32_t i, num = 0;
|
||||||
|
char *line = NULL;
|
||||||
|
const char *expected[] = { ";Line 0 inserted",
|
||||||
|
";Line 1 inserted",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
";Line 3 replaced",
|
||||||
|
"",
|
||||||
|
";Line 4" };
|
||||||
|
|
||||||
|
|
||||||
|
if ((error = ini_comment_create(&ic)) ||
|
||||||
|
(error = ini_comment_build(ic, ";Line 0")) ||
|
||||||
|
(error = ini_comment_build(ic, NULL)) ||
|
||||||
|
(error = ini_comment_build(ic, ";Line 2")) ||
|
||||||
|
(error = ini_comment_build(ic, ";Line 3")) ||
|
||||||
|
(error = ini_comment_build(ic, ""))) {
|
||||||
|
printf("Failed to create comment object\n");
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
INIOUT(printf("<==== Comment ====>\n"));
|
||||||
|
INIOUT(ini_comment_print(ic, stdout));
|
||||||
|
INIOUT(printf("<=================>\n"));
|
||||||
|
|
||||||
|
if ((error = ini_comment_append(ic, ";Line 4")) ||
|
||||||
|
(error = ini_comment_clear(ic, 2)) ||
|
||||||
|
(error = ini_comment_replace(ic, 3, ";Line 3 replaced")) ||
|
||||||
|
(error = ini_comment_remove(ic, 0)) ||
|
||||||
|
(error = ini_comment_insert(ic, 0, ";Line 0 inserted")) ||
|
||||||
|
(error = ini_comment_insert(ic, 1, ";Line 1 inserted"))) {
|
||||||
|
printf("Failed to create comment object\n");
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
INIOUT(printf("<==== Comment ====>\n"));
|
||||||
|
INIOUT(ini_comment_print(ic, stdout));
|
||||||
|
INIOUT(printf("<=================>\n"));
|
||||||
|
|
||||||
|
error = ini_comment_get_numlines(ic, &num);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to get number of lines.\n");
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < num; i++) {
|
||||||
|
error = ini_comment_get_line(ic, i, &line, NULL);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to get line.\n");
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
if (strcmp(line, expected[i]) != 0) {
|
||||||
|
printf("Lines do not match.\n");
|
||||||
|
printf("GOT: %s\n", line);
|
||||||
|
printf("EXP: %s\n", expected[i]);
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INIOUT(printf("\n\nSwap test\n\n"));
|
||||||
|
|
||||||
|
if ((error = ini_comment_swap(ic, 0 , 6)) ||
|
||||||
|
(error = ini_comment_swap(ic, 1 , 5)) ||
|
||||||
|
(error = ini_comment_swap(ic, 2 , 4))) {
|
||||||
|
printf("Failed to swap lines.\n");
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < num; i++) {
|
||||||
|
error = ini_comment_get_line(ic, i, &line, NULL);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to get line.\n");
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
if (strcmp(line, expected[6 - i]) != 0) {
|
||||||
|
printf("Lines do not match.\n");
|
||||||
|
printf("GOT: %s\n", line);
|
||||||
|
printf("EXP: %s\n", expected[6 - i]);
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int copy_test(void)
|
||||||
|
{
|
||||||
|
int error = EOK;
|
||||||
|
struct ini_comment *ic = NULL;
|
||||||
|
struct ini_comment *ic_copy = NULL;
|
||||||
|
char *line = NULL;
|
||||||
|
char *line_copy = NULL;
|
||||||
|
uint32_t i, num = 0;
|
||||||
|
|
||||||
|
INIOUT(printf("\n\nCopy test\n\n"));
|
||||||
|
|
||||||
|
if ((error = ini_comment_create(&ic)) ||
|
||||||
|
(error = ini_comment_build(ic, ";Line 0")) ||
|
||||||
|
(error = ini_comment_build(ic, ";Line 1")) ||
|
||||||
|
(error = ini_comment_build(ic, ";Line 2"))) {
|
||||||
|
printf("Failed to create comment object %d\n",
|
||||||
|
error);
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
INIOUT(printf("<==== Comment ====>\n"));
|
||||||
|
INIOUT(ini_comment_print(ic, stdout));
|
||||||
|
INIOUT(printf("<=================>\n"));
|
||||||
|
|
||||||
|
if ((error = ini_comment_copy(ic, &ic_copy))) {
|
||||||
|
printf("Failed to create comment object %d\n",
|
||||||
|
error);
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
INIOUT(printf("<==== Comment Copy====>\n"));
|
||||||
|
INIOUT(ini_comment_print(ic_copy, stdout));
|
||||||
|
INIOUT(printf("<=================>\n"));
|
||||||
|
|
||||||
|
error = ini_comment_get_numlines(ic, &num);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to get number of lines.\n");
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
ini_comment_destroy(ic_copy);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < num; i++) {
|
||||||
|
error = ini_comment_get_line(ic, i, &line, NULL);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to get line.\n");
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
ini_comment_destroy(ic_copy);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
error = ini_comment_get_line(ic_copy, i, &line_copy, NULL);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to get line.\n");
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
ini_comment_destroy(ic_copy);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
if (strcmp(line, line_copy) != 0) {
|
||||||
|
printf("Lines do not match.\n");
|
||||||
|
printf("Source: %s\n", line);
|
||||||
|
printf("Copy: %s\n", line_copy);
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
ini_comment_destroy(ic_copy);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
ini_comment_destroy(ic_copy);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int add_test(void)
|
||||||
|
{
|
||||||
|
int error = EOK;
|
||||||
|
struct ini_comment *ic = NULL;
|
||||||
|
struct ini_comment *ic_to_add = NULL;
|
||||||
|
struct ini_comment *ic_cmp = NULL;
|
||||||
|
uint32_t i, num1 = 0, num2 = 0;
|
||||||
|
char *line1 = NULL;
|
||||||
|
char *line2 = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
INIOUT(printf("\n\nAdd test\n\n"));
|
||||||
|
|
||||||
|
if ((error = ini_comment_create(&ic)) ||
|
||||||
|
(error = ini_comment_build(ic, ";Line 0")) ||
|
||||||
|
(error = ini_comment_build(ic, ";Line 1")) ||
|
||||||
|
(error = ini_comment_build(ic, ";Line 2"))) {
|
||||||
|
printf("Failed to create comment object %d\n",
|
||||||
|
error);
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
INIOUT(printf("<==== Comment ====>\n"));
|
||||||
|
INIOUT(ini_comment_print(ic, stdout));
|
||||||
|
INIOUT(printf("<=================>\n"));
|
||||||
|
|
||||||
|
if ((error = ini_comment_create(&ic_to_add)) ||
|
||||||
|
(error = ini_comment_build(ic_to_add, ";Line 3")) ||
|
||||||
|
(error = ini_comment_build(ic_to_add, ";Line 4")) ||
|
||||||
|
(error = ini_comment_build(ic_to_add, ";Line 5"))) {
|
||||||
|
printf("Failed to create comment object %d\n",
|
||||||
|
error);
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
INIOUT(printf("<==== Comment To Add ====>\n"));
|
||||||
|
INIOUT(ini_comment_print(ic_to_add, stdout));
|
||||||
|
INIOUT(printf("<=================>\n"));
|
||||||
|
|
||||||
|
error = ini_comment_add(ic_to_add, ic);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to add one comment to another.\n");
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
ini_comment_destroy(ic_to_add);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
INIOUT(printf("<==== Merged Comment ====>\n"));
|
||||||
|
INIOUT(ini_comment_print(ic, stdout));
|
||||||
|
INIOUT(printf("<=================>\n"));
|
||||||
|
|
||||||
|
if ((error = ini_comment_create(&ic_cmp)) ||
|
||||||
|
(error = ini_comment_build(ic_cmp, ";Line 0")) ||
|
||||||
|
(error = ini_comment_build(ic_cmp, ";Line 1")) ||
|
||||||
|
(error = ini_comment_build(ic_cmp, ";Line 2")) ||
|
||||||
|
(error = ini_comment_build(ic_cmp, ";Line 3")) ||
|
||||||
|
(error = ini_comment_build(ic_cmp, ";Line 4")) ||
|
||||||
|
(error = ini_comment_build(ic_cmp, ";Line 5"))) {
|
||||||
|
printf("Failed to create comment object %d\n",
|
||||||
|
error);
|
||||||
|
ini_comment_destroy(ic_cmp);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
ini_comment_destroy(ic_to_add);
|
||||||
|
|
||||||
|
error = ini_comment_get_numlines(ic, &num1);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to get number of lines.\n");
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
ini_comment_destroy(ic_cmp);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = ini_comment_get_numlines(ic, &num2);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to get number of lines.\n");
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
ini_comment_destroy(ic_cmp);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num1 != num2) {
|
||||||
|
printf("Sizes are different.\n");
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
ini_comment_destroy(ic_cmp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < num1; i++) {
|
||||||
|
line1 = NULL;
|
||||||
|
error = ini_comment_get_line(ic, i, &line1, NULL);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to get line.\n");
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
ini_comment_destroy(ic_cmp);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
line2 = NULL;
|
||||||
|
error = ini_comment_get_line(ic_cmp, i, &line2, NULL);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to get line.\n");
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
ini_comment_destroy(ic_cmp);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
if (strcmp(line1, line2) != 0) {
|
||||||
|
printf("Lines do not match.\n");
|
||||||
|
printf("1st: %s\n", line1);
|
||||||
|
printf("2nd: %s\n", line2);
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
ini_comment_destroy(ic_cmp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
ini_comment_destroy(ic_cmp);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int error = EOK;
|
||||||
|
test_fn tests[] = { file_test,
|
||||||
|
alter_test,
|
||||||
|
copy_test,
|
||||||
|
add_test,
|
||||||
|
construct_test,
|
||||||
|
NULL };
|
||||||
|
test_fn t;
|
||||||
|
int i = 0;
|
||||||
|
char *var;
|
||||||
|
|
||||||
|
if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = 1;
|
||||||
|
else {
|
||||||
|
var = getenv("COMMON_TEST_VERBOSE");
|
||||||
|
if (var) verbose = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
INIOUT(printf("Start\n"));
|
||||||
|
|
||||||
|
while ((t = tests[i++])) {
|
||||||
|
error = t();
|
||||||
|
if (error) {
|
||||||
|
INIOUT(printf("Failed with error %d!\n", error));
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INIOUT(printf("Success!\n"));
|
||||||
|
return 0;
|
||||||
|
}
|
1692
tests/sanity/ini_configmod_ut_check.c
Normal file
1692
tests/sanity/ini_configmod_ut_check.c
Normal file
File diff suppressed because it is too large
Load Diff
306
tests/sanity/ini_parse_ut_check.c
Normal file
306
tests/sanity/ini_parse_ut_check.c
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
/*
|
||||||
|
INI LIBRARY
|
||||||
|
|
||||||
|
Check based unit test for ini parser.
|
||||||
|
|
||||||
|
Copyright (C) Michal Zidek <mzidek@redhat.com> 2016
|
||||||
|
|
||||||
|
INI Library is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
INI Library 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 Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with INI Library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <check.h>
|
||||||
|
|
||||||
|
/* #define TRACE_LEVEL 7 */
|
||||||
|
#define TRACE_HOME
|
||||||
|
#include "trace.h"
|
||||||
|
#include "ini_configobj.h"
|
||||||
|
|
||||||
|
#define TEST_DIR_PATH ""
|
||||||
|
|
||||||
|
START_TEST(test_ini_parse_non_kvp)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct ini_cfgobj *ini_cfg;
|
||||||
|
int value;
|
||||||
|
struct ini_cfgfile *file_ctx;
|
||||||
|
struct value_obj *vo;
|
||||||
|
char non_kvp_cfg[] =
|
||||||
|
"[section_before]\n"
|
||||||
|
"one = 1\n"
|
||||||
|
|
||||||
|
"[section_non_kvp]\n"
|
||||||
|
"two = 2\n"
|
||||||
|
"non_kvp\n"
|
||||||
|
"three = 3\n"
|
||||||
|
"=nonkvp\n"
|
||||||
|
|
||||||
|
"[section_after]\n"
|
||||||
|
"four = 4\n";
|
||||||
|
|
||||||
|
ret = ini_config_file_from_mem(non_kvp_cfg, strlen(non_kvp_cfg),
|
||||||
|
&file_ctx);
|
||||||
|
fail_unless(ret == EOK, "Failed to load config. Error %d.\n", ret);
|
||||||
|
|
||||||
|
/* First try without the INI_PARSE_IGNORE_NON_KVP. This should fail
|
||||||
|
* with error. */
|
||||||
|
ret = ini_config_create(&ini_cfg);
|
||||||
|
fail_unless(ret == EOK, "Failed to create config. Error %d.\n", ret);
|
||||||
|
ret = ini_config_parse(file_ctx, INI_STOP_ON_ERROR, INI_MV1S_ALLOW, 0,
|
||||||
|
ini_cfg);
|
||||||
|
fail_if(ret != 5, "Expected error was not found.\n");
|
||||||
|
|
||||||
|
ini_config_destroy(ini_cfg);
|
||||||
|
ini_config_file_destroy(file_ctx);
|
||||||
|
|
||||||
|
/* Now try with INI_PARSE_IGNORE_NON_KVP. We should have no errors
|
||||||
|
* and all the surounding configuration should be valid */
|
||||||
|
ret = ini_config_file_from_mem(non_kvp_cfg, strlen(non_kvp_cfg),
|
||||||
|
&file_ctx);
|
||||||
|
fail_unless(ret == EOK, "Failed to load config. Error %d.\n", ret);
|
||||||
|
ret = ini_config_create(&ini_cfg);
|
||||||
|
fail_unless(ret == EOK, "Failed to create config. Error %d.\n", ret);
|
||||||
|
ret = ini_config_parse(file_ctx, INI_STOP_ON_ERROR, INI_MV1S_ALLOW,
|
||||||
|
INI_PARSE_IGNORE_NON_KVP,
|
||||||
|
ini_cfg);
|
||||||
|
fail_unless(ret == EOK, "ini_config_parse returned %d\n", ret);
|
||||||
|
|
||||||
|
/* Now check if the surrounding configuration is OK */
|
||||||
|
/* section_before */
|
||||||
|
ret = ini_get_config_valueobj("section_before", "one", ini_cfg,
|
||||||
|
INI_GET_FIRST_VALUE, &vo);
|
||||||
|
fail_unless(ret == EOK, "ini_get_config_valueobj returned %d\n: %s", ret,
|
||||||
|
strerror(ret));
|
||||||
|
|
||||||
|
value = ini_get_int_config_value(vo, 1, -1, &ret);
|
||||||
|
fail_unless(ret == EOK, "ini_get_int_config_value returned %d\n: %s", ret,
|
||||||
|
strerror(ret));
|
||||||
|
|
||||||
|
fail_unless(ret == EOK);
|
||||||
|
fail_if(value != 1, "Expected value 1 got %d\n", value);
|
||||||
|
|
||||||
|
/* section_non_kvp */
|
||||||
|
ret = ini_get_config_valueobj("section_non_kvp", "two", ini_cfg,
|
||||||
|
INI_GET_FIRST_VALUE, &vo);
|
||||||
|
fail_unless(ret == EOK);
|
||||||
|
|
||||||
|
value = ini_get_int_config_value(vo, 1, -1, &ret);
|
||||||
|
fail_unless(ret == EOK);
|
||||||
|
fail_if(value != 2, "Expected value 2 got %d\n", value);
|
||||||
|
|
||||||
|
ret = ini_get_config_valueobj("section_non_kvp", "three", ini_cfg,
|
||||||
|
INI_GET_FIRST_VALUE, &vo);
|
||||||
|
fail_unless(ret == EOK);
|
||||||
|
|
||||||
|
value = ini_get_int_config_value(vo, 1, -1, &ret);
|
||||||
|
fail_unless(ret == EOK);
|
||||||
|
fail_if(value != 3, "Expected value 3 got %d\n", value);
|
||||||
|
|
||||||
|
/* section_after */
|
||||||
|
ret = ini_get_config_valueobj("section_after", "four", ini_cfg,
|
||||||
|
INI_GET_FIRST_VALUE, &vo);
|
||||||
|
fail_unless(ret == EOK);
|
||||||
|
|
||||||
|
value = ini_get_int_config_value(vo, 1, -1, &ret);
|
||||||
|
fail_unless(ret == EOK);
|
||||||
|
fail_if(value != 4, "Expected value 4 got %d\n", value);
|
||||||
|
|
||||||
|
ini_config_destroy(ini_cfg);
|
||||||
|
ini_config_file_destroy(file_ctx);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_ini_parse_section_key_conflict)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This tests the behavior of ini_config_parse to ensure correct handling
|
||||||
|
* of conflicts between sections and keys of the same name. There are
|
||||||
|
* three possibilities for conflict:
|
||||||
|
*
|
||||||
|
* 1. Inside a section, between the section name and a key name
|
||||||
|
* 2. Between a default-section key name and a section name
|
||||||
|
* 3. Between a key name in a different section and a section name
|
||||||
|
*
|
||||||
|
* In case (1), parsing finished without an error. However, when
|
||||||
|
* trying to select a value object inside a section, the returned
|
||||||
|
* object was an unchecked cast from the section's data, and not the
|
||||||
|
* attribute's data. In cases (2) and (3), the parser segfaulted while
|
||||||
|
* trying to merge a section with an attribute.
|
||||||
|
*/
|
||||||
|
|
||||||
|
char config1[] =
|
||||||
|
"[a]\n"
|
||||||
|
"a=a\n";
|
||||||
|
|
||||||
|
char config2[] =
|
||||||
|
"a=b\n"
|
||||||
|
"[a]\n"
|
||||||
|
"c=d\n";
|
||||||
|
|
||||||
|
char config3[] =
|
||||||
|
"[a]\n"
|
||||||
|
"b=c\n"
|
||||||
|
"[b]\n"
|
||||||
|
"a=d\n";
|
||||||
|
|
||||||
|
char *file_contents[] = {config1, config2, config3, NULL};
|
||||||
|
|
||||||
|
size_t iter;
|
||||||
|
|
||||||
|
struct ini_cfgobj *ini_config = NULL;
|
||||||
|
struct ini_cfgfile *file_ctx = NULL;
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
char **sections = NULL;
|
||||||
|
int sections_count = 0;
|
||||||
|
int sections_error = 0;
|
||||||
|
|
||||||
|
char **attributes = NULL;
|
||||||
|
int attributes_count = 0;
|
||||||
|
int attributes_error = 0;
|
||||||
|
|
||||||
|
struct value_obj *val = NULL;
|
||||||
|
char *val_str = NULL;
|
||||||
|
|
||||||
|
for (iter = 0; file_contents[iter] != NULL; iter++) {
|
||||||
|
ret = ini_config_create(&ini_config);
|
||||||
|
fail_unless(ret == EOK, "Failed to create config. Error %d.\n", ret);
|
||||||
|
|
||||||
|
ret = ini_config_file_from_mem(file_contents[iter],
|
||||||
|
strlen(file_contents[iter]),
|
||||||
|
&file_ctx);
|
||||||
|
fail_unless(ret == EOK, "Failed to load file. Error %d.\n", ret);
|
||||||
|
|
||||||
|
ret = ini_config_parse(file_ctx, 1, 0, 0, ini_config);
|
||||||
|
fail_unless(ret == EOK, "Failed to parse file. Error %d.\n", ret);
|
||||||
|
|
||||||
|
sections = ini_get_section_list(ini_config, §ions_count,
|
||||||
|
§ions_error);
|
||||||
|
fail_unless(sections_error == EOK,
|
||||||
|
"Failed to get sections. Error %d.\n",
|
||||||
|
sections_error);
|
||||||
|
|
||||||
|
for (i = 0; i < sections_count; i++) {
|
||||||
|
attributes = ini_get_attribute_list(ini_config,
|
||||||
|
sections[i],
|
||||||
|
&attributes_count,
|
||||||
|
&attributes_error);
|
||||||
|
fail_unless(attributes_error == EOK,
|
||||||
|
"Failed to get attributes. Error %d.\n",
|
||||||
|
attributes_error);
|
||||||
|
|
||||||
|
for (j = 0; j < attributes_count; j++) {
|
||||||
|
ret = ini_get_config_valueobj(sections[i], attributes[j],
|
||||||
|
ini_config, 0, &val);
|
||||||
|
fail_unless(ret == EOK,
|
||||||
|
"Failed to get attribute. Error %d.\n",
|
||||||
|
ret);
|
||||||
|
|
||||||
|
val_str = ini_get_string_config_value(val, &ret);
|
||||||
|
fail_unless(ret == EOK,
|
||||||
|
"Failed to get attribute as string. Error %d.\n",
|
||||||
|
ret);
|
||||||
|
fail_unless(val_str != NULL,
|
||||||
|
"Failed to get attribute as string: was NULL.\n");
|
||||||
|
|
||||||
|
free(val_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
ini_free_attribute_list(attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
ini_free_section_list(sections);
|
||||||
|
ini_config_file_destroy(file_ctx);
|
||||||
|
ini_config_destroy(ini_config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
/* Maybe we should test even bigger values? */
|
||||||
|
#define VALUE_LEN 10000
|
||||||
|
/* The +100 is space for section name and key name. */
|
||||||
|
#define CFGBUF_LEN (VALUE_LEN + 100)
|
||||||
|
START_TEST(test_ini_long_value)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct ini_cfgobj *ini_cfg;
|
||||||
|
struct ini_cfgfile *file_ctx;
|
||||||
|
struct value_obj *vo;
|
||||||
|
char big_val_cfg[CFGBUF_LEN] = {0};
|
||||||
|
char value[VALUE_LEN] = {0};
|
||||||
|
char *value_got;
|
||||||
|
|
||||||
|
/* The value is just a lot of As ending with '\0'*/
|
||||||
|
memset(value, 'A', VALUE_LEN - 1);
|
||||||
|
|
||||||
|
/* Create config file */
|
||||||
|
ret = snprintf(big_val_cfg, CFGBUF_LEN, "[section]\nkey=%s", value);
|
||||||
|
|
||||||
|
ret = ini_config_file_from_mem(big_val_cfg, strlen(big_val_cfg),
|
||||||
|
&file_ctx);
|
||||||
|
fail_unless(ret == EOK, "Failed to load config. Error %d.\n", ret);
|
||||||
|
|
||||||
|
ret = ini_config_create(&ini_cfg);
|
||||||
|
fail_unless(ret == EOK, "Failed to create config. Error %d.\n", ret);
|
||||||
|
ret = ini_config_parse(file_ctx, INI_STOP_ON_ERROR, INI_MV1S_ALLOW, 0,
|
||||||
|
ini_cfg);
|
||||||
|
fail_if(ret != 0, "Failed to parse config. Error %d.\n", ret);
|
||||||
|
|
||||||
|
ret = ini_get_config_valueobj("section", "key", ini_cfg,
|
||||||
|
INI_GET_FIRST_VALUE, &vo);
|
||||||
|
fail_unless(ret == EOK, "ini_get_config_valueobj returned %d\n: %s", ret,
|
||||||
|
strerror(ret));
|
||||||
|
|
||||||
|
value_got = ini_get_string_config_value(vo, &ret);
|
||||||
|
fail_unless(ret == EOK, "ini_get_int_config_value returned %d\n: %s", ret,
|
||||||
|
strerror(ret));
|
||||||
|
|
||||||
|
fail_unless(strcmp(value, value_got) == 0, "Expected and found values differ!\n");
|
||||||
|
free(value_got);
|
||||||
|
ini_config_destroy(ini_cfg);
|
||||||
|
ini_config_file_destroy(file_ctx);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
static Suite *ini_parse_suite(void)
|
||||||
|
{
|
||||||
|
Suite *s = suite_create("ini_parse_suite");
|
||||||
|
|
||||||
|
TCase *tc_parse = tcase_create("ini_parse");
|
||||||
|
tcase_add_test(tc_parse, test_ini_parse_non_kvp);
|
||||||
|
tcase_add_test(tc_parse, test_ini_parse_section_key_conflict);
|
||||||
|
tcase_add_test(tc_parse, test_ini_long_value);
|
||||||
|
|
||||||
|
suite_add_tcase(s, tc_parse);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
int number_failed;
|
||||||
|
|
||||||
|
Suite *s = ini_parse_suite();
|
||||||
|
SRunner *sr = srunner_create(s);
|
||||||
|
/* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */
|
||||||
|
srunner_run_all(sr, CK_ENV);
|
||||||
|
number_failed = srunner_ntests_failed(sr);
|
||||||
|
srunner_free(sr);
|
||||||
|
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
|
}
|
1108
tests/sanity/ini_validators_ut_check.c
Normal file
1108
tests/sanity/ini_validators_ut_check.c
Normal file
File diff suppressed because it is too large
Load Diff
741
tests/sanity/ini_valueobj_ut.c
Normal file
741
tests/sanity/ini_valueobj_ut.c
Normal file
@ -0,0 +1,741 @@
|
|||||||
|
/*
|
||||||
|
INI LIBRARY
|
||||||
|
|
||||||
|
Unit test for the value object.
|
||||||
|
|
||||||
|
Copyright (C) Dmitri Pal <dpal@redhat.com> 2010
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h> /* for errors */
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#include "ini_valueobj.h"
|
||||||
|
#define TRACE_HOME
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
|
#define TEST_SIZE 80
|
||||||
|
|
||||||
|
int verbose = 0;
|
||||||
|
|
||||||
|
#define VOOUT(foo) \
|
||||||
|
do { \
|
||||||
|
if (verbose) foo; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
typedef int (*test_fn)(void);
|
||||||
|
|
||||||
|
static int create_comment(int i, struct ini_comment **ic)
|
||||||
|
{
|
||||||
|
int error = EOK;
|
||||||
|
const char *template = ";Line 0 of the value %d";
|
||||||
|
char comment[TEST_SIZE];
|
||||||
|
struct ini_comment *new_ic = NULL;
|
||||||
|
|
||||||
|
TRACE_FLOW_ENTRY();
|
||||||
|
|
||||||
|
snprintf(comment, TEST_SIZE, template, i);
|
||||||
|
|
||||||
|
|
||||||
|
if ((error = ini_comment_create(&new_ic)) ||
|
||||||
|
(error = ini_comment_build(new_ic, comment)) ||
|
||||||
|
(error = ini_comment_build(new_ic, NULL)) ||
|
||||||
|
(error = ini_comment_build(new_ic, "#This is the second line")) ||
|
||||||
|
(error = ini_comment_build(new_ic, ";This is the third line")) ||
|
||||||
|
(error = ini_comment_build(new_ic, ""))) {
|
||||||
|
printf("Failed to create comment object. Error %d.\n", error);
|
||||||
|
ini_comment_destroy(new_ic);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ic = new_ic;
|
||||||
|
|
||||||
|
TRACE_FLOW_EXIT();
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save value to the file */
|
||||||
|
/* NOTE: might be moved into the API in future */
|
||||||
|
static int save_value(FILE *ff, const char *key, struct value_obj *vo)
|
||||||
|
{
|
||||||
|
|
||||||
|
int error = EOK;
|
||||||
|
struct simplebuffer *sbobj = NULL;
|
||||||
|
uint32_t left = 0;
|
||||||
|
|
||||||
|
TRACE_FLOW_ENTRY();
|
||||||
|
|
||||||
|
error = simplebuffer_alloc(&sbobj);
|
||||||
|
if (error) {
|
||||||
|
TRACE_ERROR_NUMBER("Failed to allocate dynamic string.", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Serialize */
|
||||||
|
error = value_serialize(vo, key, sbobj);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to serialize a value object %d.\n", error);
|
||||||
|
simplebuffer_free(sbobj);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add CR */
|
||||||
|
error = simplebuffer_add_cr(sbobj);
|
||||||
|
if (error) {
|
||||||
|
TRACE_ERROR_NUMBER("Failed to add CR", error);
|
||||||
|
simplebuffer_free(sbobj);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save */
|
||||||
|
left = simplebuffer_get_len(sbobj);
|
||||||
|
while (left > 0) {
|
||||||
|
error = simplebuffer_write(fileno(ff), sbobj, &left);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to write value object %d.\n", error);
|
||||||
|
simplebuffer_free(sbobj);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
simplebuffer_free(sbobj);
|
||||||
|
|
||||||
|
TRACE_FLOW_EXIT();
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test to create value object using arrays */
|
||||||
|
static int other_create_test(FILE *ff, struct value_obj **vo)
|
||||||
|
{
|
||||||
|
int error = EOK;
|
||||||
|
struct value_obj *new_vo = NULL;
|
||||||
|
struct ref_array *raw_lines;
|
||||||
|
struct ref_array *raw_lengths;
|
||||||
|
struct ini_comment *ic = NULL;
|
||||||
|
struct ini_comment *ic2 = NULL;
|
||||||
|
char *val;
|
||||||
|
const char *vallines[] = { "Domain1,",
|
||||||
|
" Domain2 ,",
|
||||||
|
" Domain3 " };
|
||||||
|
const char *fullstr;
|
||||||
|
const char *expected = "Domain1, Domain2 , Domain3";
|
||||||
|
int i;
|
||||||
|
uint32_t origin = 0;
|
||||||
|
uint32_t line = 0;
|
||||||
|
uint32_t len = 0;
|
||||||
|
uint32_t expected_len = 0;
|
||||||
|
|
||||||
|
|
||||||
|
TRACE_FLOW_ENTRY();
|
||||||
|
|
||||||
|
/* Create a pair of arrays */
|
||||||
|
error = value_create_arrays(&raw_lines,
|
||||||
|
&raw_lengths);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to create arrays %d.\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i< 3; i++) {
|
||||||
|
errno = 0;
|
||||||
|
val = strdup(vallines[i]);
|
||||||
|
if (val == NULL) {
|
||||||
|
error = errno;
|
||||||
|
printf("Failed to dup memory %d.\n", error);
|
||||||
|
value_destroy_arrays(raw_lines,
|
||||||
|
raw_lengths);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add line to the arrays */
|
||||||
|
error = value_add_to_arrays(val,
|
||||||
|
strlen(val),
|
||||||
|
raw_lines,
|
||||||
|
raw_lengths);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to add to arrays %d.\n", error);
|
||||||
|
value_destroy_arrays(raw_lines,
|
||||||
|
raw_lengths);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a comment */
|
||||||
|
error = create_comment(1000, &ic);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to create comment %d.\n", error);
|
||||||
|
value_destroy_arrays(raw_lines,
|
||||||
|
raw_lengths);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create object */
|
||||||
|
error = value_create_from_refarray(raw_lines,
|
||||||
|
raw_lengths,
|
||||||
|
1,
|
||||||
|
INI_VALUE_READ,
|
||||||
|
3,
|
||||||
|
70,
|
||||||
|
ic,
|
||||||
|
&new_vo);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to create comment %d.\n", error);
|
||||||
|
value_destroy_arrays(raw_lines,
|
||||||
|
raw_lengths);
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save value to the file */
|
||||||
|
error = save_value(ff, "baz", new_vo);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to save value to file %d.\n", error);
|
||||||
|
value_destroy(new_vo);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now do assertions and modifications to the object */
|
||||||
|
|
||||||
|
/* NOTE: Below this line do not need to free arrays or comment
|
||||||
|
* they became internal parts of the value object
|
||||||
|
* and will be freed as a part of it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Get concatenated value */
|
||||||
|
error = value_get_concatenated(new_vo,
|
||||||
|
&fullstr);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to get the string %d.\n", error);
|
||||||
|
value_destroy(new_vo);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get length of the concatenated value */
|
||||||
|
value_get_concatenated_len(new_vo, &len);
|
||||||
|
expected_len = strlen(expected);
|
||||||
|
|
||||||
|
if ((len != expected_len) ||
|
||||||
|
(strncmp(fullstr, expected, expected_len + 1) != 0)) {
|
||||||
|
printf("The expected value is different.\n");
|
||||||
|
printf("The expected value is %s\n", expected);
|
||||||
|
printf("The real value is %s\n", fullstr);
|
||||||
|
printf("The expected len is %d, real %d.\n", expected_len, len);
|
||||||
|
value_destroy(new_vo);
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get value's origin */
|
||||||
|
error = value_get_origin(new_vo, &origin);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to get origin %d.\n", error);
|
||||||
|
value_destroy(new_vo);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (origin != INI_VALUE_READ) {
|
||||||
|
printf("The expected origin is different.\n%d\n", origin);
|
||||||
|
value_destroy(new_vo);
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get value's line */
|
||||||
|
error = value_get_line(new_vo, &line);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to get origin %d.\n", error);
|
||||||
|
value_destroy(new_vo);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line != 1) {
|
||||||
|
printf("The expected line is different.\n%d\n", origin);
|
||||||
|
value_destroy(new_vo);
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get comment from the value */
|
||||||
|
ic = NULL;
|
||||||
|
error = value_extract_comment(new_vo, &ic);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to extract comment %d.\n", error);
|
||||||
|
value_destroy(new_vo);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ic == NULL) {
|
||||||
|
printf("The expected comment to be there.\n");
|
||||||
|
value_destroy(new_vo);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOOUT(ini_comment_print(ic, stdout));
|
||||||
|
|
||||||
|
/* Get comment again */
|
||||||
|
ic2 = NULL;
|
||||||
|
error = value_extract_comment(new_vo, &ic2);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to extract comment %d.\n", error);
|
||||||
|
value_destroy(new_vo);
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ic2 != NULL) {
|
||||||
|
printf("The expected NO comment to be there.\n");
|
||||||
|
value_destroy(new_vo);
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
/* No free for ic2 since it is the same object */
|
||||||
|
|
||||||
|
/* But this should not happen anyways -
|
||||||
|
* it will be coding error.
|
||||||
|
*/
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Put comment back */
|
||||||
|
error = value_put_comment(new_vo, ic);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to put comment back %d.\n", error);
|
||||||
|
value_destroy(new_vo);
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save value to the file */
|
||||||
|
error = save_value(ff, "bar", new_vo);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to save value to file %d.\n", error);
|
||||||
|
value_destroy(new_vo);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
*vo = new_vo;
|
||||||
|
|
||||||
|
TRACE_FLOW_EXIT();
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Modify the value object */
|
||||||
|
static int modify_test(FILE *ff, struct value_obj *vo)
|
||||||
|
{
|
||||||
|
int error = EOK;
|
||||||
|
const char *strval = "Domain100, Domain200, Domain300";
|
||||||
|
|
||||||
|
TRACE_FLOW_ENTRY();
|
||||||
|
|
||||||
|
|
||||||
|
/* Update key length */
|
||||||
|
error = value_set_keylen(vo, strlen("foobar"));
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to change key length %d.\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update value */
|
||||||
|
error = value_update(vo,
|
||||||
|
strval,
|
||||||
|
strlen(strval),
|
||||||
|
INI_VALUE_CREATED,
|
||||||
|
10);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to update value %d.\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Save value to the file */
|
||||||
|
error = save_value(ff, "foobar", vo);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to save value to file %d.\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE_FLOW_EXIT();
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int vo_basic_test(void)
|
||||||
|
{
|
||||||
|
int error = EOK;
|
||||||
|
const char *strvalue = "Test multi_word_value_that_will_"
|
||||||
|
"be_split_between_several_lines_!";
|
||||||
|
|
||||||
|
/* Other testing can be done with the following string:
|
||||||
|
* const char *strvalue = "Test multi word value that "
|
||||||
|
* "will be split between several lines";
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct value_obj *vo = NULL;
|
||||||
|
uint32_t wrap = 0;
|
||||||
|
struct ini_comment *ic = NULL;
|
||||||
|
FILE *ff = NULL;
|
||||||
|
|
||||||
|
TRACE_FLOW_ENTRY();
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
ff = fopen("test.ini","wt");
|
||||||
|
if (ff == NULL) {
|
||||||
|
error = errno;
|
||||||
|
printf("Failed to open file. Error %d.\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (wrap = 0; wrap < 80; wrap++) {
|
||||||
|
|
||||||
|
ic = NULL;
|
||||||
|
error = create_comment(wrap, &ic);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to create a new comment object %d.\n", error);
|
||||||
|
fclose(ff);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
vo = NULL;
|
||||||
|
error = value_create_new(strvalue,
|
||||||
|
strlen(strvalue),
|
||||||
|
INI_VALUE_CREATED,
|
||||||
|
3,
|
||||||
|
wrap,
|
||||||
|
ic,
|
||||||
|
&vo);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to create a new value object %d.\n", error);
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
fclose(ff);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = save_value(ff, "key", vo);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to save value to file %d.\n", error);
|
||||||
|
value_destroy(vo);
|
||||||
|
fclose(ff);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
value_destroy(vo);
|
||||||
|
}
|
||||||
|
|
||||||
|
vo = NULL;
|
||||||
|
|
||||||
|
/* Run other create test here */
|
||||||
|
error = other_create_test(ff, &vo);
|
||||||
|
if (error) {
|
||||||
|
printf("Create test failed %d.\n", error);
|
||||||
|
fclose(ff);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Run modify test here */
|
||||||
|
error = modify_test(ff, vo);
|
||||||
|
if (error) {
|
||||||
|
printf("Modify test failed %d.\n", error);
|
||||||
|
fclose(ff);
|
||||||
|
value_destroy(vo);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
value_destroy(vo);
|
||||||
|
|
||||||
|
|
||||||
|
ic = NULL;
|
||||||
|
error = create_comment(100, &ic);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to create a new comment object %d.\n", error);
|
||||||
|
fclose(ff);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
ini_comment_print(ic, ff);
|
||||||
|
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
|
||||||
|
fclose(ff);
|
||||||
|
|
||||||
|
TRACE_FLOW_EXIT();
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vo_copy_test(void)
|
||||||
|
{
|
||||||
|
int error = EOK;
|
||||||
|
const char *strvalue = "Test multi word value that "
|
||||||
|
"will be split between several lines";
|
||||||
|
|
||||||
|
struct value_obj *vo = NULL;
|
||||||
|
struct value_obj *vo_copy = NULL;
|
||||||
|
uint32_t wrap = 0;
|
||||||
|
struct ini_comment *ic = NULL;
|
||||||
|
FILE *ff = NULL;
|
||||||
|
char comment[100];
|
||||||
|
|
||||||
|
TRACE_FLOW_ENTRY();
|
||||||
|
|
||||||
|
VOOUT(printf("Copy test\n"));
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
ff = fopen("test.ini","a");
|
||||||
|
if (ff == NULL) {
|
||||||
|
error = errno;
|
||||||
|
printf("Failed to open file. Error %d.\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = ini_comment_create(&ic);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to create comment object\n");
|
||||||
|
fclose(ff);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = ini_comment_append(ic, "#This is a copy test!");
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to add a line to the comment %d.\n", error);
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
fclose(ff);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = ini_comment_append(ic, "#Replacable comment line");
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to add a line to the comment %d.\n", error);
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
fclose(ff);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = value_create_new(strvalue,
|
||||||
|
strlen(strvalue),
|
||||||
|
INI_VALUE_CREATED,
|
||||||
|
3,
|
||||||
|
20,
|
||||||
|
ic,
|
||||||
|
&vo);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to create a new value object %d.\n", error);
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
fclose(ff);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = save_value(ff, "key", vo);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to save value to file %d.\n", error);
|
||||||
|
value_destroy(vo);
|
||||||
|
fclose(ff);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (wrap = 0; wrap < 80; wrap++) {
|
||||||
|
|
||||||
|
TRACE_INFO_NUMBER("Iteration:", wrap);
|
||||||
|
|
||||||
|
vo_copy = NULL;
|
||||||
|
error = value_copy(vo, &vo_copy);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to create a new value object %d.\n", error);
|
||||||
|
value_destroy(vo);
|
||||||
|
fclose(ff);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = value_set_boundary(vo_copy, wrap);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to set boundary %d.\n", error);
|
||||||
|
value_destroy(vo);
|
||||||
|
value_destroy(vo_copy);
|
||||||
|
fclose(ff);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get comment from the value */
|
||||||
|
ic = NULL;
|
||||||
|
error = value_extract_comment(vo_copy, &ic);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to extract comment %d.\n", error);
|
||||||
|
value_destroy(vo);
|
||||||
|
value_destroy(vo_copy);
|
||||||
|
fclose(ff);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Replace comment in the value */
|
||||||
|
snprintf(comment, TEST_SIZE, ";This is value with boundary %d", wrap);
|
||||||
|
VOOUT(printf("Comment: %s\n", comment));
|
||||||
|
error = ini_comment_replace(ic, 1, comment);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to replace comment %d.\n", error);
|
||||||
|
value_destroy(vo);
|
||||||
|
value_destroy(vo_copy);
|
||||||
|
fclose(ff);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set comment into the value */
|
||||||
|
error = value_put_comment(vo_copy, ic);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to set comment %d.\n", error);
|
||||||
|
value_destroy(vo);
|
||||||
|
value_destroy(vo_copy);
|
||||||
|
fclose(ff);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = save_value(ff, "key", vo_copy);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to save value to file %d.\n", error);
|
||||||
|
value_destroy(vo);
|
||||||
|
value_destroy(vo_copy);
|
||||||
|
fclose(ff);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
value_destroy(vo_copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
value_destroy(vo);
|
||||||
|
fclose(ff);
|
||||||
|
TRACE_FLOW_EXIT();
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vo_show_test(void)
|
||||||
|
{
|
||||||
|
VOOUT(system("cat test.ini"));
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vo_mc_test(void)
|
||||||
|
{
|
||||||
|
int error = EOK;
|
||||||
|
struct value_obj *vo1 = NULL;
|
||||||
|
struct value_obj *vo2 = NULL;
|
||||||
|
struct ini_comment *ic = NULL;
|
||||||
|
|
||||||
|
TRACE_FLOW_ENTRY();
|
||||||
|
|
||||||
|
VOOUT(printf("<=== Merge Comment Test ===>\n"));
|
||||||
|
|
||||||
|
error = create_comment(1, &ic);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to create a new comment object %d.\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = value_create_new("test1",
|
||||||
|
5,
|
||||||
|
INI_VALUE_CREATED,
|
||||||
|
3,
|
||||||
|
80,
|
||||||
|
ic,
|
||||||
|
&vo1);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to create the first value object %d.\n", error);
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = create_comment(2, &ic);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to create a new comment object %d.\n", error);
|
||||||
|
value_destroy(vo1);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = value_create_new("test2",
|
||||||
|
5,
|
||||||
|
INI_VALUE_CREATED,
|
||||||
|
3,
|
||||||
|
80,
|
||||||
|
ic,
|
||||||
|
&vo2);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to create the second value object %d.\n", error);
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
value_destroy(vo1);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Merge comment from one value into another */
|
||||||
|
error = value_merge_comment(vo2, vo1);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to merge comments %d.\n", error);
|
||||||
|
value_destroy(vo1);
|
||||||
|
value_destroy(vo2);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
value_destroy(vo2);
|
||||||
|
|
||||||
|
VOOUT(printf("<=== Key ===>\n"));
|
||||||
|
VOOUT(value_print("key", vo1));
|
||||||
|
|
||||||
|
error = value_extract_comment(vo1, &ic);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to extract comment %d.\n", error);
|
||||||
|
value_destroy(vo1);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
value_destroy(vo1);
|
||||||
|
|
||||||
|
VOOUT(printf("<=== Comment ===>\n"));
|
||||||
|
VOOUT(ini_comment_print(ic, stdout));
|
||||||
|
ini_comment_destroy(ic);
|
||||||
|
|
||||||
|
TRACE_FLOW_EXIT();
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Main function of the unit test */
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int error = 0;
|
||||||
|
test_fn tests[] = { vo_basic_test,
|
||||||
|
vo_copy_test,
|
||||||
|
vo_show_test,
|
||||||
|
vo_mc_test,
|
||||||
|
NULL };
|
||||||
|
test_fn t;
|
||||||
|
int i = 0;
|
||||||
|
char *var;
|
||||||
|
|
||||||
|
if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = 1;
|
||||||
|
else {
|
||||||
|
var = getenv("COMMON_TEST_VERBOSE");
|
||||||
|
if (var) verbose = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOOUT(printf("Start\n"));
|
||||||
|
|
||||||
|
while ((t = tests[i++])) {
|
||||||
|
error = t();
|
||||||
|
if (error) {
|
||||||
|
VOOUT(printf("Failed with error %d!\n", error));
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOOUT(printf("Success!\n"));
|
||||||
|
return 0;
|
||||||
|
}
|
768
tests/sanity/path_utils_ut.c
Normal file
768
tests/sanity/path_utils_ut.c
Normal file
@ -0,0 +1,768 @@
|
|||||||
|
/*
|
||||||
|
path_utils - unit tests
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
Jakub Hrozek <jhrozek@redhat.com>
|
||||||
|
|
||||||
|
Copyright (C) 2009 Red Hat
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <check.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "path_utils.h"
|
||||||
|
|
||||||
|
#define fail_unless_str_equal(a, b) do { \
|
||||||
|
fail_unless(strcmp(a, b) == 0, \
|
||||||
|
"The strings '%s' and '%s' are different, expected same", \
|
||||||
|
a, b); \
|
||||||
|
} while(0);
|
||||||
|
|
||||||
|
#define DIR_TEMPLATE "test-directory-list-dir-XXXXXX"
|
||||||
|
#define SUBDIR "test-directory-list-subdir"
|
||||||
|
#define SUBSUBDIR "test-directory-list-subsubdir"
|
||||||
|
char *dlist_dir;
|
||||||
|
char *dlist_subdir;
|
||||||
|
char *dlist_subsubdir;
|
||||||
|
|
||||||
|
/**** get_dirname ****/
|
||||||
|
START_TEST(test_dirname)
|
||||||
|
{
|
||||||
|
char p[PATH_MAX];
|
||||||
|
char cwd[PATH_MAX];
|
||||||
|
|
||||||
|
fail_unless(get_dirname(p, PATH_MAX, "/foo/bar") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, "/foo");
|
||||||
|
|
||||||
|
fail_unless(get_dirname(p, PATH_MAX, "/") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, "/");
|
||||||
|
|
||||||
|
fail_unless(get_dirname(p, PATH_MAX, "/foo") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, "/");
|
||||||
|
|
||||||
|
fail_unless(get_dirname(p, PATH_MAX, "//foo//bar") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, "//foo");
|
||||||
|
|
||||||
|
fail_unless(get_dirname(p, PATH_MAX, "//foo//") == SUCCESS);
|
||||||
|
fail_unless(!strcmp(p, "/") || !strcmp(p, "//"));
|
||||||
|
|
||||||
|
fail_unless(get_dirname(p, PATH_MAX, "foo//bar") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, "foo");
|
||||||
|
|
||||||
|
fail_unless(get_dirname(p, PATH_MAX, "foo//////bar") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, "foo");
|
||||||
|
|
||||||
|
/* if pathname does not contain a slash, dirname returns cwd */
|
||||||
|
fail_if(getcwd(cwd, PATH_MAX) == NULL, "getcwd failed");
|
||||||
|
|
||||||
|
fail_unless(get_dirname(p, PATH_MAX, "foo") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, cwd);
|
||||||
|
|
||||||
|
fail_unless(get_dirname(p, PATH_MAX, ".") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, cwd);
|
||||||
|
|
||||||
|
fail_unless(get_dirname(p, PATH_MAX, "..") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, cwd);
|
||||||
|
|
||||||
|
fail_unless(get_dirname(p, PATH_MAX, "") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, cwd);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_dirname_neg)
|
||||||
|
{
|
||||||
|
char neg[3];
|
||||||
|
char p[PATH_MAX];
|
||||||
|
|
||||||
|
fail_if(get_dirname(neg, 3, "/foo/bar") == SUCCESS);
|
||||||
|
fail_unless(get_dirname(p, PATH_MAX, NULL) == EINVAL);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
/**** get_basename ****/
|
||||||
|
START_TEST(test_basename)
|
||||||
|
{
|
||||||
|
char p[PATH_MAX];
|
||||||
|
char cwd[PATH_MAX];
|
||||||
|
|
||||||
|
fail_unless(get_basename(p, PATH_MAX, "/foo/bar") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, "bar");
|
||||||
|
|
||||||
|
fail_unless(get_basename(p, PATH_MAX, "/foo/") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, "foo");
|
||||||
|
|
||||||
|
fail_unless(get_basename(p, PATH_MAX, "foo") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, "foo");
|
||||||
|
|
||||||
|
fail_unless(get_basename(p, PATH_MAX, "/") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, "/");
|
||||||
|
|
||||||
|
fail_if(getcwd(cwd, PATH_MAX) == NULL, "getcwd failed");
|
||||||
|
|
||||||
|
fail_unless(get_basename(p, PATH_MAX, ".") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, cwd);
|
||||||
|
|
||||||
|
fail_unless(get_basename(p, PATH_MAX, "") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, cwd);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_basename_neg)
|
||||||
|
{
|
||||||
|
char neg[3];
|
||||||
|
char p[PATH_MAX];
|
||||||
|
|
||||||
|
fail_if(get_basename(neg, 3, "/foo/bar") == SUCCESS);
|
||||||
|
|
||||||
|
fail_unless(get_basename(p, PATH_MAX, NULL) == EINVAL);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
/**** is_absolute_path ****/
|
||||||
|
START_TEST(test_is_absolute_path)
|
||||||
|
{
|
||||||
|
fail_unless(is_absolute_path("") == false);
|
||||||
|
fail_unless(is_absolute_path("foo/bar") == false);
|
||||||
|
|
||||||
|
fail_unless(is_absolute_path("/foo/bar") == true);
|
||||||
|
fail_unless(is_absolute_path("/foo") == true);
|
||||||
|
fail_unless(is_absolute_path("/") == true);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
/**** get_dirname_and_basename ****/
|
||||||
|
/* Just a couple of basic tests - get_dirname_and_basename()
|
||||||
|
* uses get_dirname() and get_basename() under the hood which
|
||||||
|
* are tested enough in their specific tests
|
||||||
|
*/
|
||||||
|
START_TEST(test_dirname_and_basename)
|
||||||
|
{
|
||||||
|
char dir[PATH_MAX];
|
||||||
|
char base[PATH_MAX];
|
||||||
|
char cwd[PATH_MAX];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = get_directory_and_base_name(dir, PATH_MAX, base, PATH_MAX, "/foo/bar");
|
||||||
|
fail_unless(ret == SUCCESS);
|
||||||
|
fail_unless_str_equal(dir, "/foo");
|
||||||
|
fail_unless_str_equal(base, "bar");
|
||||||
|
|
||||||
|
ret = get_directory_and_base_name(dir, PATH_MAX, base, PATH_MAX, "/foo");
|
||||||
|
fail_unless(ret == SUCCESS);
|
||||||
|
fail_unless_str_equal(dir, "/");
|
||||||
|
fail_unless_str_equal(base, "foo");
|
||||||
|
|
||||||
|
ret = get_directory_and_base_name(dir, PATH_MAX, base, PATH_MAX, "/");
|
||||||
|
fail_unless(ret == SUCCESS);
|
||||||
|
fail_unless_str_equal(dir, "/");
|
||||||
|
fail_unless_str_equal(base, "/");
|
||||||
|
|
||||||
|
fail_if(getcwd(cwd, PATH_MAX) == NULL, "getcwd failed");
|
||||||
|
|
||||||
|
ret = get_directory_and_base_name(dir, PATH_MAX, base, PATH_MAX, "foo");
|
||||||
|
fail_unless(ret == SUCCESS);
|
||||||
|
fail_unless_str_equal(dir, cwd);
|
||||||
|
fail_unless_str_equal(base, "foo");
|
||||||
|
|
||||||
|
ret = get_directory_and_base_name(dir, PATH_MAX, base, PATH_MAX, "");
|
||||||
|
fail_unless(ret == SUCCESS);
|
||||||
|
fail_unless_str_equal(dir, cwd);
|
||||||
|
fail_unless_str_equal(base, "");
|
||||||
|
|
||||||
|
ret = get_directory_and_base_name(dir, PATH_MAX, base, PATH_MAX, ".");
|
||||||
|
fail_unless(ret == SUCCESS);
|
||||||
|
fail_unless_str_equal(dir, cwd);
|
||||||
|
fail_unless_str_equal(base, "");
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_dirname_and_basename_neg)
|
||||||
|
{
|
||||||
|
char dir[PATH_MAX];
|
||||||
|
char base[PATH_MAX];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = get_directory_and_base_name(dir, PATH_MAX, base, PATH_MAX, NULL);
|
||||||
|
fail_unless(ret == EINVAL);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
/**** path_concat ****/
|
||||||
|
START_TEST(test_path_concat)
|
||||||
|
{
|
||||||
|
char p[PATH_MAX];
|
||||||
|
char p2[9];
|
||||||
|
|
||||||
|
fail_unless(path_concat(p, PATH_MAX, "/foo", "bar") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, "/foo/bar");
|
||||||
|
|
||||||
|
fail_unless(path_concat(p, PATH_MAX, "/foo", "/bar") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, "/foo/bar");
|
||||||
|
|
||||||
|
fail_unless(path_concat(p, PATH_MAX, "/foo/", "/bar") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, "/foo/bar");
|
||||||
|
|
||||||
|
fail_unless(path_concat(p, PATH_MAX, "/foo", "") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, "/foo");
|
||||||
|
|
||||||
|
fail_unless(path_concat(p, PATH_MAX, "foo", NULL) == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, "foo");
|
||||||
|
|
||||||
|
fail_unless(path_concat(p, PATH_MAX, "", "foo") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, "foo");
|
||||||
|
|
||||||
|
fail_unless(path_concat(p, PATH_MAX, "/", "foo") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, "/foo");
|
||||||
|
|
||||||
|
fail_unless(path_concat(p, PATH_MAX, "/foo", "/") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, "/foo/");
|
||||||
|
|
||||||
|
fail_unless(path_concat(p, PATH_MAX, "/foo", "bar/") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, "/foo/bar/");
|
||||||
|
|
||||||
|
fail_unless(path_concat(p, PATH_MAX, NULL, "foo") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, "foo");
|
||||||
|
|
||||||
|
/* on-by-one */
|
||||||
|
fail_unless(path_concat(p2, 9, "/foo", "bar") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p2, "/foo/bar");
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_path_concat_neg)
|
||||||
|
{
|
||||||
|
char small[3];
|
||||||
|
char small2[5];
|
||||||
|
char small3[7];
|
||||||
|
char p2[10];
|
||||||
|
|
||||||
|
/* these two test different conditions */
|
||||||
|
|
||||||
|
/* Test if head is longer than the buffer */
|
||||||
|
fail_unless(path_concat(small, 3, "/foo", "bar") == ENOBUFS);
|
||||||
|
/* On ENOBUFS, path should be empty */
|
||||||
|
fail_unless_str_equal(small, "");
|
||||||
|
|
||||||
|
/* Test if head is the same length as the buffer */
|
||||||
|
fail_unless(path_concat(small2, 5, "/foo", "bar") == ENOBUFS);
|
||||||
|
/* On ENOBUFS, path should be empty */
|
||||||
|
fail_unless_str_equal(small2, "");
|
||||||
|
|
||||||
|
/* Test if head+tail is the longer than the buffer */
|
||||||
|
fail_unless(path_concat(small3, 7, "/foo", "bar") == ENOBUFS);
|
||||||
|
/* On ENOBUFS, path should be empty */
|
||||||
|
fail_unless_str_equal(small3, "");
|
||||||
|
|
||||||
|
/* off-by-one */
|
||||||
|
/* Fill with garbage data for now */
|
||||||
|
memset(p2, 'Z', 9);
|
||||||
|
p2[9] = '\0';
|
||||||
|
|
||||||
|
fail_unless(path_concat(p2, 8, "/foo", "bar") == ENOBUFS);
|
||||||
|
/* Make sure we don't write past the end of the buffer */
|
||||||
|
fail_unless(p2[8] == 'Z', "Got [%d]", p2[8]);
|
||||||
|
/* On ENOBUFS, path should be empty */
|
||||||
|
fail_unless_str_equal(p2, "");
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
/**** make_path_absolute ****/
|
||||||
|
START_TEST(test_make_path_absolute)
|
||||||
|
{
|
||||||
|
char p[PATH_MAX];
|
||||||
|
char p2[PATH_MAX];
|
||||||
|
char cwd[PATH_MAX];
|
||||||
|
char *buf;
|
||||||
|
size_t buf_len;
|
||||||
|
|
||||||
|
fail_unless(make_path_absolute(p, PATH_MAX, "/foo") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, "/foo");
|
||||||
|
|
||||||
|
fail_if(getcwd(cwd, PATH_MAX) == NULL, "getcwd failed");
|
||||||
|
|
||||||
|
fail_unless(make_path_absolute(p, PATH_MAX, "foo") == SUCCESS);
|
||||||
|
snprintf(p2, PATH_MAX, "%s/foo", cwd);
|
||||||
|
fail_unless_str_equal(p, p2);
|
||||||
|
|
||||||
|
fail_unless(make_path_absolute(p, PATH_MAX, "") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, cwd);
|
||||||
|
|
||||||
|
/* on-by-one; 2 = terminating null + path delimeter */
|
||||||
|
buf_len = strlen(cwd) + strlen("foo") + 2;
|
||||||
|
buf = malloc(buf_len);
|
||||||
|
fail_if(buf == NULL);
|
||||||
|
fail_unless(make_path_absolute(buf, buf_len, "foo") == SUCCESS);
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_make_path_absolute_neg)
|
||||||
|
{
|
||||||
|
char small[1];
|
||||||
|
char cwd[PATH_MAX];
|
||||||
|
char *small2;
|
||||||
|
int small_len;
|
||||||
|
|
||||||
|
fail_unless(make_path_absolute(small, 1, "/foo") == ENOBUFS);
|
||||||
|
fail_unless(make_path_absolute(NULL, 1, "/foo") == ENOBUFS);
|
||||||
|
|
||||||
|
/* off-by-one */
|
||||||
|
fail_if(getcwd(cwd, PATH_MAX) == NULL, "getcwd failed");
|
||||||
|
small_len = strlen(cwd) + strlen("foo") + 1;
|
||||||
|
small2 = malloc(small_len);
|
||||||
|
fail_if(small2 == NULL);
|
||||||
|
fail_unless(make_path_absolute(small2, small_len, "foo") == ENOBUFS);
|
||||||
|
free(small2);
|
||||||
|
|
||||||
|
/* just enough space for cwd */
|
||||||
|
small_len = strlen(cwd) + 1;
|
||||||
|
small2 = malloc(small_len);
|
||||||
|
fail_if(small2 == NULL);
|
||||||
|
fail_unless(make_path_absolute(small2, small_len, "foo") == ENOBUFS);
|
||||||
|
free(small2);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
/**** make_normalized_absolute_path ****/
|
||||||
|
START_TEST(test_make_normalized_absolute_path)
|
||||||
|
{
|
||||||
|
char p[PATH_MAX];
|
||||||
|
char p2[PATH_MAX];
|
||||||
|
char cwd[PATH_MAX];
|
||||||
|
|
||||||
|
fail_if(getcwd(cwd, PATH_MAX) == NULL, "getcwd failed");
|
||||||
|
|
||||||
|
fail_unless(make_normalized_absolute_path(p, PATH_MAX, "foo/baz/../bar") == SUCCESS);
|
||||||
|
snprintf(p2, PATH_MAX, "%s/foo/bar", cwd);
|
||||||
|
fail_unless_str_equal(p, p2);
|
||||||
|
|
||||||
|
fail_unless(make_normalized_absolute_path(p, PATH_MAX, "/foo/../bar") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, "/bar");
|
||||||
|
|
||||||
|
fail_unless(make_normalized_absolute_path(p, PATH_MAX, "/foo/../baz/../bar") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, "/bar");
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_make_normalized_absolute_path_neg)
|
||||||
|
{
|
||||||
|
char small[1];
|
||||||
|
|
||||||
|
fail_unless(make_path_absolute(small, 1, "/foo") == ENOBUFS);
|
||||||
|
fail_unless(make_path_absolute(NULL, 1, "/foo") == ENOBUFS);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
/**** split_path ****/
|
||||||
|
START_TEST(test_split_path)
|
||||||
|
{
|
||||||
|
char **array;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
array = split_path("/foo/bar", &n);
|
||||||
|
fail_if(array == NULL);
|
||||||
|
fail_unless(n == 3);
|
||||||
|
if (array) {
|
||||||
|
fail_unless_str_equal(array[0], "/");
|
||||||
|
fail_unless_str_equal(array[1], "foo");
|
||||||
|
fail_unless_str_equal(array[2], "bar");
|
||||||
|
free(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
array = split_path("/foo/../bar", &n);
|
||||||
|
fail_if(array == NULL);
|
||||||
|
fail_unless(n == 4);
|
||||||
|
if (array) {
|
||||||
|
fail_unless_str_equal(array[0], "/");
|
||||||
|
fail_unless_str_equal(array[1], "foo");
|
||||||
|
fail_unless_str_equal(array[2], "..");
|
||||||
|
fail_unless_str_equal(array[3], "bar");
|
||||||
|
free(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
array = split_path("/foo/bar", NULL);
|
||||||
|
fail_if(array == NULL);
|
||||||
|
if (array) {
|
||||||
|
fail_unless_str_equal(array[0], "/");
|
||||||
|
fail_unless_str_equal(array[1], "foo");
|
||||||
|
fail_unless_str_equal(array[2], "bar");
|
||||||
|
free(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
array = split_path("foo/bar", &n);
|
||||||
|
fail_if(array == NULL);
|
||||||
|
fail_unless(n == 2);
|
||||||
|
if (array) {
|
||||||
|
fail_unless_str_equal(array[0], "foo");
|
||||||
|
fail_unless_str_equal(array[1], "bar");
|
||||||
|
free(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
array = split_path(".", &n);
|
||||||
|
fail_if(array == NULL);
|
||||||
|
fail_unless(n == 1);
|
||||||
|
if (array) {
|
||||||
|
fail_unless_str_equal(array[0], ".");
|
||||||
|
free(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
array = split_path("foo", &n);
|
||||||
|
fail_if(array == NULL);
|
||||||
|
fail_unless(n == 1);
|
||||||
|
if (array) {
|
||||||
|
fail_unless_str_equal(array[0], "foo");
|
||||||
|
free(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* one might expect { "" } or outright NULL, but we agreed not to
|
||||||
|
* do changes beyond bugfixes at this point */
|
||||||
|
array = split_path("", &n);
|
||||||
|
fail_if(array == NULL);
|
||||||
|
fail_unless(n == 0);
|
||||||
|
if (array) {
|
||||||
|
fail_unless(array[0] == NULL);
|
||||||
|
free(array);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_split_path_neg)
|
||||||
|
{
|
||||||
|
char **array;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
array = split_path(NULL, &n);
|
||||||
|
fail_unless(array == NULL);
|
||||||
|
|
||||||
|
array = split_path(NULL, NULL);
|
||||||
|
fail_unless(array == NULL);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
/**** normalize_path ****/
|
||||||
|
START_TEST(test_normalize_path)
|
||||||
|
{
|
||||||
|
char norm[PATH_MAX];
|
||||||
|
char small[8];
|
||||||
|
|
||||||
|
fail_unless(normalize_path(norm, PATH_MAX, "/foo/../bar") == SUCCESS);
|
||||||
|
fail_unless_str_equal(norm, "/bar");
|
||||||
|
|
||||||
|
fail_unless(normalize_path(norm, PATH_MAX, "/foo/../baz/../bar") == SUCCESS);
|
||||||
|
fail_unless_str_equal(norm, "/bar");
|
||||||
|
|
||||||
|
fail_unless(normalize_path(norm, PATH_MAX, "foo/baz/../bar") == SUCCESS);
|
||||||
|
fail_unless_str_equal(norm, "foo/bar");
|
||||||
|
|
||||||
|
fail_unless(normalize_path(norm, PATH_MAX, "/foo/./bar") == SUCCESS);
|
||||||
|
fail_unless_str_equal(norm, "/foo/bar");
|
||||||
|
|
||||||
|
fail_unless(normalize_path(norm, PATH_MAX, "/foo//bar") == SUCCESS);
|
||||||
|
fail_unless_str_equal(norm, "/foo/bar");
|
||||||
|
|
||||||
|
fail_unless(normalize_path(norm, PATH_MAX, "/foo//bar") == SUCCESS);
|
||||||
|
fail_unless_str_equal(norm, "/foo/bar");
|
||||||
|
|
||||||
|
fail_unless(normalize_path(norm, PATH_MAX, "") == SUCCESS);
|
||||||
|
fail_unless_str_equal(norm, ".");
|
||||||
|
|
||||||
|
fail_unless(normalize_path(norm, PATH_MAX, "/../..") == SUCCESS);
|
||||||
|
fail_unless_str_equal(norm, "/");
|
||||||
|
|
||||||
|
/* on-by-one */
|
||||||
|
fail_unless(normalize_path(small, 8, "foo/baz/../bar") == SUCCESS);
|
||||||
|
fail_unless_str_equal(small, "foo/bar");
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_normalize_path_neg)
|
||||||
|
{
|
||||||
|
char norm[PATH_MAX];
|
||||||
|
char small[4];
|
||||||
|
|
||||||
|
fail_unless(normalize_path(norm, PATH_MAX, "foo/../..") == PATH_UTILS_ERROR_NOT_FULLY_NORMALIZED);
|
||||||
|
|
||||||
|
/* with a buffer of 4 chars, this would test off-by-one error */
|
||||||
|
fail_unless(normalize_path(small, 4, "/foo/../bar") == ENOBUFS);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
/**** common_path_prefix ****/
|
||||||
|
START_TEST(test_common_path_prefix)
|
||||||
|
{
|
||||||
|
char common[PATH_MAX];
|
||||||
|
char small[5];
|
||||||
|
int count;
|
||||||
|
|
||||||
|
fail_unless(common_path_prefix(common, PATH_MAX, &count, "/usr/lib", "/usr/share") == SUCCESS);
|
||||||
|
fail_unless_str_equal(common, "/usr");
|
||||||
|
fail_unless(count == 2);
|
||||||
|
|
||||||
|
fail_unless(common_path_prefix(common, PATH_MAX, NULL, "/usr/lib", "/usr/share") == SUCCESS);
|
||||||
|
fail_unless_str_equal(common, "/usr");
|
||||||
|
|
||||||
|
fail_unless(common_path_prefix(common, PATH_MAX, &count, "/usr/lib", "/usr/lab") == SUCCESS);
|
||||||
|
fail_unless_str_equal(common, "/usr");
|
||||||
|
fail_unless(count == 2);
|
||||||
|
|
||||||
|
fail_unless(common_path_prefix(common, PATH_MAX, &count, "foo", "bar") == SUCCESS);
|
||||||
|
fail_unless_str_equal(common, "");
|
||||||
|
fail_unless(count == 0);
|
||||||
|
|
||||||
|
fail_unless(common_path_prefix(common, PATH_MAX, &count, "/", "/") == SUCCESS);
|
||||||
|
fail_unless_str_equal(common, "/");
|
||||||
|
fail_unless(count == 1);
|
||||||
|
|
||||||
|
fail_unless(common_path_prefix(common, PATH_MAX, &count, NULL, "/usr/share") == SUCCESS);
|
||||||
|
fail_unless_str_equal(common, "");
|
||||||
|
fail_unless(count == 0);
|
||||||
|
|
||||||
|
/* on-by-one */
|
||||||
|
fail_unless(common_path_prefix(small, 5, NULL, "/usr/lib", "/usr/share") == SUCCESS);
|
||||||
|
fail_unless_str_equal(small, "/usr");
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_common_path_prefix_neg)
|
||||||
|
{
|
||||||
|
char small[1];
|
||||||
|
char small2[4];
|
||||||
|
int count;
|
||||||
|
|
||||||
|
fail_unless(common_path_prefix(small, 1, &count, "/usr/lib", "/usr/share") == ENOBUFS);
|
||||||
|
fail_unless(common_path_prefix(NULL, PATH_MAX, &count, "/usr/lib", "/usr/share") == ENOBUFS);
|
||||||
|
/* off-by-one */
|
||||||
|
fail_unless(common_path_prefix(small2, 4, NULL, "/usr/lib", "/usr/share") == ENOBUFS);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
/**** find_existing_directory_ancestor ****/
|
||||||
|
START_TEST(test_find_existing_directory_ancestor)
|
||||||
|
{
|
||||||
|
char p[PATH_MAX];
|
||||||
|
char cwd[PATH_MAX];
|
||||||
|
|
||||||
|
fail_unless(find_existing_directory_ancestor(p, PATH_MAX, "/etc/passwd") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, "/etc");
|
||||||
|
|
||||||
|
/* if pathname does not contain a slash, the parent is cwd */
|
||||||
|
fail_if(getcwd(cwd, PATH_MAX) == NULL, "getcwd failed");
|
||||||
|
|
||||||
|
fail_unless(find_existing_directory_ancestor(p, PATH_MAX, "foo/bar") == SUCCESS);
|
||||||
|
fail_unless_str_equal(p, cwd);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_find_existing_directory_ancestor_neg)
|
||||||
|
{
|
||||||
|
char small[4];
|
||||||
|
fail_unless(find_existing_directory_ancestor(small, 4, "/etc/passwd") == ENOBUFS);
|
||||||
|
fail_unless(find_existing_directory_ancestor(NULL, 4, "/etc/passwd") == ENOBUFS);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
/**** directory_list ****/
|
||||||
|
static void setup_directory_list(void)
|
||||||
|
{
|
||||||
|
char *s = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
s = strdup(DIR_TEMPLATE);
|
||||||
|
fail_unless(s != NULL, "strdup failed\n");
|
||||||
|
if (!s) return;
|
||||||
|
dlist_dir = mkdtemp(s);
|
||||||
|
fail_unless(dlist_dir != NULL, "mkstemp failed [%d][%s]", errno, strerror(errno));
|
||||||
|
|
||||||
|
ret = asprintf(&dlist_subdir, "%s/%s", dlist_dir, SUBDIR);
|
||||||
|
fail_unless(ret != 1, "strdup failed\n");
|
||||||
|
ret = mkdir(dlist_subdir, 0700);
|
||||||
|
fail_unless(ret != -1, "mkdir %s failed [%d][%s]", dlist_subdir, errno, strerror(errno));
|
||||||
|
|
||||||
|
ret = asprintf(&dlist_subsubdir, "%s/%s", dlist_subdir, SUBSUBDIR);
|
||||||
|
fail_unless(ret != 1, "strdup failed\n");
|
||||||
|
ret = mkdir(dlist_subsubdir, 0700);
|
||||||
|
fail_unless(ret != -1, "mkdir %s failed [%d][%s]", dlist_subsubdir, errno, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void teardown_directory_list(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (dlist_subsubdir) {
|
||||||
|
ret = rmdir(dlist_subsubdir);
|
||||||
|
fail_unless(ret != -1, "unlink %s failed [%d][%s]", dlist_subsubdir, errno, strerror(errno));
|
||||||
|
free(dlist_subsubdir);
|
||||||
|
dlist_subsubdir = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dlist_subdir) {
|
||||||
|
ret = rmdir(dlist_subdir);
|
||||||
|
fail_unless(ret != -1, "unlink %s failed [%d][%s]", dlist_subdir, errno, strerror(errno));
|
||||||
|
free(dlist_subdir);
|
||||||
|
dlist_subdir = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dlist_dir) {
|
||||||
|
ret = rmdir(dlist_dir);
|
||||||
|
fail_unless(ret != -1, "unlink %s failed [%d][%s]", dlist_dir, errno, strerror(errno));
|
||||||
|
free(dlist_dir);
|
||||||
|
dlist_dir = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool dirlist_cb_nonrecursive(const char *directory,
|
||||||
|
const char *base_name,
|
||||||
|
const char *path,
|
||||||
|
struct stat *info,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
int *data = (int *) user_data;
|
||||||
|
|
||||||
|
fail_unless_str_equal(path, dlist_subdir);
|
||||||
|
fail_unless(*data == 123);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool dirlist_cb_recursive(const char *directory, const char *base_name,
|
||||||
|
const char *path, struct stat *info,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
bool *seen_child = (bool *) user_data;
|
||||||
|
static bool seen_parent = false;
|
||||||
|
|
||||||
|
if (!seen_parent) {
|
||||||
|
fail_unless_str_equal(path, dlist_subdir);
|
||||||
|
seen_parent = true;
|
||||||
|
} else {
|
||||||
|
*seen_child = true;
|
||||||
|
fail_unless_str_equal(path, dlist_subsubdir);
|
||||||
|
seen_parent = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
START_TEST(test_directory_list)
|
||||||
|
{
|
||||||
|
int data = 123;
|
||||||
|
bool seen_child;
|
||||||
|
|
||||||
|
fail_unless(directory_list(dlist_dir, false, dirlist_cb_nonrecursive, &data) == SUCCESS);
|
||||||
|
|
||||||
|
seen_child = false;
|
||||||
|
fail_unless(directory_list(dlist_dir, true, dirlist_cb_recursive, &seen_child) == SUCCESS);
|
||||||
|
fail_unless(seen_child == true);
|
||||||
|
|
||||||
|
seen_child = false;
|
||||||
|
fail_unless(directory_list(dlist_dir, false, dirlist_cb_recursive, &seen_child) == SUCCESS);
|
||||||
|
fail_unless(seen_child == false);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_directory_list_neg)
|
||||||
|
{
|
||||||
|
fail_if(directory_list("/not/here", false, dirlist_cb_nonrecursive, NULL) == SUCCESS);
|
||||||
|
fail_if(directory_list("/etc/passwd", false, dirlist_cb_nonrecursive, NULL) == SUCCESS);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
/**** is_ancestor_path ****/
|
||||||
|
START_TEST(test_is_ancestor_path)
|
||||||
|
{
|
||||||
|
fail_unless(is_ancestor_path("/a/b/c", "/a/b/c/d") == true);
|
||||||
|
/* equal, not ancestor */
|
||||||
|
fail_unless(is_ancestor_path("/a/b/c/d", "/a/b/c/d") == false);
|
||||||
|
fail_unless(is_ancestor_path("/a/x/c", "/a/b/c/d") == false);
|
||||||
|
fail_unless(is_ancestor_path(NULL, "/a/b/c/d") == false);
|
||||||
|
fail_unless(is_ancestor_path("/a/x/c", NULL) == false);
|
||||||
|
fail_unless(is_ancestor_path(NULL, NULL) == false);
|
||||||
|
fail_unless(is_ancestor_path("", "") == false);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
|
||||||
|
static Suite *path_utils_suite(void)
|
||||||
|
{
|
||||||
|
Suite *s = suite_create("path_utils");
|
||||||
|
|
||||||
|
TCase *tc_path_utils = tcase_create("path_utils");
|
||||||
|
TCase *tc_directory_list = tcase_create("path_utils_directory_list");
|
||||||
|
|
||||||
|
tcase_add_test(tc_path_utils, test_dirname);
|
||||||
|
tcase_add_test(tc_path_utils, test_dirname_neg);
|
||||||
|
|
||||||
|
tcase_add_test(tc_path_utils, test_basename);
|
||||||
|
tcase_add_test(tc_path_utils, test_basename_neg);
|
||||||
|
|
||||||
|
tcase_add_test(tc_path_utils, test_dirname_and_basename);
|
||||||
|
tcase_add_test(tc_path_utils, test_dirname_and_basename_neg);
|
||||||
|
|
||||||
|
tcase_add_test(tc_path_utils, test_is_absolute_path);
|
||||||
|
|
||||||
|
tcase_add_test(tc_path_utils, test_path_concat);
|
||||||
|
tcase_add_test(tc_path_utils, test_path_concat_neg);
|
||||||
|
|
||||||
|
tcase_add_test(tc_path_utils, test_split_path);
|
||||||
|
tcase_add_test(tc_path_utils, test_split_path_neg);
|
||||||
|
|
||||||
|
tcase_add_test(tc_path_utils, test_make_path_absolute);
|
||||||
|
tcase_add_test(tc_path_utils, test_make_path_absolute_neg);
|
||||||
|
|
||||||
|
tcase_add_test(tc_path_utils, test_normalize_path);
|
||||||
|
tcase_add_test(tc_path_utils, test_normalize_path_neg);
|
||||||
|
|
||||||
|
tcase_add_test(tc_path_utils, test_make_normalized_absolute_path);
|
||||||
|
tcase_add_test(tc_path_utils, test_make_normalized_absolute_path_neg);
|
||||||
|
|
||||||
|
tcase_add_test(tc_path_utils, test_common_path_prefix);
|
||||||
|
tcase_add_test(tc_path_utils, test_common_path_prefix_neg);
|
||||||
|
|
||||||
|
tcase_add_test(tc_path_utils, test_find_existing_directory_ancestor);
|
||||||
|
tcase_add_test(tc_path_utils, test_find_existing_directory_ancestor_neg);
|
||||||
|
|
||||||
|
tcase_add_test(tc_path_utils, test_is_ancestor_path);
|
||||||
|
|
||||||
|
tcase_add_checked_fixture(tc_directory_list,
|
||||||
|
setup_directory_list,
|
||||||
|
teardown_directory_list);
|
||||||
|
tcase_add_test(tc_directory_list, test_directory_list);
|
||||||
|
tcase_add_test(tc_directory_list, test_directory_list_neg);
|
||||||
|
|
||||||
|
suite_add_tcase(s, tc_path_utils);
|
||||||
|
suite_add_tcase(s, tc_directory_list);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
int number_failed;
|
||||||
|
|
||||||
|
Suite *s = path_utils_suite();
|
||||||
|
SRunner *sr = srunner_create(s);
|
||||||
|
/* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */
|
||||||
|
srunner_run_all(sr, CK_ENV);
|
||||||
|
number_failed = srunner_ntests_failed(sr);
|
||||||
|
srunner_free(sr);
|
||||||
|
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
775
tests/sanity/ref_array_ut.c
Normal file
775
tests/sanity/ref_array_ut.c
Normal file
@ -0,0 +1,775 @@
|
|||||||
|
/*
|
||||||
|
REF ARRAY
|
||||||
|
|
||||||
|
Implementation of the dynamic array with reference count.
|
||||||
|
|
||||||
|
Copyright (C) Dmitri Pal <dpal@redhat.com> 2009
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h> /* for errors */
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "ref_array.h"
|
||||||
|
#define TRACE_HOME
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
|
int verbose = 0;
|
||||||
|
|
||||||
|
#define RAOUT(foo) \
|
||||||
|
do { \
|
||||||
|
if (verbose) foo; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
typedef int (*test_fn)(void);
|
||||||
|
|
||||||
|
/* Basic test */
|
||||||
|
static int ref_array_basic_test(void)
|
||||||
|
{
|
||||||
|
const char *line1 = "line1";
|
||||||
|
const char *line2 = "line2";
|
||||||
|
const char *line3 = "line3";
|
||||||
|
const char *line4 = "line4";
|
||||||
|
const char *line5 = "line5";
|
||||||
|
const char *line6 = "line6";
|
||||||
|
uint32_t i;
|
||||||
|
struct ref_array *ra;
|
||||||
|
struct ref_array *ra2;
|
||||||
|
int error = EOK;
|
||||||
|
uint32_t len = 0;
|
||||||
|
uint32_t other_len = 0;
|
||||||
|
char *ret;
|
||||||
|
char *elem;
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
error = ref_array_create(&ra, sizeof(char *), 1, NULL, NULL);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to create array %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(ref_array_debug(ra, 0));
|
||||||
|
|
||||||
|
error = ref_array_append(ra, &line1);
|
||||||
|
if (error) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Failed to append to array line 1 %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(ref_array_debug(ra, 0));
|
||||||
|
|
||||||
|
error = ref_array_append(ra, &line2);
|
||||||
|
if (error) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Failed to append to array line 2 %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(ref_array_debug(ra, 0));
|
||||||
|
|
||||||
|
error = ref_array_append(ra, &line3);
|
||||||
|
if (error) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Failed to append to array line 3 %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(ref_array_debug(ra, 0));
|
||||||
|
|
||||||
|
error = ref_array_append(ra, &line4);
|
||||||
|
if (error) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Failed to append to array line 4 %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(ref_array_debug(ra, 0));
|
||||||
|
|
||||||
|
error = ref_array_append(ra, &line5);
|
||||||
|
if (error) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Failed to append to array line 5 %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(ref_array_debug(ra, 0));
|
||||||
|
|
||||||
|
error = ref_array_append(ra, &line6);
|
||||||
|
if (error) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Failed to append to array line 6 %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(ref_array_debug(ra, 0));
|
||||||
|
|
||||||
|
RAOUT(printf("\n\nTest 1 - Printing lines.\n\n"));
|
||||||
|
|
||||||
|
error = ref_array_getlen(ra, &other_len);
|
||||||
|
if (error) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Failed to get length %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = ref_array_len(ra);
|
||||||
|
|
||||||
|
if (len != other_len) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Lengths do not match:\n");
|
||||||
|
printf("Len : %d\n", len);
|
||||||
|
printf("Get Len: %d\n", other_len);
|
||||||
|
return EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
ref_array_get(ra, i, &ret);
|
||||||
|
RAOUT(printf("%s\n", ret));
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(printf("\n\nTest 2 - Creating reference and then printing lines.\n\n"));
|
||||||
|
|
||||||
|
ra2 = ref_array_getref(ra);
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
ret = *((char **)ref_array_get(ra2, i, NULL));
|
||||||
|
RAOUT(printf("%s\n", ret));
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(printf("\n\nTest 3 - Get elements with copying.\n\n"));
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
ref_array_get(ra2, i, &ret);
|
||||||
|
RAOUT(printf("%s\n", ret));
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(printf("\n\nTest 4a - Get elements with copying and assignment.\n\n"));
|
||||||
|
|
||||||
|
/* This is a bad practice to use one variable
|
||||||
|
* as a parameter and as an acceptor for the return value.
|
||||||
|
* See next example for a better way to do it.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
ret = *((char **)ref_array_get(ra2, i, &ret));
|
||||||
|
RAOUT(printf("%s\n", ret));
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(printf("\n\nTest 4b - Get elements with copying and assignment.\n\n"));
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
ret = *((char **)ref_array_get(ra2, i, &elem));
|
||||||
|
RAOUT(printf("%s\n", ret));
|
||||||
|
RAOUT(printf("%s\n", elem));
|
||||||
|
if (strcmp(ret, elem) != 0) {
|
||||||
|
ref_array_destroy(ra2);
|
||||||
|
printf("\nRetrieved strings were expected to be same,\n");
|
||||||
|
printf("but they are not:\n");
|
||||||
|
printf("By pointer:[%s]\nAs element:[%s]\n", ret, elem);
|
||||||
|
return EFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(printf("\n\nTest 5 - While loop up.\n\n"));
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
for (;;) {
|
||||||
|
ptr = ref_array_get(ra2, i, &ret);
|
||||||
|
if (ptr) {
|
||||||
|
RAOUT(printf("%s\n", ret));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(printf("\n\nTest 6 - While loop down.\n\n"));
|
||||||
|
|
||||||
|
i = len - 1;
|
||||||
|
for (;;) {
|
||||||
|
ptr = ref_array_get(ra2, i, &ret);
|
||||||
|
if (ptr) {
|
||||||
|
RAOUT(printf("%s\n", ret));
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(printf("\n\nDone!!!\n\n"));
|
||||||
|
|
||||||
|
ref_array_destroy(ra2);
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void array_cleanup(void *elem,
|
||||||
|
ref_array_del_enum type,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
RAOUT(printf("%s%s\n", (char *)data, *((char **)elem)));
|
||||||
|
free(*((char **)elem));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free test */
|
||||||
|
static int ref_array_free_test(void)
|
||||||
|
{
|
||||||
|
const char *line1 = "line1";
|
||||||
|
const char *line2 = "line2";
|
||||||
|
const char *line3 = "line3";
|
||||||
|
const char *line4 = "line4";
|
||||||
|
char text[] = "Deleting: ";
|
||||||
|
char *str;
|
||||||
|
uint32_t i;
|
||||||
|
struct ref_array *ra;
|
||||||
|
int error = EOK;
|
||||||
|
char *ret;
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
error = ref_array_create(&ra, sizeof(char *), 1, array_cleanup, (char *)text);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to create array %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(ref_array_debug(ra, 0));
|
||||||
|
|
||||||
|
str = strdup(line1);
|
||||||
|
|
||||||
|
error = ref_array_append(ra, &str);
|
||||||
|
if (error) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Failed to append to array line 1 %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(ref_array_debug(ra, 0));
|
||||||
|
|
||||||
|
str = strdup(line2);
|
||||||
|
|
||||||
|
error = ref_array_append(ra, &str);
|
||||||
|
if (error) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Failed to append to array line 2 %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(ref_array_debug(ra, 0));
|
||||||
|
|
||||||
|
str = strdup(line3);
|
||||||
|
|
||||||
|
error = ref_array_append(ra, &str);
|
||||||
|
if (error) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Failed to append to array line 3 %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(ref_array_debug(ra, 0));
|
||||||
|
|
||||||
|
str = strdup(line4);
|
||||||
|
|
||||||
|
error = ref_array_append(ra, &str);
|
||||||
|
if (error) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Failed to append to array line 4 %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(ref_array_debug(ra, 0));
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
for (;;) {
|
||||||
|
ptr = ref_array_get(ra, i, &ret);
|
||||||
|
if (ptr) {
|
||||||
|
RAOUT(printf("%s\n", ret));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(printf("\n\nDone!!!\n\n"));
|
||||||
|
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ref_array_adv_test(void)
|
||||||
|
{
|
||||||
|
int error = EOK;
|
||||||
|
const char *lines[] = { "line0",
|
||||||
|
"line1",
|
||||||
|
"line2",
|
||||||
|
"line3",
|
||||||
|
"line4",
|
||||||
|
"line5",
|
||||||
|
"line6",
|
||||||
|
"line7",
|
||||||
|
"line8",
|
||||||
|
"line9" };
|
||||||
|
char text[] = "Deleting: ";
|
||||||
|
char *str;
|
||||||
|
uint32_t i;
|
||||||
|
struct ref_array *ra;
|
||||||
|
char *ret;
|
||||||
|
void *ptr;
|
||||||
|
int expected[] = { 0, 1, 7, 8, 9 };
|
||||||
|
int expected2[] = { 1, 7, 8, 9, 0 };
|
||||||
|
|
||||||
|
error = ref_array_create(&ra,
|
||||||
|
sizeof(char *),
|
||||||
|
1,
|
||||||
|
array_cleanup,
|
||||||
|
(char *)text);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to create array %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 5;i++) {
|
||||||
|
|
||||||
|
str = strdup(lines[i]);
|
||||||
|
|
||||||
|
error = ref_array_append(ra, &str);
|
||||||
|
if (error) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Failed to append line %d, error %d\n",
|
||||||
|
i, error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(printf("\nInitial array.\n"));
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
for (;;) {
|
||||||
|
ptr = ref_array_get(ra, i, &ret);
|
||||||
|
if (ptr) {
|
||||||
|
RAOUT(printf("%s\n", ret));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Try to remove invalid entry */
|
||||||
|
error = ref_array_remove(ra, 1000);
|
||||||
|
if (error != ERANGE) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Removing entry expected error got success.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try to insert invalid entry */
|
||||||
|
error = ref_array_insert(ra, 1000, &text);
|
||||||
|
if (error != ERANGE) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Inserting entry expected error got success.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try to replace invalid entry */
|
||||||
|
error = ref_array_replace(ra, 1000, &text);
|
||||||
|
if (error != ERANGE) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Replacing entry expected error got success.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Insert several entries */
|
||||||
|
for (i = 9; i > 4; i--) {
|
||||||
|
|
||||||
|
str = strdup(lines[i]);
|
||||||
|
|
||||||
|
error = ref_array_insert(ra, 9 - i, &str);
|
||||||
|
if (error) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
free(str);
|
||||||
|
printf("Failed to insert line %d, error %d\n",
|
||||||
|
i, error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Displpay array contents */
|
||||||
|
RAOUT(printf("\nArray with inserted values.\n"));
|
||||||
|
i = 0;
|
||||||
|
for (;;) {
|
||||||
|
ptr = ref_array_get(ra, i, &ret);
|
||||||
|
if (ptr) {
|
||||||
|
RAOUT(printf("%s\n", ret));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Replace everything */
|
||||||
|
for (i = 0; i < 10;i++) {
|
||||||
|
|
||||||
|
str = strdup(lines[i]);
|
||||||
|
|
||||||
|
error = ref_array_replace(ra, i, &str);
|
||||||
|
if (error) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
free(str);
|
||||||
|
printf("Failed to replace line %d, error %d\n",
|
||||||
|
i, error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Displpay array contents */
|
||||||
|
RAOUT(printf("\nArray with replaced values.\n"));
|
||||||
|
i = 0;
|
||||||
|
for (;;) {
|
||||||
|
ptr = ref_array_get(ra, i, &ret);
|
||||||
|
if (ptr) {
|
||||||
|
RAOUT(printf("%s\n", ret));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset */
|
||||||
|
ref_array_reset(ra);
|
||||||
|
|
||||||
|
/* Displpay array contents */
|
||||||
|
RAOUT(printf("\nEmpty array.\n"));
|
||||||
|
i = 0;
|
||||||
|
for (;;) {
|
||||||
|
ptr = ref_array_get(ra, i, &ret);
|
||||||
|
if (ptr) {
|
||||||
|
RAOUT(printf("%s\n", ret));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add everything */
|
||||||
|
for (i = 0; i < 10;i++) {
|
||||||
|
|
||||||
|
str = strdup(lines[i]);
|
||||||
|
|
||||||
|
error = ref_array_insert(ra, i, &str);
|
||||||
|
if (error) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
free(str);
|
||||||
|
printf("Failed to insert into array %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Displpay array contents */
|
||||||
|
RAOUT(printf("\nAll added back.\n"));
|
||||||
|
i = 0;
|
||||||
|
for (;;) {
|
||||||
|
ptr = ref_array_get(ra, i, &ret);
|
||||||
|
if (ptr) {
|
||||||
|
RAOUT(printf("%s\n", ret));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove part */
|
||||||
|
for (i = 0; i < 5;i++) {
|
||||||
|
|
||||||
|
error = ref_array_remove(ra, 2);
|
||||||
|
if (error) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Failed to remive item from array %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Displpay array contents */
|
||||||
|
RAOUT(printf("\nCleaned array.\n"));
|
||||||
|
i = 0;
|
||||||
|
for (;;) {
|
||||||
|
ptr = ref_array_get(ra, i, &ret);
|
||||||
|
if (ptr) {
|
||||||
|
RAOUT(printf("%s\n", ret));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(printf("\n\nChecking for expected contents\n\n"));
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
for (;;) {
|
||||||
|
ptr = ref_array_get(ra, i, &ret);
|
||||||
|
if (ptr) {
|
||||||
|
RAOUT(printf("Comparing:\n[%s]\n[%s]\n\n",
|
||||||
|
ret, lines[expected[i]]));
|
||||||
|
if (strcmp(ret, lines[expected[i]]) != 0) {
|
||||||
|
printf("Unexpected contents of the array.\n");
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(printf("\n\nSwap test\n\n"));
|
||||||
|
|
||||||
|
if ((error = ref_array_swap(ra, 0, 1)) ||
|
||||||
|
(error = ref_array_swap(ra, 1, 2)) ||
|
||||||
|
(error = ref_array_swap(ra, 2, 3)) ||
|
||||||
|
(error = ref_array_swap(ra, 3, 4))) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Failed to to swap %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
for (;;) {
|
||||||
|
ptr = ref_array_get(ra, i, &ret);
|
||||||
|
if (ptr) {
|
||||||
|
RAOUT(printf("Comparing:\n[%s]\n[%s]\n\n",
|
||||||
|
ret, lines[expected2[i]]));
|
||||||
|
if (strcmp(ret, lines[expected2[i]]) != 0) {
|
||||||
|
printf("Unexpected contents of the array.\n");
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(printf("\n\nDone!!!\n\n"));
|
||||||
|
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int copy_cb(void *elem,
|
||||||
|
void *new_elem)
|
||||||
|
{
|
||||||
|
char *ne = NULL;
|
||||||
|
|
||||||
|
ne = strdup(*((char **)elem));
|
||||||
|
*((char **)new_elem) = ne;
|
||||||
|
|
||||||
|
RAOUT(printf("Source: %s\nCopy:%s\n", *((char **)elem), ne));
|
||||||
|
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ref_array_copy_test(void)
|
||||||
|
{
|
||||||
|
const char *line1 = "line1";
|
||||||
|
const char *line2 = "line2";
|
||||||
|
const char *line3 = "line3";
|
||||||
|
const char *line4 = "line4";
|
||||||
|
const char *line5 = "line5";
|
||||||
|
const char *line6 = "line6";
|
||||||
|
uint32_t i;
|
||||||
|
struct ref_array *ra;
|
||||||
|
struct ref_array *ra2;
|
||||||
|
int error = EOK;
|
||||||
|
uint32_t len = 6;
|
||||||
|
char text[] = "Deleting: ";
|
||||||
|
|
||||||
|
error = ref_array_create(&ra, sizeof(char *), 1, NULL, NULL);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to create array %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(ref_array_debug(ra, 0));
|
||||||
|
|
||||||
|
error = ref_array_append(ra, &line1);
|
||||||
|
if (error) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Failed to append to array line 1 %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(ref_array_debug(ra, 0));
|
||||||
|
|
||||||
|
error = ref_array_append(ra, &line2);
|
||||||
|
if (error) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Failed to append to array line 2 %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(ref_array_debug(ra, 0));
|
||||||
|
|
||||||
|
error = ref_array_append(ra, &line3);
|
||||||
|
if (error) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Failed to append to array line 3 %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(ref_array_debug(ra, 0));
|
||||||
|
|
||||||
|
error = ref_array_append(ra, &line4);
|
||||||
|
if (error) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Failed to append to array line 4 %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(ref_array_debug(ra, 0));
|
||||||
|
|
||||||
|
error = ref_array_append(ra, &line5);
|
||||||
|
if (error) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Failed to append to array line 5 %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(ref_array_debug(ra, 0));
|
||||||
|
|
||||||
|
error = ref_array_append(ra, &line6);
|
||||||
|
if (error) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Failed to append to array line 6 %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(ref_array_debug(ra, 0));
|
||||||
|
|
||||||
|
RAOUT(printf("\n\nCopy lines.\n\n"));
|
||||||
|
|
||||||
|
error = ref_array_copy(ra, copy_cb, array_cleanup, (char *)text, &ra2);
|
||||||
|
if (error) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Failed to copy array %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
if (strcmp(*((char **)ref_array_get(ra, i, NULL)),
|
||||||
|
*((char **)ref_array_get(ra2, i, NULL))) != 0) {
|
||||||
|
printf("\nRetrieved strings were expected to be same,\n");
|
||||||
|
printf("but they are not:\n");
|
||||||
|
printf("First:[%s]\nSecond:[%s]\n",
|
||||||
|
*((char **)ref_array_get(ra, i, NULL)),
|
||||||
|
*((char **)ref_array_get(ra2, i, NULL)));
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
ref_array_destroy(ra2);
|
||||||
|
return EFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(printf("\n\nSource array.\n\n"));
|
||||||
|
RAOUT(ref_array_debug(ra, 0));
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
|
||||||
|
RAOUT(printf("\n\nAbout to destroy a copy.\n\n"));
|
||||||
|
RAOUT(ref_array_debug(ra2, 0));
|
||||||
|
ref_array_destroy(ra2);
|
||||||
|
|
||||||
|
RAOUT(printf("\n\nDone!!!\n\n"));
|
||||||
|
return EOK;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ref_array_copy_num_test(void)
|
||||||
|
{
|
||||||
|
uint32_t i,j,k;
|
||||||
|
struct ref_array *ra;
|
||||||
|
struct ref_array *ra2;
|
||||||
|
int error = EOK;
|
||||||
|
uint32_t len = 5;
|
||||||
|
|
||||||
|
error = ref_array_create(&ra, sizeof(uint32_t), 1, NULL, NULL);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to create array %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(ref_array_debug(ra, 1));
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
error = ref_array_append(ra, &i);
|
||||||
|
if (error) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Failed to append number to array %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(ref_array_debug(ra, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(printf("\n\nCopy num test.\n\n"));
|
||||||
|
|
||||||
|
error = ref_array_copy(ra, NULL, NULL, NULL, &ra2);
|
||||||
|
if (error) {
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
printf("Failed to copy array %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
j = *((uint32_t *)(ref_array_get(ra, i, NULL)));
|
||||||
|
k = *((uint32_t *)(ref_array_get(ra2, i, NULL)));
|
||||||
|
if (j != k) {
|
||||||
|
printf("\nRetrieved values were expected to be same,\n");
|
||||||
|
printf("but they are not:\n");
|
||||||
|
printf("First:[%d]\nSecond:[%d]\n", j, k);
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
ref_array_destroy(ra2);
|
||||||
|
return EFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ref_array_destroy(ra);
|
||||||
|
ref_array_destroy(ra2);
|
||||||
|
|
||||||
|
RAOUT(printf("\n\nDone!!!\n\n"));
|
||||||
|
return EOK;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Main function of the unit test */
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int error = 0;
|
||||||
|
test_fn tests[] = { ref_array_basic_test,
|
||||||
|
ref_array_free_test,
|
||||||
|
ref_array_adv_test,
|
||||||
|
ref_array_copy_test,
|
||||||
|
ref_array_copy_num_test,
|
||||||
|
NULL };
|
||||||
|
test_fn t;
|
||||||
|
int i = 0;
|
||||||
|
char *var;
|
||||||
|
|
||||||
|
if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = 1;
|
||||||
|
else {
|
||||||
|
var = getenv("COMMON_TEST_VERBOSE");
|
||||||
|
if (var) verbose = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(printf("Start\n"));
|
||||||
|
|
||||||
|
while ((t = tests[i++])) {
|
||||||
|
error = t();
|
||||||
|
if (error) {
|
||||||
|
RAOUT(printf("Failed with error %d!\n", error));
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RAOUT(printf("Success!\n"));
|
||||||
|
return 0;
|
||||||
|
}
|
145
tests/sanity/simplebuffer_ut.c
Normal file
145
tests/sanity/simplebuffer_ut.c
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
Simple buffer UNIT test
|
||||||
|
|
||||||
|
Basic buffer manipulation routines.
|
||||||
|
|
||||||
|
Copyright (C) Dmitri Pal <dpal@redhat.com> 2010
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#define TRACE_HOME
|
||||||
|
#include "trace.h"
|
||||||
|
#include "simplebuffer.h"
|
||||||
|
|
||||||
|
|
||||||
|
int verbose = 0;
|
||||||
|
|
||||||
|
#define BOOUT(foo) \
|
||||||
|
do { \
|
||||||
|
if (verbose) foo; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
static int simple_test(void)
|
||||||
|
{
|
||||||
|
int error = EOK;
|
||||||
|
struct simplebuffer *data = NULL;
|
||||||
|
char str1[] = "test string 1";
|
||||||
|
char str2[] = "test string 2";
|
||||||
|
const char str3[] = "test string 3";
|
||||||
|
uint32_t left = 0;
|
||||||
|
int i;
|
||||||
|
const unsigned char *buf;
|
||||||
|
|
||||||
|
BOOUT(printf("Simple test start.\n"));
|
||||||
|
|
||||||
|
error = simplebuffer_alloc(&data);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to allocate object %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = simplebuffer_add_raw(data,
|
||||||
|
(void *)str1,
|
||||||
|
strlen(str1),
|
||||||
|
1);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to add string to an object %d\n", error);
|
||||||
|
simplebuffer_free(data);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = simplebuffer_add_cr(data);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to add CR to an object %d\n", error);
|
||||||
|
simplebuffer_free(data);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = simplebuffer_add_raw(data,
|
||||||
|
(void *)str2,
|
||||||
|
strlen(str2),
|
||||||
|
1);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to add string to an object %d\n", error);
|
||||||
|
simplebuffer_free(data);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = simplebuffer_add_cr(data);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to add CR to an object %d\n", error);
|
||||||
|
simplebuffer_free(data);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = simplebuffer_add_str(data,
|
||||||
|
str3,
|
||||||
|
strlen(str3),
|
||||||
|
1);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to add string to an object %d\n", error);
|
||||||
|
simplebuffer_free(data);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
left = simplebuffer_get_len(data);
|
||||||
|
buf = simplebuffer_get_buf(data);
|
||||||
|
|
||||||
|
BOOUT(for(i = 0; i < left; i++) {
|
||||||
|
printf("%02d: %02X\n", i, buf[i]);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (verbose) {
|
||||||
|
while (left > 0) {
|
||||||
|
error = simplebuffer_write(1, data, &left);
|
||||||
|
if (error) {
|
||||||
|
printf("Failed to write to output %d\n", error);
|
||||||
|
simplebuffer_free(data);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOUT(printf("\n[%s]\n", simplebuffer_get_buf(data)));
|
||||||
|
BOOUT(printf("Length: %d\n", simplebuffer_get_len(data)));
|
||||||
|
|
||||||
|
|
||||||
|
simplebuffer_free(data);
|
||||||
|
|
||||||
|
BOOUT(printf("Simple test end.\n"));
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int error = EOK;
|
||||||
|
|
||||||
|
if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = 1;
|
||||||
|
|
||||||
|
BOOUT(printf("Start\n"));
|
||||||
|
|
||||||
|
if ((error = simple_test())) {
|
||||||
|
printf("Test failed! Error %d.\n", error);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOUT(printf("Success!\n"));
|
||||||
|
return 0;
|
||||||
|
}
|
175
tests/sanity/trace.h
Normal file
175
tests/sanity/trace.h
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
/*
|
||||||
|
COMMON TRACE
|
||||||
|
|
||||||
|
Common header file for tracing.
|
||||||
|
|
||||||
|
Copyright (C) Dmitri Pal <dpal@redhat.com> 2009
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef COMMON_TRACE_H
|
||||||
|
#define COMMON_TRACE_H
|
||||||
|
|
||||||
|
#ifdef TRACE_LEVEL
|
||||||
|
#define HAVE_TRACE
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* The trace level is a bit mask */
|
||||||
|
#define TRACE_FLOW 0x0000001 /* - trace messages that are entry exit into functions */
|
||||||
|
#define TRACE_ERROR 0x0000002 /* - trace messages that are errors */
|
||||||
|
#define TRACE_INFO 0x0000004 /* - trace things that are informational */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef TRACE_HOME /* Define this in the module that contains main */
|
||||||
|
unsigned trace_level = TRACE_LEVEL;
|
||||||
|
#else
|
||||||
|
extern unsigned trace_level;
|
||||||
|
#endif /* TRACE_HOME */
|
||||||
|
#endif /* TRACE_LEVEL */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_TRACE
|
||||||
|
/* Tracing strings */
|
||||||
|
#define TRACE_STRING(level, msg, str) \
|
||||||
|
do { \
|
||||||
|
if (level & trace_level) { \
|
||||||
|
printf("[DEBUG] %40s (%4d) %s%s %s\n", \
|
||||||
|
__FILE__, __LINE__, \
|
||||||
|
(level == TRACE_ERROR) ? "ERROR-> " : "", \
|
||||||
|
(msg != NULL) ? msg : "MISSING MESSAGE", \
|
||||||
|
(str != NULL) ? str : "(null)"); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
/* Tracing unsigned numbers */
|
||||||
|
#define TRACE_NUMBER(level, msg, num) \
|
||||||
|
do { \
|
||||||
|
if (level & trace_level) { \
|
||||||
|
printf("[DEBUG] %40s (%4d) %s%s %lu\n", \
|
||||||
|
__FILE__, __LINE__, \
|
||||||
|
(level == TRACE_ERROR) ? "ERROR-> " : "", \
|
||||||
|
(msg != NULL) ? msg : "MISSING MESSAGE", \
|
||||||
|
(unsigned long int)(num)); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
/* Tracing signed numbers */
|
||||||
|
#define TRACE_SNUMBER(level, msg, num) \
|
||||||
|
do { \
|
||||||
|
if (level & trace_level) { \
|
||||||
|
printf("[DEBUG] %40s (%4d) %s%s %ld\n", \
|
||||||
|
__FILE__, __LINE__, \
|
||||||
|
(level == TRACE_ERROR) ? "ERROR-> " : "", \
|
||||||
|
(msg != NULL) ? msg : "MISSING MESSAGE", \
|
||||||
|
(long int)(num)); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
/* Tracing long numbers */
|
||||||
|
#define TRACE_LNUMBER(level, msg, num) \
|
||||||
|
do { \
|
||||||
|
if (level & trace_level) { \
|
||||||
|
printf("[DEBUG] %40s (%4d) %s%s %llu\n", \
|
||||||
|
__FILE__, __LINE__, \
|
||||||
|
(level == TRACE_ERROR) ? "ERROR-> " : "", \
|
||||||
|
(msg != NULL) ? msg : "MISSING MESSAGE", \
|
||||||
|
(unsigned long long int)(num)); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
/* Tracing signed long numbers */
|
||||||
|
#define TRACE_SLNUMBER(level, msg, num) \
|
||||||
|
do { \
|
||||||
|
if (level & trace_level) { \
|
||||||
|
printf("[DEBUG] %40s (%4d) %s%s %lld\n", \
|
||||||
|
__FILE__, __LINE__, \
|
||||||
|
(level == TRACE_ERROR) ? "ERROR-> " : "", \
|
||||||
|
(msg != NULL) ? msg : "MISSING MESSAGE", \
|
||||||
|
(long long int)(num)); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
/* Tracing doubles */
|
||||||
|
#define TRACE_DOUBLE(level, msg, num) \
|
||||||
|
do { \
|
||||||
|
if (level & trace_level) { \
|
||||||
|
printf("[DEBUG] %40s (%4d) %s%s %e\n", \
|
||||||
|
__FILE__, __LINE__, \
|
||||||
|
(level == TRACE_ERROR) ? "ERROR-> " : "", \
|
||||||
|
(msg != NULL) ? msg : "MISSING MESSAGE", \
|
||||||
|
(double)(num)); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define TRACE_RETURN(flow, val) \
|
||||||
|
do { \
|
||||||
|
char mstr[200]; \
|
||||||
|
sprintf(mstr, "%s returning:", __FUNCTION__); \
|
||||||
|
flow(mstr, val); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
/* Assertion */
|
||||||
|
#define TRACE_ASSERT(expression) expression ? : printf("ASSERTION FAILED\n")
|
||||||
|
#else /* HAVE_TRACE */
|
||||||
|
|
||||||
|
/* Noop in case the tracing is disabled */
|
||||||
|
#define TRACE_STRING(level, msg, str)
|
||||||
|
#define TRACE_NUMBER(level, msg, num)
|
||||||
|
#define TRACE_SNUMBER(level, msg, num)
|
||||||
|
#define TRACE_LNUMBER(level, msg, num)
|
||||||
|
#define TRACE_SLNUMBER(level, msg, num)
|
||||||
|
#define TRACE_DOUBLE(level, msg, num)
|
||||||
|
#define TRACE_RETURN(flow, val)
|
||||||
|
#define TRACE_ASSERT(expression)
|
||||||
|
#endif /* HAVE_TRACE */
|
||||||
|
|
||||||
|
|
||||||
|
/* Convenience wrappers for strings */
|
||||||
|
#define TRACE_FLOW_STRING(msg, str) TRACE_STRING(TRACE_FLOW, msg, str)
|
||||||
|
#define TRACE_ERROR_STRING(msg, str) TRACE_STRING(TRACE_ERROR, msg, str)
|
||||||
|
#define TRACE_INFO_STRING(msg, str) TRACE_STRING(TRACE_INFO, msg, str)
|
||||||
|
|
||||||
|
/* Convenience wrappers for unsigned numbers */
|
||||||
|
#define TRACE_FLOW_NUMBER(msg, num) TRACE_NUMBER(TRACE_FLOW, msg, num)
|
||||||
|
#define TRACE_ERROR_NUMBER(msg, num) TRACE_NUMBER(TRACE_ERROR, msg, num)
|
||||||
|
#define TRACE_INFO_NUMBER(msg, num) TRACE_NUMBER(TRACE_INFO, msg, num)
|
||||||
|
|
||||||
|
/* Convenience wrappers for signed numbers */
|
||||||
|
#define TRACE_FLOW_SNUMBER(msg, num) TRACE_SNUMBER(TRACE_FLOW, msg, num)
|
||||||
|
#define TRACE_ERROR_SNUMBER(msg, num) TRACE_SNUMBER(TRACE_ERROR, msg, num)
|
||||||
|
#define TRACE_INFO_SNUMBER(msg, num) TRACE_SNUMBER(TRACE_INFO, msg, num)
|
||||||
|
|
||||||
|
/* Convenience wrappers for 64-bit long unsigned numbers */
|
||||||
|
#define TRACE_FLOW_LNUMBER(msg, num) TRACE_LNUMBER(TRACE_FLOW, msg, num)
|
||||||
|
#define TRACE_ERROR_LNUMBER(msg, num) TRACE_LNUMBER(TRACE_ERROR, msg, num)
|
||||||
|
#define TRACE_INFO_LNUMBER(msg, num) TRACE_LNUMBER(TRACE_INFO, msg, num)
|
||||||
|
|
||||||
|
/* Convenience wrappers for 64-bit long signed numbers */
|
||||||
|
#define TRACE_FLOW_SLNUMBER(msg, num) TRACE_SLNUMBER(TRACE_FLOW, msg, num)
|
||||||
|
#define TRACE_ERROR_SLNUMBER(msg, num) TRACE_SLNUMBER(TRACE_ERROR, msg, num)
|
||||||
|
#define TRACE_INFO_SLNUMBER(msg, num) TRACE_SLNUMBER(TRACE_INFO, msg, num)
|
||||||
|
|
||||||
|
/* Convenience wrappers for numbers */
|
||||||
|
#define TRACE_FLOW_DOUBLE(msg, num) TRACE_DOUBLE(TRACE_FLOW, msg, num)
|
||||||
|
#define TRACE_ERROR_DOUBLE(msg, num) TRACE_DOUBLE(TRACE_ERROR, msg, num)
|
||||||
|
#define TRACE_INFO_DOUBLE(msg, num) TRACE_DOUBLE(TRACE_INFO, msg, num)
|
||||||
|
|
||||||
|
/* Some other nice wrappers for function entry and exit */
|
||||||
|
#define TRACE_FLOW_ENTRY() TRACE_FLOW_STRING(__FUNCTION__, "Entry")
|
||||||
|
#define TRACE_FLOW_EXIT() TRACE_FLOW_STRING(__FUNCTION__, "Exit")
|
||||||
|
#define TRACE_FLOW_RETURN(val) TRACE_RETURN(TRACE_FLOW_NUMBER, val)
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* COMMON_TRACE_H */
|
28
tests/tests.yml
Normal file
28
tests/tests.yml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
- hosts: localhost
|
||||||
|
roles:
|
||||||
|
- role: standard-test-basic
|
||||||
|
tags:
|
||||||
|
- classic
|
||||||
|
tests:
|
||||||
|
- sanity:
|
||||||
|
dir: sanity
|
||||||
|
run: ./ding-libs-tests.sh
|
||||||
|
required_packages:
|
||||||
|
- check
|
||||||
|
- check-devel
|
||||||
|
- libbasicobjects
|
||||||
|
- libbasicobjects-devel
|
||||||
|
- libref_array
|
||||||
|
- libref_array-devel
|
||||||
|
- libcollection
|
||||||
|
- libcollection-devel
|
||||||
|
- libdhash
|
||||||
|
- libdhash-devel
|
||||||
|
- libconfig
|
||||||
|
- libconfig-devel
|
||||||
|
- libini_config
|
||||||
|
- libini_config-devel
|
||||||
|
- libpath_utils
|
||||||
|
- libpath_utils-devel
|
||||||
|
- make
|
||||||
|
- gcc
|
Loading…
Reference in New Issue
Block a user