ding-libs/tests/sanity/ref_array_ut.c
Steeve Goveas f8513f5719 Enable gating for ding-libs
Resolves: rhbz#1962772

sssd-team is added as a recipient
2021-05-28 21:10:08 +05:30

776 lines
19 KiB
C

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