unit-tests: Move test suites to its own subfolder
This commit is contained in:
@@ -0,0 +1,360 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Martin Willi
|
||||
* Copyright (C) 2013 revosec AG
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_suite.h"
|
||||
|
||||
#include <collections/array.h>
|
||||
|
||||
START_TEST(test_append_ptr)
|
||||
{
|
||||
array_t *array;
|
||||
uintptr_t x;
|
||||
int i;
|
||||
|
||||
array = array_create(0, 0);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
ck_assert_int_eq(array_count(array), 0);
|
||||
|
||||
array_insert(array, ARRAY_HEAD, (void*)(uintptr_t)3);
|
||||
array_insert(array, ARRAY_TAIL, (void*)(uintptr_t)4);
|
||||
ck_assert_int_eq(array_count(array), 2);
|
||||
|
||||
/* 3, 4 */
|
||||
|
||||
array_insert(array, ARRAY_HEAD, (void*)(uintptr_t)1);
|
||||
array_insert(array, 1, (void*)(uintptr_t)2);
|
||||
ck_assert_int_eq(array_count(array), 4);
|
||||
|
||||
/* 1, 2, 3, 4 */
|
||||
|
||||
array_insert(array, ARRAY_TAIL, (void*)(uintptr_t)5);
|
||||
array_insert(array, ARRAY_HEAD, (void*)(uintptr_t)0);
|
||||
ck_assert_int_eq(array_count(array), 6);
|
||||
|
||||
/* 0, 1, 2, 3, 4, 5 */
|
||||
|
||||
ck_assert(array_remove(array, ARRAY_TAIL, &x));
|
||||
ck_assert_int_eq(x, 5);
|
||||
ck_assert(array_remove(array, 4, &x));
|
||||
ck_assert_int_eq(x, 4);
|
||||
|
||||
if (i < 3)
|
||||
{
|
||||
array_compress(array);
|
||||
}
|
||||
|
||||
/* 0, 1, 2, 3 */
|
||||
|
||||
ck_assert(array_remove(array, 1, &x));
|
||||
ck_assert_int_eq(x, 1);
|
||||
ck_assert(array_remove(array, ARRAY_HEAD, &x));
|
||||
ck_assert_int_eq(x, 0);
|
||||
|
||||
if (i < 2)
|
||||
{
|
||||
array_compress(array);
|
||||
}
|
||||
|
||||
/* 2, 3 */
|
||||
|
||||
ck_assert(array_remove(array, ARRAY_TAIL, &x));
|
||||
ck_assert_int_eq(x, 3);
|
||||
ck_assert(array_remove(array, ARRAY_TAIL, &x));
|
||||
ck_assert_int_eq(x, 2);
|
||||
|
||||
if (i < 1)
|
||||
{
|
||||
array_compress(array);
|
||||
}
|
||||
|
||||
ck_assert_int_eq(array_count(array), 0);
|
||||
|
||||
ck_assert(array_remove(array, ARRAY_HEAD, NULL) == FALSE);
|
||||
ck_assert(array_remove(array, ARRAY_TAIL, NULL) == FALSE);
|
||||
}
|
||||
|
||||
array_destroy(array);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_append_obj)
|
||||
{
|
||||
array_t *array;
|
||||
int i, x, y[6] = {0, 1, 2, 3, 4, 5};
|
||||
|
||||
array = array_create(sizeof(y[0]), 0);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
ck_assert_int_eq(array_count(array), 0);
|
||||
|
||||
array_insert(array, ARRAY_HEAD, &y[3]);
|
||||
array_insert(array, ARRAY_TAIL, &y[4]);
|
||||
ck_assert_int_eq(array_count(array), 2);;
|
||||
|
||||
/* 3, 4 */
|
||||
|
||||
array_insert(array, ARRAY_HEAD, &y[1]);
|
||||
array_insert(array, 1, &y[2]);
|
||||
ck_assert_int_eq(array_count(array), 4);
|
||||
|
||||
/* 1, 2, 3, 4 */
|
||||
|
||||
array_insert(array, ARRAY_TAIL, &y[5]);
|
||||
array_insert(array, ARRAY_HEAD, &y[0]);
|
||||
ck_assert_int_eq(array_count(array), 6);
|
||||
|
||||
/* 0, 1, 2, 3, 4, 5 */
|
||||
|
||||
ck_assert(array_remove(array, ARRAY_TAIL, &x));
|
||||
ck_assert_int_eq(x, 5);
|
||||
ck_assert(array_remove(array, 4, &x));
|
||||
ck_assert_int_eq(x, 4);
|
||||
|
||||
if (i < 3)
|
||||
{
|
||||
array_compress(array);
|
||||
}
|
||||
|
||||
/* 0, 1, 2, 3 */
|
||||
|
||||
ck_assert(array_remove(array, ARRAY_HEAD, &x));
|
||||
ck_assert_int_eq(x, 0);
|
||||
ck_assert(array_remove(array, ARRAY_HEAD, &x));
|
||||
ck_assert_int_eq(x, 1);
|
||||
|
||||
if (i < 2)
|
||||
{
|
||||
array_compress(array);
|
||||
}
|
||||
|
||||
/* 2, 3 */
|
||||
|
||||
ck_assert(array_remove(array, ARRAY_TAIL, &x));
|
||||
ck_assert_int_eq(x, 3);
|
||||
ck_assert(array_remove(array, ARRAY_HEAD, &x));
|
||||
ck_assert_int_eq(x, 2);
|
||||
|
||||
if (i < 1)
|
||||
{
|
||||
array_compress(array);
|
||||
}
|
||||
|
||||
ck_assert_int_eq(array_count(array), 0);
|
||||
|
||||
ck_assert(array_remove(array, ARRAY_HEAD, NULL) == FALSE);
|
||||
ck_assert(array_remove(array, ARRAY_TAIL, NULL) == FALSE);
|
||||
}
|
||||
|
||||
array_destroy(array);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_enumerate)
|
||||
{
|
||||
array_t *array;
|
||||
int i, *x, y[6] = {0, 1, 2, 3, 4, 5};
|
||||
enumerator_t *enumerator;
|
||||
|
||||
array = array_create(sizeof(y[0]), 0);
|
||||
|
||||
array_insert(array, ARRAY_TAIL, &y[0]);
|
||||
array_insert(array, ARRAY_TAIL, &y[1]);
|
||||
array_insert(array, ARRAY_TAIL, &y[2]);
|
||||
array_insert(array, ARRAY_TAIL, &y[3]);
|
||||
array_insert(array, ARRAY_TAIL, &y[4]);
|
||||
array_insert(array, ARRAY_TAIL, &y[5]);
|
||||
|
||||
ck_assert_int_eq(array_count(array), 6);
|
||||
|
||||
/* 0, 1, 2, 3, 4, 5 */
|
||||
|
||||
i = 0;
|
||||
enumerator = array_create_enumerator(array);
|
||||
while (enumerator->enumerate(enumerator, &x))
|
||||
{
|
||||
ck_assert_int_eq(*x, y[i]);
|
||||
i++;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
ck_assert_int_eq(i, 6);
|
||||
|
||||
i = 0;
|
||||
enumerator = array_create_enumerator(array);
|
||||
while (enumerator->enumerate(enumerator, &x))
|
||||
{
|
||||
ck_assert_int_eq(*x, y[i]);
|
||||
if (i == 0 || i == 3 || i == 5)
|
||||
{
|
||||
array_remove_at(array, enumerator);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
ck_assert_int_eq(i, 6);
|
||||
ck_assert_int_eq(array_count(array), 3);
|
||||
|
||||
/* 1, 2, 4 */
|
||||
|
||||
i = 0;
|
||||
enumerator = array_create_enumerator(array);
|
||||
while (enumerator->enumerate(enumerator, &x))
|
||||
{
|
||||
switch (i++)
|
||||
{
|
||||
case 0:
|
||||
ck_assert_int_eq(*x, y[1]);
|
||||
break;
|
||||
case 1:
|
||||
ck_assert_int_eq(*x, y[2]);
|
||||
break;
|
||||
case 2:
|
||||
ck_assert_int_eq(*x, y[4]);
|
||||
break;
|
||||
default:
|
||||
ck_assert(0);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
array_compress(array);
|
||||
|
||||
i = 0;
|
||||
enumerator = array_create_enumerator(array);
|
||||
while (enumerator->enumerate(enumerator, &x))
|
||||
{
|
||||
switch (i++)
|
||||
{
|
||||
case 0:
|
||||
ck_assert_int_eq(*x, y[1]);
|
||||
break;
|
||||
case 1:
|
||||
ck_assert_int_eq(*x, y[2]);
|
||||
break;
|
||||
case 2:
|
||||
ck_assert_int_eq(*x, y[4]);
|
||||
break;
|
||||
default:
|
||||
ck_assert(0);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
array_destroy(array);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static void invoke(void *data, int idx, void *user)
|
||||
{
|
||||
int *y = user, *x = data;
|
||||
|
||||
ck_assert(idx < 3);
|
||||
|
||||
ck_assert_int_eq(y[idx], *x);
|
||||
y[idx] = 0;
|
||||
}
|
||||
|
||||
START_TEST(test_invoke)
|
||||
{
|
||||
array_t *array;
|
||||
int y[] = {1, 2, 3};
|
||||
|
||||
array = array_create(sizeof(y[0]), 0);
|
||||
|
||||
array_insert(array, ARRAY_TAIL, &y[0]);
|
||||
array_insert(array, ARRAY_TAIL, &y[1]);
|
||||
array_insert(array, ARRAY_TAIL, &y[2]);
|
||||
|
||||
array_invoke(array, invoke, y);
|
||||
|
||||
ck_assert_int_eq(y[0], 0);
|
||||
ck_assert_int_eq(y[0], 0);
|
||||
ck_assert_int_eq(y[0], 0);
|
||||
|
||||
array_destroy(array);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
typedef struct obj_t obj_t;
|
||||
|
||||
struct obj_t {
|
||||
void (*fun)(obj_t *obj);
|
||||
int x;
|
||||
int *counter;
|
||||
};
|
||||
|
||||
static void fun(obj_t *obj)
|
||||
{
|
||||
ck_assert(obj->x == (*obj->counter)++);
|
||||
}
|
||||
|
||||
START_TEST(test_invoke_offset)
|
||||
{
|
||||
array_t *array;
|
||||
obj_t objs[5];
|
||||
int i, counter = 0;
|
||||
|
||||
array = array_create(0, 0);
|
||||
|
||||
for (i = 0; i < countof(objs); i++)
|
||||
{
|
||||
objs[i].x = i;
|
||||
objs[i].counter = &counter;
|
||||
objs[i].fun = fun;
|
||||
|
||||
array_insert(array, ARRAY_TAIL, &objs[i]);
|
||||
}
|
||||
|
||||
ck_assert_int_eq(countof(objs), array_count(array));
|
||||
|
||||
array_invoke_offset(array, offsetof(obj_t, fun));
|
||||
|
||||
ck_assert_int_eq(counter, countof(objs));
|
||||
|
||||
array_destroy(array);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *array_suite_create()
|
||||
{
|
||||
Suite *s;
|
||||
TCase *tc;
|
||||
|
||||
s = suite_create("array");
|
||||
|
||||
tc = tcase_create("add/remove ptr");
|
||||
tcase_add_test(tc, test_append_ptr);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("add/remove obj");
|
||||
tcase_add_test(tc, test_append_obj);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("enumerate");
|
||||
tcase_add_test(tc, test_enumerate);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("invoke");
|
||||
tcase_add_test(tc, test_invoke);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("invoke offset");
|
||||
tcase_add_test(tc, test_invoke_offset);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,840 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "test_suite.h"
|
||||
|
||||
#include <asn1/asn1.h>
|
||||
#include <asn1/oid.h>
|
||||
#include <utils/chunk.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* algorithm_identifier
|
||||
*/
|
||||
|
||||
START_TEST(test_asn1_algorithmIdentifier)
|
||||
{
|
||||
typedef struct {
|
||||
int n;
|
||||
chunk_t algid;
|
||||
} testdata_t;
|
||||
|
||||
testdata_t test[] = {
|
||||
{ OID_ECDSA_WITH_SHA1, chunk_from_chars(0x30, 0x09, 0x06, 0x07,
|
||||
0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01) },
|
||||
{ OID_SHA1_WITH_RSA, chunk_from_chars(0x30, 0x0d, 0x06, 0x09,
|
||||
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00) },
|
||||
};
|
||||
|
||||
chunk_t algid;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < countof(test); i++)
|
||||
{
|
||||
algid = asn1_algorithmIdentifier(test[i].n);
|
||||
ck_assert(chunk_equals(algid, test[i].algid));
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* parse_algorithm_identifier
|
||||
*/
|
||||
|
||||
START_TEST(test_asn1_parse_algorithmIdentifier)
|
||||
{
|
||||
typedef struct {
|
||||
int alg;
|
||||
bool empty;
|
||||
chunk_t parameters;
|
||||
} testdata_t;
|
||||
|
||||
testdata_t test[] = {
|
||||
{ OID_ECDSA_WITH_SHA1, TRUE, chunk_empty },
|
||||
{ OID_SHA1_WITH_RSA, TRUE, chunk_from_chars(0x05, 0x00) },
|
||||
{ OID_3DES_EDE_CBC, FALSE, chunk_from_chars(0x04, 0x01, 0xaa) },
|
||||
{ OID_PBKDF2, FALSE, chunk_from_chars(0x30, 0x01, 0xaa) }
|
||||
};
|
||||
|
||||
chunk_t algid, parameters;
|
||||
int i, alg;
|
||||
|
||||
for (i = 0; i < countof(test); i++)
|
||||
{
|
||||
algid = asn1_wrap(ASN1_SEQUENCE, "mc",
|
||||
asn1_build_known_oid(test[i].alg), test[i].parameters);
|
||||
parameters = chunk_empty;
|
||||
if (i == 2)
|
||||
{
|
||||
alg = asn1_parse_algorithmIdentifier(algid, 0, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
alg = asn1_parse_algorithmIdentifier(algid, 0, ¶meters);
|
||||
if (test[i].empty)
|
||||
{
|
||||
ck_assert(parameters.len == 0 && parameters.ptr == NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
ck_assert(chunk_equals(parameters, test[i].parameters));
|
||||
}
|
||||
}
|
||||
ck_assert(alg == test[i].alg);
|
||||
chunk_free(&algid);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* known_oid
|
||||
*/
|
||||
|
||||
START_TEST(test_asn1_known_oid)
|
||||
{
|
||||
typedef struct {
|
||||
int n;
|
||||
chunk_t oid;
|
||||
} testdata_t;
|
||||
|
||||
testdata_t test[] = {
|
||||
{ OID_UNKNOWN, chunk_empty },
|
||||
{ OID_UNKNOWN, chunk_from_chars(0x55, 0x04, 0x02) },
|
||||
{ OID_COUNTRY, chunk_from_chars(0x55, 0x04, 0x06) },
|
||||
{ OID_STRONGSWAN, chunk_from_chars(0x2b, 0x06, 0x01, 0x04, 0x01,
|
||||
0x82, 0xa0, 0x2a, 0x01) }
|
||||
};
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < countof(test); i++)
|
||||
{
|
||||
ck_assert(asn1_known_oid(test[i].oid) == test[i].n);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* build_known_oid
|
||||
*/
|
||||
|
||||
START_TEST(test_asn1_build_known_oid)
|
||||
{
|
||||
typedef struct {
|
||||
int n;
|
||||
chunk_t oid;
|
||||
} testdata_t;
|
||||
|
||||
testdata_t test[] = {
|
||||
{ OID_UNKNOWN, chunk_empty },
|
||||
{ OID_MAX, chunk_empty },
|
||||
{ OID_COUNTRY, chunk_from_chars(0x06, 0x03, 0x55, 0x04, 0x06) },
|
||||
{ OID_STRONGSWAN, chunk_from_chars(0x06, 0x09, 0x2b, 0x06, 0x01, 0x04,
|
||||
0x01, 0x82, 0xa0, 0x2a, 0x01) }
|
||||
};
|
||||
|
||||
int i;
|
||||
chunk_t oid = chunk_empty;
|
||||
|
||||
for (i = 0; i < countof(test); i++)
|
||||
{
|
||||
oid = asn1_build_known_oid(test[i].n);
|
||||
if (test[i].oid.len == 0)
|
||||
{
|
||||
ck_assert(oid.len == 0 && oid.ptr == NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
ck_assert(chunk_equals(oid, test[i].oid));
|
||||
chunk_free(&oid);
|
||||
}
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* oid_from_string
|
||||
*/
|
||||
|
||||
START_TEST(test_asn1_oid_from_string)
|
||||
{
|
||||
typedef struct {
|
||||
char *string;
|
||||
chunk_t oid;
|
||||
} testdata_t;
|
||||
|
||||
testdata_t test[] = {
|
||||
{ "", chunk_empty },
|
||||
{ " ", chunk_empty },
|
||||
{ "0.2.262.1", chunk_from_chars(
|
||||
0x02, 0x82, 0x06, 0x01) },
|
||||
{ "1.2.840.10045.4.1", chunk_from_chars(
|
||||
0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01) },
|
||||
{ "1.3.6.1.4.1.36906.1", chunk_from_chars(
|
||||
0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa0, 0x2a, 0x01) },
|
||||
{ "2.16.840.1.101.3.4.2.1", chunk_from_chars(
|
||||
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01) },
|
||||
{ "0.10.100.1000.10000.100000.1000000.10000000.100000000.268435455",
|
||||
chunk_from_chars(0x0a,0x64, 0x87, 0x68, 0xce, 0x10, 0x86, 0x8d,
|
||||
0x20, 0xbd, 0x84, 0x40, 0x84, 0xe2, 0xad, 0x00,
|
||||
0xaf, 0xd7, 0xc2, 0x00, 0xff, 0xff, 0xff, 0x7f) },
|
||||
{ "0.1.2.3.4.5.6.7.8.9.10.128.129.130.131.132.133.134.135.136.137."
|
||||
"256.257.258.259.260.261.262.263.264.265.384.385.386.387.388."
|
||||
"2097153", chunk_from_chars(
|
||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
|
||||
0x81, 0x00, 0x81, 0x01, 0x81, 0x02, 0x81, 0x03, 0x81, 0x04,
|
||||
0x81, 0x05, 0x81, 0x06, 0x81, 0x07, 0x81, 0x08, 0x81, 0x09,
|
||||
0x82, 0x00, 0x82, 0x01, 0x82, 0x02, 0x82, 0x03, 0x82, 0x04,
|
||||
0x82, 0x05, 0x82, 0x06, 0x82, 0x07, 0x82, 0x08, 0x82, 0x09,
|
||||
0x83, 0x00, 0x83, 0x01, 0x83, 0x02, 0x83, 0x03, 0x83, 0x04,
|
||||
0x81, 0x80, 0x80, 0x01) },
|
||||
{ "0.1.2.3.4.5.6.7.8.9.10.128.129.130.131.132.133.134.135.136.137."
|
||||
"256.257.258.259.260.261.262.263.264.265.384.385.386.387.388."
|
||||
"1.2097153", chunk_empty },
|
||||
{ "1.a.2.b.3", chunk_empty }
|
||||
};
|
||||
|
||||
int i;
|
||||
chunk_t oid = chunk_empty;
|
||||
|
||||
for (i = 0; i < countof(test); i++)
|
||||
{
|
||||
oid = asn1_oid_from_string(test[i].string);
|
||||
if (test[i].oid.len == 0)
|
||||
{
|
||||
ck_assert(oid.len == 0 && oid.ptr == NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
ck_assert(chunk_equals(oid, test[i].oid));
|
||||
chunk_free(&oid);
|
||||
}
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* oid_to_string
|
||||
*/
|
||||
|
||||
START_TEST(test_asn1_oid_to_string)
|
||||
{
|
||||
typedef struct {
|
||||
char *string;
|
||||
chunk_t oid;
|
||||
} testdata_t;
|
||||
|
||||
testdata_t test[] = {
|
||||
{ NULL, chunk_empty },
|
||||
{ "0.2.262.1", chunk_from_chars(
|
||||
0x02, 0x82, 0x06, 0x01) },
|
||||
{ "1.2.840.10045.4.1", chunk_from_chars(
|
||||
0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01) },
|
||||
{ "1.3.6.1.4.1.36906.1", chunk_from_chars(
|
||||
0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa0, 0x2a, 0x01) },
|
||||
{ "2.16.840.1.101.3.4.2.1", chunk_from_chars(
|
||||
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01) },
|
||||
{ "0.10.100.1000.10000.100000.1000000.10000000.100000000.268435455",
|
||||
chunk_from_chars( 0x0a, 0x64, 0x87, 0x68, 0xce, 0x10, 0x86, 0x8d,
|
||||
0x20, 0xbd, 0x84, 0x40, 0x84, 0xe2, 0xad, 0x00,
|
||||
0xaf, 0xd7, 0xc2, 0x00, 0xff, 0xff, 0xff, 0x7f) },
|
||||
{ NULL, chunk_from_chars(
|
||||
0x0a, 0x02, 0x64, 0x87, 0x68, 0xce, 0x10, 0x86, 0x8d, 0x20,
|
||||
0xbd, 0x84, 0x40, 0x84, 0xe2, 0xad, 0x00, 0xaf, 0xd7, 0xc2, 0x00,
|
||||
0xff, 0xff, 0xff, 0x7f) },
|
||||
{ NULL, chunk_from_chars(0x0a, 0x87) }
|
||||
};
|
||||
|
||||
int i;
|
||||
char *string = NULL;
|
||||
|
||||
for (i = 0; i < countof(test); i++)
|
||||
{
|
||||
string = asn1_oid_to_string(test[i].oid);
|
||||
if (test[i].string == NULL)
|
||||
{
|
||||
ck_assert(string == NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
ck_assert(streq(string, test[i].string));
|
||||
free(string);
|
||||
}
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* length
|
||||
*/
|
||||
|
||||
START_TEST(test_asn1_length)
|
||||
{
|
||||
chunk_t a;
|
||||
|
||||
a = chunk_empty;
|
||||
ck_assert(asn1_length(&a) == ASN1_INVALID_LENGTH);
|
||||
|
||||
a = chunk_from_chars(0x04);
|
||||
ck_assert(asn1_length(&a) == ASN1_INVALID_LENGTH);
|
||||
|
||||
a = chunk_from_chars(0x04, 0x00);
|
||||
ck_assert(asn1_length(&a) == 0);
|
||||
|
||||
a = chunk_from_chars(0x04, 0x01);
|
||||
ck_assert(asn1_length(&a) == ASN1_INVALID_LENGTH);
|
||||
|
||||
a = chunk_from_chars(0x04, 0x01, 0xaa);
|
||||
ck_assert(asn1_length(&a) == 1);
|
||||
|
||||
a = chunk_from_chars(0x04, 0x7f, 0xaa);
|
||||
a.len = 2 + 127;
|
||||
ck_assert(asn1_length(&a) == 127);
|
||||
|
||||
a = chunk_from_chars(0x04, 0x80, 0xaa);
|
||||
a.len = 2 + 128;
|
||||
ck_assert(asn1_length(&a) == ASN1_INVALID_LENGTH);
|
||||
|
||||
a = chunk_from_chars(0x04, 0x81);
|
||||
ck_assert(asn1_length(&a) == ASN1_INVALID_LENGTH);
|
||||
|
||||
a = chunk_from_chars(0x04, 0x81, 0x80, 0xaa);
|
||||
ck_assert(asn1_length(&a) == ASN1_INVALID_LENGTH);
|
||||
|
||||
a = chunk_from_chars(0x04, 0x81, 0x80, 0xaa);
|
||||
a.len = 3 + 128;
|
||||
ck_assert(asn1_length(&a) == 128);
|
||||
|
||||
a = chunk_from_chars(0x04, 0x82, 0x01, 0x02, 0xaa);
|
||||
a.len = 4 + 258;
|
||||
ck_assert(asn1_length(&a) == 258);
|
||||
|
||||
a = chunk_from_chars(0x04, 0x83, 0x01, 0x02, 0x03, 0xaa);
|
||||
a.len = 5 + 66051;
|
||||
ck_assert(asn1_length(&a) == 66051);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* unwrap
|
||||
*/
|
||||
|
||||
START_TEST(test_asn1_unwrap)
|
||||
{
|
||||
chunk_t c0 = chunk_from_chars(0x30);
|
||||
chunk_t c1 = chunk_from_chars(0x30, 0x01, 0xaa);
|
||||
chunk_t c2 = chunk_from_chars(0x30, 0x80);
|
||||
chunk_t c3 = chunk_from_chars(0x30, 0x81);
|
||||
chunk_t c4 = chunk_from_chars(0x30, 0x81, 0x01, 0xaa);
|
||||
chunk_t c5 = chunk_from_chars(0x30, 0x81, 0x02, 0xaa);
|
||||
|
||||
chunk_t inner;
|
||||
chunk_t inner_ref = chunk_from_chars(0xaa);
|
||||
|
||||
ck_assert(asn1_unwrap(&c0, &inner) == ASN1_INVALID);
|
||||
|
||||
ck_assert(asn1_unwrap(&c1, &inner) == ASN1_SEQUENCE);
|
||||
|
||||
ck_assert(chunk_equals(inner, inner_ref));
|
||||
|
||||
ck_assert(asn1_unwrap(&c2, &inner) == ASN1_INVALID);
|
||||
|
||||
ck_assert(asn1_unwrap(&c3, &inner) == ASN1_INVALID);
|
||||
|
||||
ck_assert(asn1_unwrap(&c4, &inner) == ASN1_SEQUENCE);
|
||||
|
||||
ck_assert(chunk_equals(inner, inner_ref));
|
||||
|
||||
ck_assert(asn1_unwrap(&c5, &inner) == ASN1_INVALID);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* is_asn1
|
||||
*/
|
||||
|
||||
START_TEST(test_is_asn1)
|
||||
{
|
||||
typedef struct {
|
||||
bool asn1;
|
||||
chunk_t chunk;
|
||||
} testdata_t;
|
||||
|
||||
u_char buf[8];
|
||||
chunk_t chunk_zero = { buf, 0 };
|
||||
chunk_t chunk_mean = { 0, 1 };
|
||||
|
||||
testdata_t test[] = {
|
||||
{ FALSE, chunk_zero },
|
||||
{ FALSE, chunk_empty },
|
||||
{ FALSE, chunk_mean },
|
||||
{ TRUE, chunk_from_chars(0x30, 0x00) },
|
||||
{ TRUE, chunk_from_chars(0x31, 0x00) },
|
||||
{ TRUE, chunk_from_chars(0x04, 0x00) },
|
||||
{ FALSE, chunk_from_chars(0x02, 0x00) },
|
||||
{ FALSE, chunk_from_chars(0x30, 0x01) },
|
||||
{ FALSE, chunk_from_chars(0x30, 0x80) },
|
||||
{ TRUE, chunk_from_chars(0x30, 0x01, 0xa1) },
|
||||
{ FALSE, chunk_from_chars(0x30, 0x01, 0xa1, 0xa2) },
|
||||
{ TRUE, chunk_from_chars(0x30, 0x01, 0xa1, 0x0a) },
|
||||
{ FALSE, chunk_from_chars(0x30, 0x01, 0xa1, 0xa2, 0x0a) },
|
||||
};
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < countof(test); i++)
|
||||
{
|
||||
ck_assert(is_asn1(test[i].chunk) == test[i].asn1);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* is_printablestring
|
||||
*/
|
||||
|
||||
START_TEST(test_asn1_is_printablestring)
|
||||
{
|
||||
typedef struct {
|
||||
bool printable;
|
||||
char *string;
|
||||
} testdata_t;
|
||||
|
||||
|
||||
testdata_t test[] = {
|
||||
{ TRUE, "" },
|
||||
{ TRUE, "Z" },
|
||||
{ FALSE, "Z#" },
|
||||
{ FALSE, "&Z" },
|
||||
{ FALSE, "Z@z" },
|
||||
{ FALSE, "!" }, { FALSE, "*" }, { FALSE, "$" }, { FALSE, "%" },
|
||||
{ FALSE, "[" }, { FALSE, "]" }, { FALSE, "{" }, { FALSE, "}" },
|
||||
{ FALSE, "|" }, { FALSE, "~" }, { FALSE, "^" }, { FALSE, "_" },
|
||||
{ FALSE, "\"" }, { FALSE, "\\" }, { FALSE, "ä" }, { FALSE, "à" },
|
||||
{ TRUE, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789 '()+,-./:=?" },
|
||||
};
|
||||
|
||||
chunk_t chunk;
|
||||
int i;
|
||||
|
||||
ck_assert(asn1_is_printablestring(chunk_empty));
|
||||
|
||||
for (i = 0; i < countof(test); i++)
|
||||
{
|
||||
chunk = chunk_from_str(test[i].string);
|
||||
ck_assert(asn1_is_printablestring(chunk) == test[i].printable);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* to_time
|
||||
*/
|
||||
|
||||
START_TEST(test_asn1_to_time)
|
||||
{
|
||||
typedef struct {
|
||||
time_t time;
|
||||
u_int8_t type;
|
||||
char *string;
|
||||
} testdata_t;
|
||||
|
||||
testdata_t test[] = {
|
||||
{ 352980, 0x18, "197001050203Z" },
|
||||
{ 352984, 0x18, "19700105020304Z" },
|
||||
{ 352980, 0x17, "7001050203Z" },
|
||||
{ 347580, 0x17, "7001050203+0130" },
|
||||
{ 358380, 0x17, "7001050203-0130" },
|
||||
{ 352984, 0x17, "700105020304Z" },
|
||||
{ 347584, 0x17, "700105020304+0130" },
|
||||
{ 358384, 0x17, "700105020304-0130" },
|
||||
{ 0, 0x17, "700105020304+01" },
|
||||
{ 0, 0x17, "700105020304-01" },
|
||||
{ 0, 0x17, "700105020304" },
|
||||
{ 0, 0x17, "70010502Z" },
|
||||
{ 0, 0x17, "7001050203xxZ" },
|
||||
{ 0, 0x17, "7000050203Z" },
|
||||
{ 0, 0x17, "7013050203Z" },
|
||||
{ 5097600, 0x17, "7003010000Z" },
|
||||
{ 68256000, 0x17, "7203010000Z" },
|
||||
{ 951868800, 0x17, "0003010000Z" },
|
||||
{ 4107542400, 0x18, "210003010000Z" }
|
||||
};
|
||||
|
||||
int i;
|
||||
chunk_t chunk;
|
||||
|
||||
for (i = 0; i < countof(test); i++)
|
||||
{
|
||||
if (test[i].time > TIME_32_BIT_SIGNED_MAX && sizeof(time_t) == 4)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
chunk = chunk_from_str(test[i].string);
|
||||
ck_assert(asn1_to_time(&chunk, test[i].type) == test[i].time);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* from_time
|
||||
*/
|
||||
|
||||
START_TEST(test_asn1_from_time)
|
||||
{
|
||||
typedef struct {
|
||||
time_t time;
|
||||
u_int8_t type;
|
||||
chunk_t chunk;
|
||||
} testdata_t;
|
||||
|
||||
testdata_t test[] = {
|
||||
{ 352984, 0x18, chunk_from_chars(
|
||||
0x18, 0x0f, 0x31, 0x39, 0x37, 0x30, 0x30, 0x31, 0x30, 0x35,
|
||||
0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x5a) },
|
||||
{ 352984, 0x17, chunk_from_chars(
|
||||
0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30, 0x35,
|
||||
0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x5a) },
|
||||
{ 1078099200, 0x17, chunk_from_chars(
|
||||
0x17, 0x0d, 0x30, 0x34, 0x30, 0x33, 0x30, 0x31,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a) },
|
||||
{ 4107542400, 0x18, chunk_from_chars(
|
||||
0x18, 0x0f, 0x32, 0x31, 0x30, 0x30, 0x30, 0x33, 0x30, 0x31,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a) }
|
||||
};
|
||||
|
||||
int i;
|
||||
chunk_t chunk;
|
||||
|
||||
for (i = 0; i < countof(test); i++)
|
||||
{
|
||||
if (test[i].time > TIME_32_BIT_SIGNED_MAX && sizeof(time_t) == 4)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
chunk = asn1_from_time(&test[i].time, test[i].type);
|
||||
ck_assert(chunk_equals(chunk, test[i].chunk));
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* parse_time
|
||||
*/
|
||||
|
||||
START_TEST(test_asn1_parse_time)
|
||||
{
|
||||
typedef struct {
|
||||
time_t time;
|
||||
chunk_t chunk;
|
||||
} testdata_t;
|
||||
|
||||
testdata_t test[] = {
|
||||
{ 352984, chunk_from_chars(
|
||||
0x18, 0x0f, 0x31, 0x39, 0x37, 0x30, 0x30, 0x31, 0x30, 0x35,
|
||||
0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x5a) },
|
||||
{ 352984, chunk_from_chars(
|
||||
0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30, 0x35,
|
||||
0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x5a) },
|
||||
{ 0, chunk_from_chars(0x05, 0x00) }
|
||||
};
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < countof(test); i++)
|
||||
{
|
||||
ck_assert(asn1_parse_time(test[i].chunk, 0) == test[i].time);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* build_object
|
||||
*/
|
||||
|
||||
START_TEST(test_asn1_build_object)
|
||||
{
|
||||
typedef struct {
|
||||
size_t len;
|
||||
size_t size;
|
||||
u_char *b;
|
||||
} testdata_t;
|
||||
|
||||
u_char b0[] = { 0x05, 0x00 };
|
||||
u_char b1[] = { 0x04, 0x7f };
|
||||
u_char b2[] = { 0x04, 0x81, 0x80 };
|
||||
u_char b3[] = { 0x04, 0x81, 0xff };
|
||||
u_char b4[] = { 0x04, 0x82, 0x01, 0x00 };
|
||||
u_char b5[] = { 0x04, 0x82, 0xff, 0xff };
|
||||
u_char b6[] = { 0x04, 0x83, 0x01, 0x00, 0x00 };
|
||||
|
||||
testdata_t test[] = {
|
||||
{ 0, sizeof(b0), b0 },
|
||||
{ 127, sizeof(b1), b1 },
|
||||
{ 128, sizeof(b2), b2 },
|
||||
{ 255, sizeof(b3), b3 },
|
||||
{ 256, sizeof(b4), b4 },
|
||||
{ 65535, sizeof(b5), b5 },
|
||||
{ 65536, sizeof(b6), b6 }
|
||||
};
|
||||
|
||||
chunk_t a = chunk_empty;
|
||||
u_char *pos;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < countof(test); i++)
|
||||
{
|
||||
pos = asn1_build_object(&a, test[i].b[0], test[i].len);
|
||||
ck_assert(pos == (a.ptr + test[i].size));
|
||||
ck_assert(a.len == test[i].size + test[i].len);
|
||||
ck_assert(memeq(a.ptr, test[i].b, test[i].size));
|
||||
chunk_free(&a);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* simple_object
|
||||
*/
|
||||
|
||||
START_TEST(test_asn1_simple_object)
|
||||
{
|
||||
chunk_t a = chunk_empty;
|
||||
chunk_t b = chunk_from_chars(0x04, 0x05, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5);
|
||||
chunk_t c = chunk_from_chars(0xa1, 0xa2, 0xa3, 0xa4, 0xa5);
|
||||
|
||||
a = asn1_simple_object(0x04, c);
|
||||
ck_assert(chunk_equals(a, b));
|
||||
chunk_free(&a);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* parse_simple_object
|
||||
*/
|
||||
|
||||
START_TEST(test_asn1_parse_simple_object)
|
||||
{
|
||||
typedef struct {
|
||||
bool res;
|
||||
int type;
|
||||
chunk_t chunk;
|
||||
} testdata_t;
|
||||
|
||||
testdata_t test[] = {
|
||||
{ FALSE, 0x04, chunk_from_chars(0x04) },
|
||||
{ FALSE, 0x04, chunk_from_chars(0x02, 0x01, 0x55) },
|
||||
{ FALSE, 0x04, chunk_from_chars(0x04, 0x01) },
|
||||
{ TRUE, 0x04, chunk_from_chars(0x04, 0x01, 0x55) },
|
||||
{ TRUE, 0x06, chunk_from_chars(0x06, 0x02, 0x55, 0x03) },
|
||||
{ TRUE, 0x06, chunk_from_chars(0x06, 0x00) },
|
||||
{ TRUE, 0x13, chunk_from_chars(0x13, 0x01, 0x55), }
|
||||
};
|
||||
|
||||
int i;
|
||||
bool res;
|
||||
|
||||
for (i = 0; i < countof(test); i++)
|
||||
{
|
||||
res = asn1_parse_simple_object(&test[i].chunk, test[i].type, 0, "test");
|
||||
ck_assert(res == test[i].res);
|
||||
if (res && test[i].chunk.len)
|
||||
{
|
||||
ck_assert(*test[i].chunk.ptr == 0x55);
|
||||
}
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* bitstring
|
||||
*/
|
||||
|
||||
START_TEST(test_asn1_bitstring)
|
||||
{
|
||||
chunk_t a = chunk_empty;
|
||||
chunk_t b = chunk_from_chars(0x03, 0x05, 0x00, 0xa1, 0xa2, 0xa3, 0xa4);
|
||||
chunk_t c = chunk_from_chars(0xa1, 0xa2, 0xa3, 0xa4);
|
||||
chunk_t d = chunk_clone(c);
|
||||
|
||||
a = asn1_bitstring("c", c);
|
||||
ck_assert(chunk_equals(a, b));
|
||||
chunk_free(&a);
|
||||
|
||||
a = asn1_bitstring("m", d);
|
||||
ck_assert(chunk_equals(a, b));
|
||||
chunk_free(&a);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* integer
|
||||
*/
|
||||
|
||||
START_TEST(test_asn1_integer)
|
||||
{
|
||||
typedef struct {
|
||||
chunk_t b;
|
||||
chunk_t c;
|
||||
} testdata_t;
|
||||
|
||||
chunk_t b0 = chunk_from_chars(0x02, 0x01, 0x00);
|
||||
chunk_t b1 = chunk_from_chars(0x02, 0x01, 0x7f);
|
||||
chunk_t b2 = chunk_from_chars(0x02, 0x02, 0x00, 0x80);
|
||||
|
||||
chunk_t c0 = chunk_empty;
|
||||
chunk_t c1 = chunk_from_chars(0x7f);
|
||||
chunk_t c2 = chunk_from_chars(0x80);
|
||||
chunk_t c3 = chunk_from_chars(0x00, 0x80);
|
||||
|
||||
testdata_t test[] = {
|
||||
{ b0, c0 },
|
||||
{ b1, c1 },
|
||||
{ b2, c2 },
|
||||
{ b2, c3 }
|
||||
};
|
||||
|
||||
chunk_t a = chunk_empty;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < countof(test); i++)
|
||||
{
|
||||
a = asn1_integer("c", test[i].c);
|
||||
ck_assert(chunk_equals(a, test[i].b));
|
||||
chunk_free(&a);
|
||||
|
||||
a = asn1_integer("m", chunk_clone(test[i].c));
|
||||
ck_assert(chunk_equals(a, test[i].b));
|
||||
chunk_free(&a);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* parse_integer_uint64
|
||||
*/
|
||||
|
||||
START_TEST(test_asn1_parse_integer_uint64)
|
||||
{
|
||||
typedef struct {
|
||||
u_int64_t n;
|
||||
chunk_t chunk;
|
||||
} testdata_t;
|
||||
|
||||
|
||||
testdata_t test[] = {
|
||||
{ 67305985ULL, chunk_from_chars(
|
||||
0x04, 0x03, 0x02, 0x01) },
|
||||
{ 578437695752307201ULL, chunk_from_chars(
|
||||
0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01) },
|
||||
{ 18446744073709551615ULL, chunk_from_chars(
|
||||
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff) }
|
||||
};
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < countof(test); i++)
|
||||
{
|
||||
ck_assert(asn1_parse_integer_uint64(test[i].chunk) == test[i].n);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *asn1_suite_create()
|
||||
{
|
||||
Suite *s;
|
||||
TCase *tc;
|
||||
|
||||
s = suite_create("asn1");
|
||||
|
||||
tc = tcase_create("algorithmIdentifier");
|
||||
tcase_add_test(tc, test_asn1_algorithmIdentifier);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("parse_algorithmIdentifier");
|
||||
tcase_add_test(tc, test_asn1_parse_algorithmIdentifier);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("known_oid");
|
||||
tcase_add_test(tc, test_asn1_known_oid);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("build_known_oid");
|
||||
tcase_add_test(tc, test_asn1_build_known_oid);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("oid_from_string");
|
||||
tcase_add_test(tc, test_asn1_oid_from_string);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("oid_to_string");
|
||||
tcase_add_test(tc, test_asn1_oid_to_string);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("length");
|
||||
tcase_add_test(tc, test_asn1_length);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("unwrap");
|
||||
tcase_add_test(tc, test_asn1_unwrap);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("is_asn1");
|
||||
tcase_add_test(tc, test_is_asn1);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("is_printablestring");
|
||||
tcase_add_test(tc, test_asn1_is_printablestring);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("to_time");
|
||||
tcase_add_test(tc, test_asn1_to_time);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("from_time");
|
||||
tcase_add_test(tc, test_asn1_from_time);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("parse_time");
|
||||
tcase_add_test(tc, test_asn1_parse_time);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("build_object");
|
||||
tcase_add_test(tc, test_asn1_build_object);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("simple_object");
|
||||
tcase_add_test(tc, test_asn1_simple_object);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("parse_simple_object");
|
||||
tcase_add_test(tc, test_asn1_parse_simple_object);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("bitstring");
|
||||
tcase_add_test(tc, test_asn1_bitstring);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("integer");
|
||||
tcase_add_test(tc, test_asn1_integer);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("parse_integer_uint64");
|
||||
tcase_add_test(tc, test_asn1_parse_integer_uint64);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,450 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_suite.h"
|
||||
|
||||
#include <bio/bio_reader.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* different integer reads
|
||||
*/
|
||||
|
||||
#define assert_integer_read(data, bits, val) ({ \
|
||||
bio_reader_t *reader = bio_reader_create(data); \
|
||||
typeof(val) i; \
|
||||
for (i = 0; reader->remaining(reader) >= (bits / 8); i++) \
|
||||
{ \
|
||||
ck_assert(reader->read_uint##bits(reader, &val)); \
|
||||
ck_assert_int_eq(i, val); \
|
||||
} \
|
||||
ck_assert_int_eq(i, data.len / (bits / 8)); \
|
||||
ck_assert_int_eq(reader->remaining(reader), data.len % (bits / 8)); \
|
||||
ck_assert(!reader->read_uint##bits(reader, &val)); \
|
||||
reader->destroy(reader); \
|
||||
})
|
||||
|
||||
#define assert_integer_read_uneven(data, bits, val) ({ \
|
||||
int i; \
|
||||
for (i = 0; i <= bits / 8; i++, data.len++) \
|
||||
{ \
|
||||
assert_integer_read(data, bits, val); \
|
||||
} \
|
||||
})
|
||||
|
||||
#define assert_basic_read(bits, val) ({ \
|
||||
chunk_t data; \
|
||||
data = chunk_empty; \
|
||||
assert_integer_read(data, bits, val); \
|
||||
data = chunk_alloca(bits / 8); \
|
||||
memset(data.ptr, 0, data.len); \
|
||||
data.len = 0; \
|
||||
assert_integer_read_uneven(data, bits, val); \
|
||||
})
|
||||
|
||||
#define assert_extended_read(data, bits, val) ({ \
|
||||
chunk_t extended = chunk_alloca(data.len + bits / 8); \
|
||||
memset(extended.ptr, 0, extended.len); \
|
||||
extended.ptr[extended.len - 1] = data.len / (bits / 8); \
|
||||
memcpy(extended.ptr, data.ptr, data.len); \
|
||||
extended.len = data.len; \
|
||||
assert_integer_read_uneven(extended, bits, val); \
|
||||
})
|
||||
|
||||
START_TEST(test_read_uint8)
|
||||
{
|
||||
chunk_t data = chunk_from_chars(0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07);
|
||||
u_int8_t val;
|
||||
|
||||
assert_integer_read(data, 8, val);
|
||||
assert_basic_read(8, val);
|
||||
assert_extended_read(data, 8, val);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_read_uint16)
|
||||
{
|
||||
chunk_t data = chunk_from_chars(0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03);
|
||||
u_int16_t val;
|
||||
|
||||
assert_integer_read(data, 16, val);
|
||||
assert_basic_read(16, val);
|
||||
assert_extended_read(data, 16, val);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_read_uint24)
|
||||
{
|
||||
chunk_t data = chunk_from_chars(0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03);
|
||||
u_int32_t val;
|
||||
|
||||
assert_integer_read(data, 24, val);
|
||||
assert_basic_read(24, val);
|
||||
assert_extended_read(data, 24, val);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_read_uint32)
|
||||
{
|
||||
chunk_t data = chunk_from_chars(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03);
|
||||
u_int32_t val;
|
||||
|
||||
assert_integer_read(data, 32, val);
|
||||
assert_basic_read(32, val);
|
||||
assert_extended_read(data, 32, val);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_read_uint64)
|
||||
{
|
||||
chunk_t data = chunk_from_chars(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03);
|
||||
u_int64_t val;
|
||||
|
||||
assert_integer_read(data, 64, val);
|
||||
assert_basic_read(64, val);
|
||||
assert_extended_read(data, 64, val);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* different integer reads from the end of a buffer
|
||||
*/
|
||||
|
||||
#define assert_integer_read_end(data, bits, val) ({ \
|
||||
bio_reader_t *reader = bio_reader_create(data); \
|
||||
typeof(val) i; \
|
||||
for (i = 0; reader->remaining(reader) >= (bits / 8); i++) \
|
||||
{ \
|
||||
ck_assert(reader->read_uint##bits##_end(reader, &val)); \
|
||||
ck_assert_int_eq(i, val); \
|
||||
} \
|
||||
ck_assert_int_eq(i, data.len / (bits / 8)); \
|
||||
ck_assert_int_eq(reader->remaining(reader), data.len % (bits / 8)); \
|
||||
ck_assert(!reader->read_uint##bits##_end(reader, &val)); \
|
||||
reader->destroy(reader); \
|
||||
})
|
||||
|
||||
#define assert_integer_read_end_uneven(data, bits, val) ({ \
|
||||
int i; \
|
||||
data.ptr += bits / 8; \
|
||||
for (i = 0; i <= bits / 8; i++, data.ptr--, data.len++) \
|
||||
{ \
|
||||
assert_integer_read_end(data, bits, val); \
|
||||
} \
|
||||
})
|
||||
|
||||
#define assert_basic_read_end(bits, val) ({ \
|
||||
chunk_t data; \
|
||||
data = chunk_empty; \
|
||||
assert_integer_read_end(data, bits, val); \
|
||||
data = chunk_alloca(bits / 8); \
|
||||
memset(data.ptr, 0, data.len); \
|
||||
data.len = 0; \
|
||||
assert_integer_read_end_uneven(data, bits, val); \
|
||||
})
|
||||
|
||||
#define assert_extended_read_end(data, bits, val) ({ \
|
||||
chunk_t extended = chunk_alloca(data.len + bits / 8); \
|
||||
memset(extended.ptr, 0, extended.len); \
|
||||
extended.ptr[bits / 8 - 1] = data.len / (bits / 8); \
|
||||
memcpy(extended.ptr + bits / 8, data.ptr, data.len); \
|
||||
extended.len = data.len; \
|
||||
assert_integer_read_end_uneven(extended, bits, val); \
|
||||
})
|
||||
|
||||
START_TEST(test_read_uint8_end)
|
||||
{
|
||||
chunk_t data = chunk_from_chars(0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00);
|
||||
u_int8_t val;
|
||||
|
||||
assert_integer_read_end(data, 8, val);
|
||||
assert_basic_read_end(8, val);
|
||||
assert_extended_read_end(data, 8, val);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_read_uint16_end)
|
||||
{
|
||||
chunk_t data = chunk_from_chars(0x00, 0x03, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00);
|
||||
u_int16_t val;
|
||||
|
||||
assert_integer_read_end(data, 16, val);
|
||||
assert_basic_read_end(16, val);
|
||||
assert_extended_read_end(data, 16, val);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_read_uint24_end)
|
||||
{
|
||||
chunk_t data = chunk_from_chars(0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00);
|
||||
u_int32_t val;
|
||||
|
||||
assert_integer_read_end(data, 24, val);
|
||||
assert_basic_read_end(24, val);
|
||||
assert_extended_read_end(data, 24, val);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_read_uint32_end)
|
||||
{
|
||||
chunk_t data = chunk_from_chars(0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02,
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00);
|
||||
u_int32_t val;
|
||||
|
||||
assert_integer_read_end(data, 32, val);
|
||||
assert_basic_read_end(32, val);
|
||||
assert_extended_read_end(data, 32, val);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_read_uint64_end)
|
||||
{
|
||||
chunk_t data = chunk_from_chars(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
u_int64_t val;
|
||||
|
||||
assert_integer_read_end(data, 64, val);
|
||||
assert_basic_read_end(64, val);
|
||||
assert_extended_read_end(data, 64, val);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* read data
|
||||
*/
|
||||
|
||||
static inline void assert_reader_after_read(bio_reader_t *reader, chunk_t data)
|
||||
{
|
||||
chunk_t peek;
|
||||
|
||||
ck_assert_int_eq(reader->remaining(reader), data.len);
|
||||
peek = reader->peek(reader);
|
||||
ck_assert_int_eq(reader->remaining(reader), data.len);
|
||||
ck_assert(peek.ptr == data.ptr);
|
||||
data.ptr != NULL ? ck_assert(chunk_equals(peek, data))
|
||||
: ck_assert(peek.ptr == NULL);
|
||||
}
|
||||
|
||||
START_TEST(test_read_data)
|
||||
{
|
||||
chunk_t read, data = chunk_from_chars(0x00, 0x00, 0x00, 0x00);
|
||||
bio_reader_t *reader;
|
||||
|
||||
reader = bio_reader_create(chunk_empty);
|
||||
ck_assert_int_eq(reader->remaining(reader), 0);
|
||||
ck_assert(reader->read_data(reader, 0, &read));
|
||||
ck_assert(!reader->read_data(reader, 1, &read));
|
||||
reader->destroy(reader);
|
||||
|
||||
reader = bio_reader_create(data);
|
||||
ck_assert(reader->read_data(reader, 0, &read));
|
||||
ck_assert_int_eq(read.len, 0);
|
||||
ck_assert(read.ptr == data.ptr);
|
||||
assert_reader_after_read(reader, data);
|
||||
|
||||
ck_assert(reader->read_data(reader, 1, &read));
|
||||
ck_assert_int_eq(read.len, 1);
|
||||
ck_assert(read.ptr == data.ptr);
|
||||
assert_reader_after_read(reader, chunk_skip(data, 1));
|
||||
|
||||
ck_assert(reader->read_data(reader, 2, &read));
|
||||
ck_assert_int_eq(read.len, 2);
|
||||
ck_assert(read.ptr == data.ptr + 1);
|
||||
assert_reader_after_read(reader, chunk_skip(data, 3));
|
||||
|
||||
ck_assert(!reader->read_data(reader, 2, &read));
|
||||
ck_assert(reader->read_data(reader, 1, &read));
|
||||
ck_assert_int_eq(read.len, 1);
|
||||
ck_assert(read.ptr == data.ptr + 3);
|
||||
assert_reader_after_read(reader, chunk_skip(data, 4));
|
||||
|
||||
ck_assert_int_eq(reader->remaining(reader), 0);
|
||||
ck_assert(reader->read_data(reader, 0, &read));
|
||||
ck_assert(!reader->read_data(reader, 1, &read));
|
||||
reader->destroy(reader);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_read_data_end)
|
||||
{
|
||||
chunk_t read, data = chunk_from_chars(0x00, 0x00, 0x00, 0x00);
|
||||
bio_reader_t *reader;
|
||||
|
||||
reader = bio_reader_create(chunk_empty);
|
||||
ck_assert_int_eq(reader->remaining(reader), 0);
|
||||
ck_assert(reader->read_data_end(reader, 0, &read));
|
||||
ck_assert(!reader->read_data_end(reader, 1, &read));
|
||||
reader->destroy(reader);
|
||||
|
||||
reader = bio_reader_create(data);
|
||||
ck_assert(reader->read_data_end(reader, 0, &read));
|
||||
ck_assert_int_eq(read.len, 0);
|
||||
ck_assert(read.ptr == data.ptr + data.len);
|
||||
assert_reader_after_read(reader, data);
|
||||
|
||||
ck_assert(reader->read_data_end(reader, 1, &read));
|
||||
ck_assert_int_eq(read.len, 1);
|
||||
data.len--;
|
||||
ck_assert(read.ptr == data.ptr + data.len);
|
||||
assert_reader_after_read(reader, data);
|
||||
|
||||
ck_assert(reader->read_data_end(reader, 2, &read));
|
||||
ck_assert_int_eq(read.len, 2);
|
||||
data.len -= 2;
|
||||
ck_assert(read.ptr == data.ptr + data.len);
|
||||
assert_reader_after_read(reader, data);
|
||||
|
||||
ck_assert(!reader->read_data(reader, 2, &read));
|
||||
ck_assert(reader->read_data(reader, 1, &read));
|
||||
ck_assert_int_eq(read.len, 1);
|
||||
ck_assert(read.ptr == data.ptr);
|
||||
assert_reader_after_read(reader, chunk_empty);
|
||||
|
||||
ck_assert_int_eq(reader->remaining(reader), 0);
|
||||
ck_assert(reader->read_data(reader, 0, &read));
|
||||
ck_assert(!reader->read_data(reader, 1, &read));
|
||||
reader->destroy(reader);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* read length followed by data
|
||||
*/
|
||||
|
||||
#define assert_read_data_len(bits) ({ \
|
||||
bio_reader_t *reader; \
|
||||
chunk_t read, data; \
|
||||
int i, len = bits / 8; \
|
||||
data = chunk_empty; \
|
||||
reader = bio_reader_create(data); \
|
||||
ck_assert(!reader->read_data##bits(reader, &read)); \
|
||||
reader->destroy(reader); \
|
||||
data = chunk_alloca(len + 8); \
|
||||
memset(data.ptr, 0, data.len); \
|
||||
for (i = 0; i <= 8; i++) \
|
||||
{ \
|
||||
data.ptr[len - 1] = i; \
|
||||
data.len = len + i; \
|
||||
reader = bio_reader_create(data); \
|
||||
ck_assert(reader->read_data##bits(reader, &read)); \
|
||||
ck_assert_int_eq(reader->remaining(reader), 0); \
|
||||
ck_assert_int_eq(read.len, i); \
|
||||
ck_assert((!read.ptr && !read.len) || (read.ptr == data.ptr + len)); \
|
||||
reader->destroy(reader); \
|
||||
} \
|
||||
data.ptr[len - 1] = i; \
|
||||
reader = bio_reader_create(data); \
|
||||
ck_assert(!reader->read_data##bits(reader, &read)); \
|
||||
reader->destroy(reader); \
|
||||
})
|
||||
|
||||
START_TEST(test_read_data8)
|
||||
{
|
||||
assert_read_data_len(8);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_read_data16)
|
||||
{
|
||||
assert_read_data_len(16);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_read_data24)
|
||||
{
|
||||
assert_read_data_len(24);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_read_data32)
|
||||
{
|
||||
assert_read_data_len(32);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* test constructors
|
||||
*/
|
||||
|
||||
START_TEST(test_create)
|
||||
{
|
||||
chunk_t data = chunk_from_str("foobar");
|
||||
bio_reader_t *reader;
|
||||
|
||||
data = chunk_clone(data);
|
||||
reader = bio_reader_create(data);
|
||||
reader->destroy(reader);
|
||||
chunk_free(&data);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_create_own)
|
||||
{
|
||||
chunk_t data = chunk_from_str("foobar");
|
||||
bio_reader_t *reader;
|
||||
|
||||
data = chunk_clone(data);
|
||||
reader = bio_reader_create_own(data);
|
||||
reader->destroy(reader);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *bio_reader_suite_create()
|
||||
{
|
||||
Suite *s;
|
||||
TCase *tc;
|
||||
|
||||
s = suite_create("bio_reader");
|
||||
|
||||
tc = tcase_create("integer reads");
|
||||
tcase_add_test(tc, test_read_uint8);
|
||||
tcase_add_test(tc, test_read_uint16);
|
||||
tcase_add_test(tc, test_read_uint24);
|
||||
tcase_add_test(tc, test_read_uint32);
|
||||
tcase_add_test(tc, test_read_uint64);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("integer reads from end");
|
||||
tcase_add_test(tc, test_read_uint8_end);
|
||||
tcase_add_test(tc, test_read_uint16_end);
|
||||
tcase_add_test(tc, test_read_uint24_end);
|
||||
tcase_add_test(tc, test_read_uint32_end);
|
||||
tcase_add_test(tc, test_read_uint64_end);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("data reads and peek");
|
||||
tcase_add_test(tc, test_read_data);
|
||||
tcase_add_test(tc, test_read_data_end);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("data length reads");
|
||||
tcase_add_test(tc, test_read_data8);
|
||||
tcase_add_test(tc, test_read_data16);
|
||||
tcase_add_test(tc, test_read_data24);
|
||||
tcase_add_test(tc, test_read_data32);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("constructors");
|
||||
tcase_add_test(tc, test_create);
|
||||
tcase_add_test(tc, test_create_own);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,392 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_suite.h"
|
||||
|
||||
#include <bio/bio_writer.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* different integer writes
|
||||
*/
|
||||
|
||||
static inline void verify_int_buffer(chunk_t data, int bits, int val)
|
||||
{
|
||||
size_t i;
|
||||
int len = bits / 8;
|
||||
|
||||
ck_assert_int_eq(data.len, (val + 1) * len);
|
||||
for (i = 0; i < data.len; i++)
|
||||
{
|
||||
if ((i + 1) % len)
|
||||
{
|
||||
ck_assert_int_eq(data.ptr[i], 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ck_assert_int_eq(data.ptr[i], i / len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define assert_integer_write(init, bits) ({ \
|
||||
int i; \
|
||||
bio_writer_t *writer = bio_writer_create(init); \
|
||||
for (i = 0; i < 16; i++) \
|
||||
{ \
|
||||
writer->write_uint##bits(writer, i); \
|
||||
verify_int_buffer(writer->get_buf(writer), bits, i); \
|
||||
} \
|
||||
writer->destroy(writer); \
|
||||
})
|
||||
|
||||
START_TEST(test_write_uint8)
|
||||
{
|
||||
/* use default buffer (and increase) size */
|
||||
assert_integer_write(0, 8);
|
||||
/* force a resize by the given size */
|
||||
assert_integer_write(1, 8);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_write_uint16)
|
||||
{
|
||||
assert_integer_write(0, 16);
|
||||
assert_integer_write(1, 16);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_write_uint24)
|
||||
{
|
||||
assert_integer_write(0, 24);
|
||||
assert_integer_write(1, 24);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_write_uint32)
|
||||
{
|
||||
assert_integer_write(0, 32);
|
||||
assert_integer_write(1, 32);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_write_uint64)
|
||||
{
|
||||
assert_integer_write(0, 64);
|
||||
assert_integer_write(1, 64);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* write data / skip
|
||||
*/
|
||||
|
||||
static inline void assert_writer_after_write(bio_writer_t *writer, int count)
|
||||
{
|
||||
chunk_t buf;
|
||||
size_t i;
|
||||
|
||||
buf = writer->get_buf(writer);
|
||||
ck_assert_int_eq(buf.len, count * 3);
|
||||
for (i = 0; i < buf.len; i++)
|
||||
{
|
||||
ck_assert(buf.ptr[i] == i % 3);
|
||||
}
|
||||
}
|
||||
|
||||
START_TEST(test_write_data)
|
||||
{
|
||||
chunk_t buf, data = chunk_from_chars(0x00, 0x01, 0x02);
|
||||
bio_writer_t *writer;
|
||||
|
||||
/* no allocation, but default buffer size */
|
||||
writer = bio_writer_create(0);
|
||||
buf = writer->get_buf(writer);
|
||||
ck_assert_int_eq(buf.len, 0);
|
||||
ck_assert(buf.ptr == NULL);
|
||||
|
||||
writer->write_data(writer, chunk_empty);
|
||||
buf = writer->get_buf(writer);
|
||||
ck_assert_int_eq(buf.len, 0);
|
||||
ck_assert(buf.ptr == NULL);
|
||||
writer->destroy(writer);
|
||||
|
||||
/* custom buffer size, initial buffer allocated */
|
||||
writer = bio_writer_create(1);
|
||||
buf = writer->get_buf(writer);
|
||||
ck_assert_int_eq(buf.len, 0);
|
||||
ck_assert(buf.ptr != NULL);
|
||||
|
||||
writer->write_data(writer, chunk_empty);
|
||||
buf = writer->get_buf(writer);
|
||||
ck_assert_int_eq(buf.len, 0);
|
||||
ck_assert(buf.ptr != NULL);
|
||||
writer->destroy(writer);
|
||||
|
||||
writer = bio_writer_create(0);
|
||||
|
||||
writer->write_data(writer, data);
|
||||
assert_writer_after_write(writer, 1);
|
||||
|
||||
writer->write_data(writer, data);
|
||||
assert_writer_after_write(writer, 2);
|
||||
|
||||
writer->write_data(writer, data);
|
||||
assert_writer_after_write(writer, 3);
|
||||
|
||||
writer->destroy(writer);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_skip)
|
||||
{
|
||||
chunk_t skipped, buf, data = chunk_from_chars(0x00, 0x01, 0x02);
|
||||
bio_writer_t *writer;
|
||||
|
||||
writer = bio_writer_create(4);
|
||||
skipped = writer->skip(writer, 3);
|
||||
ck_assert_int_eq(skipped.len, 3);
|
||||
buf = writer->get_buf(writer);
|
||||
ck_assert(skipped.ptr == buf.ptr);
|
||||
memset(skipped.ptr, 0, skipped.len);
|
||||
|
||||
writer->write_data(writer, data);
|
||||
buf = writer->get_buf(writer);
|
||||
ck_assert(chunk_equals(buf, chunk_from_chars(0x00, 0x00, 0x00, 0x00, 0x01, 0x02)));
|
||||
writer->destroy(writer);
|
||||
|
||||
writer = bio_writer_create(1);
|
||||
skipped = writer->skip(writer, 3);
|
||||
memcpy(skipped.ptr, data.ptr, data.len);
|
||||
|
||||
writer->write_data(writer, data);
|
||||
assert_writer_after_write(writer, 2);
|
||||
writer->destroy(writer);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* write length followed by data
|
||||
*/
|
||||
|
||||
#define assert_write_data_len(init, bits) ({ \
|
||||
bio_writer_t *writer; \
|
||||
chunk_t buf, data; \
|
||||
int i, len = bits / 8; \
|
||||
writer = bio_writer_create(init); \
|
||||
writer->write_data##bits(writer, chunk_empty); \
|
||||
buf = writer->get_buf(writer); \
|
||||
ck_assert_int_eq(buf.len, len); \
|
||||
ck_assert_int_eq(buf.ptr[len - 1], 0); \
|
||||
writer->destroy(writer); \
|
||||
data = chunk_alloca(32); \
|
||||
memset(data.ptr, 0, data.len); \
|
||||
for (i = 0; i < 32; i++) \
|
||||
{ \
|
||||
data.ptr[i] = i; \
|
||||
data.len = i; \
|
||||
writer = bio_writer_create(init); \
|
||||
writer->write_data##bits(writer, data); \
|
||||
buf = writer->get_buf(writer); \
|
||||
ck_assert_int_eq(buf.len, len + i); \
|
||||
ck_assert_int_eq(buf.ptr[len - 1], i); \
|
||||
ck_assert(chunk_equals(chunk_create(buf.ptr + len, buf.len - len), data)); \
|
||||
writer->destroy(writer); \
|
||||
} \
|
||||
})
|
||||
|
||||
START_TEST(test_write_data8)
|
||||
{
|
||||
assert_write_data_len(0, 8);
|
||||
assert_write_data_len(1, 8);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_write_data16)
|
||||
{
|
||||
assert_write_data_len(0, 16);
|
||||
assert_write_data_len(1, 16);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_write_data24)
|
||||
{
|
||||
assert_write_data_len(0, 24);
|
||||
assert_write_data_len(1, 24);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_write_data32)
|
||||
{
|
||||
assert_write_data_len(0, 32);
|
||||
assert_write_data_len(1, 32);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* add length header before current data
|
||||
*/
|
||||
|
||||
#define assert_wrap_data(init, bits) ({ \
|
||||
bio_writer_t *writer; \
|
||||
chunk_t buf, data; \
|
||||
int i, len = bits / 8; \
|
||||
writer = bio_writer_create(init); \
|
||||
writer->wrap##bits(writer); \
|
||||
buf = writer->get_buf(writer); \
|
||||
ck_assert_int_eq(buf.len, len); \
|
||||
ck_assert_int_eq(buf.ptr[len - 1], 0); \
|
||||
writer->destroy(writer); \
|
||||
data = chunk_alloca(32); \
|
||||
memset(data.ptr, 0, data.len); \
|
||||
for (i = 0; i < 32; i++) \
|
||||
{ \
|
||||
data.ptr[i] = i; \
|
||||
data.len = i; \
|
||||
writer = bio_writer_create(init); \
|
||||
writer->write_data(writer, data); \
|
||||
writer->wrap##bits(writer); \
|
||||
buf = writer->get_buf(writer); \
|
||||
ck_assert_int_eq(buf.len, len + i); \
|
||||
ck_assert_int_eq(buf.ptr[len - 1], i); \
|
||||
ck_assert(chunk_equals(chunk_create(buf.ptr + len, buf.len - len), data)); \
|
||||
writer->wrap##bits(writer); \
|
||||
buf = writer->get_buf(writer); \
|
||||
ck_assert_int_eq(buf.len, 2 * len + i); \
|
||||
ck_assert_int_eq(buf.ptr[len - 1], len + i); \
|
||||
ck_assert(chunk_equals(chunk_create(buf.ptr + 2 * len, buf.len - 2 * len), data)); \
|
||||
writer->destroy(writer); \
|
||||
} \
|
||||
})
|
||||
|
||||
START_TEST(test_wrap8)
|
||||
{
|
||||
assert_wrap_data(0, 8);
|
||||
assert_wrap_data(1, 8);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_wrap16)
|
||||
{
|
||||
assert_wrap_data(0, 16);
|
||||
assert_wrap_data(1, 16);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_wrap24)
|
||||
{
|
||||
assert_wrap_data(0, 24);
|
||||
assert_wrap_data(1, 24);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_wrap32)
|
||||
{
|
||||
assert_wrap_data(0, 32);
|
||||
assert_wrap_data(1, 32);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* test data extraction
|
||||
*/
|
||||
|
||||
START_TEST(test_get_buf)
|
||||
{
|
||||
bio_writer_t *writer;
|
||||
chunk_t data1, data2;
|
||||
|
||||
writer = bio_writer_create(0);
|
||||
writer->write_uint8(writer, 1);
|
||||
data1 = writer->get_buf(writer);
|
||||
ck_assert_int_eq(data1.len, 1);
|
||||
ck_assert(data1.ptr[0] == 1);
|
||||
|
||||
data2 = writer->get_buf(writer);
|
||||
ck_assert(chunk_equals(data1, data2));
|
||||
ck_assert(data1.ptr == data2.ptr);
|
||||
writer->destroy(writer);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_extract_buf)
|
||||
{
|
||||
bio_writer_t *writer;
|
||||
chunk_t data1, data2;
|
||||
|
||||
writer = bio_writer_create(0);
|
||||
writer->write_uint8(writer, 1);
|
||||
data1 = writer->extract_buf(writer);
|
||||
ck_assert_int_eq(data1.len, 1);
|
||||
ck_assert(data1.ptr[0] == 1);
|
||||
|
||||
data2 = writer->get_buf(writer);
|
||||
ck_assert_int_eq(data2.len, 0);
|
||||
ck_assert(data2.ptr == NULL);
|
||||
data2 = writer->extract_buf(writer);
|
||||
ck_assert_int_eq(data2.len, 0);
|
||||
ck_assert(data2.ptr == NULL);
|
||||
|
||||
writer->write_uint8(writer, 1);
|
||||
data2 = writer->get_buf(writer);
|
||||
ck_assert(chunk_equals(data1, data2));
|
||||
ck_assert(data1.ptr != data2.ptr);
|
||||
|
||||
writer->destroy(writer);
|
||||
chunk_free(&data1);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *bio_writer_suite_create()
|
||||
{
|
||||
Suite *s;
|
||||
TCase *tc;
|
||||
|
||||
s = suite_create("bio_writer");
|
||||
|
||||
tc = tcase_create("integer writes");
|
||||
tcase_add_test(tc, test_write_uint8);
|
||||
tcase_add_test(tc, test_write_uint16);
|
||||
tcase_add_test(tc, test_write_uint24);
|
||||
tcase_add_test(tc, test_write_uint32);
|
||||
tcase_add_test(tc, test_write_uint64);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("data writes/skip");
|
||||
tcase_add_test(tc, test_write_data);
|
||||
tcase_add_test(tc, test_skip);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("data length writes");
|
||||
tcase_add_test(tc, test_write_data8);
|
||||
tcase_add_test(tc, test_write_data16);
|
||||
tcase_add_test(tc, test_write_data24);
|
||||
tcase_add_test(tc, test_write_data32);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("wrap writes");
|
||||
tcase_add_test(tc, test_wrap8);
|
||||
tcase_add_test(tc, test_wrap16);
|
||||
tcase_add_test(tc, test_wrap24);
|
||||
tcase_add_test(tc, test_wrap32);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("get/extract");
|
||||
tcase_add_test(tc, test_get_buf);
|
||||
tcase_add_test(tc, test_extract_buf);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,876 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "test_suite.h"
|
||||
|
||||
#include <utils/chunk.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* utilities
|
||||
*/
|
||||
|
||||
static void assert_chunk_empty(chunk_t chunk)
|
||||
{
|
||||
ck_assert(chunk.len == 0 && chunk.ptr == NULL);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* equals
|
||||
*/
|
||||
|
||||
START_TEST(test_chunk_equals)
|
||||
{
|
||||
chunk_t chunk = chunk_from_str("chunk");
|
||||
chunk_t chunk_a, chunk_b;
|
||||
|
||||
chunk_a = chunk_empty;
|
||||
chunk_b = chunk_empty;
|
||||
ck_assert(!chunk_equals(chunk_a, chunk_b));
|
||||
|
||||
chunk_a = chunk;
|
||||
ck_assert(!chunk_equals(chunk_a, chunk_b));
|
||||
chunk_b = chunk;
|
||||
ck_assert(chunk_equals(chunk_a, chunk_b));
|
||||
|
||||
chunk_b = chunk_from_str("asdf");
|
||||
ck_assert(!chunk_equals(chunk_a, chunk_b));
|
||||
|
||||
chunk_b = chunk_from_str("chunk");
|
||||
ck_assert(chunk_equals(chunk_a, chunk_b));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* chunk_compare test
|
||||
*/
|
||||
|
||||
static struct {
|
||||
int result;
|
||||
chunk_t a;
|
||||
chunk_t b;
|
||||
} compare_data[] = {
|
||||
{ 0, { NULL, 0 }, { NULL, 0 }},
|
||||
{ 0, chunk_from_chars(0x00), chunk_from_chars(0x00)},
|
||||
{-1, chunk_from_chars(0x00), chunk_from_chars(0x01)},
|
||||
{ 1, chunk_from_chars(0x01), chunk_from_chars(0x00)},
|
||||
{ 0, chunk_from_chars(0x00, 0x00), chunk_from_chars(0x00, 0x00)},
|
||||
{-1, chunk_from_chars(0x00, 0x00), chunk_from_chars(0x00, 0x01)},
|
||||
{ 1, chunk_from_chars(0x00, 0x01), chunk_from_chars(0x00, 0x00)},
|
||||
{-1, chunk_from_chars(0x00, 0x00), chunk_from_chars(0x01, 0x00)},
|
||||
{ 1, chunk_from_chars(0x01, 0x00), chunk_from_chars(0x00, 0x00)},
|
||||
{-1, chunk_from_chars(0xff), chunk_from_chars(0x00, 0x00)},
|
||||
{ 1, chunk_from_chars(0x00, 0x00), chunk_from_chars(0xff)},
|
||||
};
|
||||
|
||||
START_TEST(test_compare)
|
||||
{
|
||||
int result, expected;
|
||||
|
||||
result = chunk_compare(compare_data[_i].a, compare_data[_i].b);
|
||||
expected = compare_data[_i].result;
|
||||
ck_assert((result == 0 && expected == 0) ||
|
||||
(result < 0 && expected < 0) ||
|
||||
(result > 0 && expected > 0));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* clear
|
||||
*/
|
||||
|
||||
START_TEST(test_chunk_clear)
|
||||
{
|
||||
chunk_t chunk;
|
||||
u_char *ptr;
|
||||
int i;
|
||||
bool cleared = TRUE;
|
||||
|
||||
chunk = chunk_empty;
|
||||
chunk_clear(&chunk);
|
||||
chunk_free(&chunk);
|
||||
|
||||
chunk = chunk_alloc(64);
|
||||
ptr = chunk.ptr;
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
chunk.ptr[i] = i;
|
||||
}
|
||||
chunk_clear(&chunk);
|
||||
/* check memory area of freed chunk. We can't use ck_assert() for this
|
||||
* test directly, as it might allocate data at the freed area. */
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
if (ptr[i] != 0 && ptr[i] == i)
|
||||
{
|
||||
cleared = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert_chunk_empty(chunk);
|
||||
ck_assert(cleared);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* chunk_length
|
||||
*/
|
||||
|
||||
START_TEST(test_chunk_length)
|
||||
{
|
||||
chunk_t a, b, c;
|
||||
size_t len;
|
||||
|
||||
a = chunk_empty;
|
||||
b = chunk_empty;
|
||||
c = chunk_empty;
|
||||
len = chunk_length("ccc", a, b, c);
|
||||
ck_assert_int_eq(len, 0);
|
||||
|
||||
a = chunk_from_str("foo");
|
||||
b = chunk_from_str("bar");
|
||||
len = chunk_length("ccc", a, b, c);
|
||||
ck_assert_int_eq(len, 6);
|
||||
|
||||
len = chunk_length("zcc", a, b, c);
|
||||
ck_assert_int_eq(len, 0);
|
||||
|
||||
len = chunk_length("czc", a, b, c);
|
||||
ck_assert_int_eq(len, 3);
|
||||
|
||||
a = chunk_from_str("foo");
|
||||
b = chunk_from_str("bar");
|
||||
c = chunk_from_str("baz");
|
||||
len = chunk_length("ccc", a, b, c);
|
||||
ck_assert_int_eq(len, 9);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* chunk_create_cat
|
||||
*/
|
||||
|
||||
START_TEST(test_chunk_create_cat)
|
||||
{
|
||||
chunk_t foo, bar;
|
||||
chunk_t a, b, c;
|
||||
u_char *ptra, *ptrb;
|
||||
|
||||
foo = chunk_from_str("foo");
|
||||
bar = chunk_from_str("bar");
|
||||
|
||||
/* to simplify things we use the chunk_cata macro */
|
||||
|
||||
a = chunk_empty;
|
||||
b = chunk_empty;
|
||||
c = chunk_cata("cc", a, b);
|
||||
ck_assert_int_eq(c.len, 0);
|
||||
ck_assert(c.ptr != NULL);
|
||||
|
||||
a = foo;
|
||||
b = bar;
|
||||
c = chunk_cata("cc", a, b);
|
||||
ck_assert_int_eq(c.len, 6);
|
||||
ck_assert(chunk_equals(c, chunk_from_str("foobar")));
|
||||
|
||||
a = chunk_clone(foo);
|
||||
b = chunk_clone(bar);
|
||||
c = chunk_cata("mm", a, b);
|
||||
ck_assert_int_eq(c.len, 6);
|
||||
ck_assert(chunk_equals(c, chunk_from_str("foobar")));
|
||||
|
||||
a = chunk_clone(foo);
|
||||
b = chunk_clone(bar);
|
||||
ptra = a.ptr;
|
||||
ptrb = b.ptr;
|
||||
c = chunk_cata("ss", a, b);
|
||||
ck_assert_int_eq(c.len, 6);
|
||||
ck_assert(chunk_equals(c, chunk_from_str("foobar")));
|
||||
/* check memory area of cleared chunk */
|
||||
ck_assert(!chunk_equals(foo, chunk_create(ptra, 3)));
|
||||
ck_assert(!chunk_equals(bar, chunk_create(ptrb, 3)));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* chunk_split
|
||||
*/
|
||||
|
||||
static bool mem_in_chunk(u_char *ptr, chunk_t chunk)
|
||||
{
|
||||
return ptr >= chunk.ptr && ptr < (chunk.ptr + chunk.len);
|
||||
}
|
||||
|
||||
START_TEST(test_chunk_split)
|
||||
{
|
||||
chunk_t foo, bar, foobar;
|
||||
chunk_t a, b, c;
|
||||
u_char *ptra, *ptrb;
|
||||
|
||||
foo = chunk_from_str("foo");
|
||||
bar = chunk_from_str("bar");
|
||||
foobar = chunk_from_str("foobar");
|
||||
|
||||
chunk_split(foobar, "aa", 3, &a, 3, &b);
|
||||
ck_assert(chunk_equals(a, foo));
|
||||
ck_assert(chunk_equals(b, bar));
|
||||
ck_assert(!mem_in_chunk(a.ptr, foobar));
|
||||
ck_assert(!mem_in_chunk(b.ptr, foobar));
|
||||
chunk_free(&a);
|
||||
chunk_free(&b);
|
||||
|
||||
chunk_split(foobar, "mm", 3, &a, 3, &b);
|
||||
ck_assert(chunk_equals(a, foo));
|
||||
ck_assert(chunk_equals(b, bar));
|
||||
ck_assert(mem_in_chunk(a.ptr, foobar));
|
||||
ck_assert(mem_in_chunk(b.ptr, foobar));
|
||||
|
||||
chunk_split(foobar, "am", 3, &a, 3, &b);
|
||||
ck_assert(chunk_equals(a, foo));
|
||||
ck_assert(chunk_equals(b, bar));
|
||||
ck_assert(!mem_in_chunk(a.ptr, foobar));
|
||||
ck_assert(mem_in_chunk(b.ptr, foobar));
|
||||
chunk_free(&a);
|
||||
|
||||
a = chunk_alloca(3);
|
||||
ptra = a.ptr;
|
||||
b = chunk_alloca(3);
|
||||
ptrb = b.ptr;
|
||||
chunk_split(foobar, "cc", 3, &a, 3, &b);
|
||||
ck_assert(chunk_equals(a, foo));
|
||||
ck_assert(chunk_equals(b, bar));
|
||||
ck_assert(a.ptr == ptra);
|
||||
ck_assert(b.ptr == ptrb);
|
||||
|
||||
chunk_split(foobar, "mm", 1, NULL, 2, &a, 2, NULL, 1, &b);
|
||||
ck_assert(chunk_equals(a, chunk_from_str("oo")));
|
||||
ck_assert(chunk_equals(b, chunk_from_str("r")));
|
||||
|
||||
chunk_split(foobar, "mm", 6, &a, 6, &b);
|
||||
ck_assert(chunk_equals(a, foobar));
|
||||
assert_chunk_empty(b);
|
||||
|
||||
chunk_split(foobar, "mac", 12, &a, 12, &b, 12, &c);
|
||||
ck_assert(chunk_equals(a, foobar));
|
||||
assert_chunk_empty(b);
|
||||
assert_chunk_empty(c);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* chunk_skip[_zero]
|
||||
*/
|
||||
|
||||
START_TEST(test_chunk_skip)
|
||||
{
|
||||
chunk_t foobar, a;
|
||||
|
||||
foobar = chunk_from_str("foobar");
|
||||
a = foobar;
|
||||
a = chunk_skip(a, 0);
|
||||
ck_assert(chunk_equals(a, foobar));
|
||||
a = chunk_skip(a, 1);
|
||||
ck_assert(chunk_equals(a, chunk_from_str("oobar")));
|
||||
a = chunk_skip(a, 2);
|
||||
ck_assert(chunk_equals(a, chunk_from_str("bar")));
|
||||
a = chunk_skip(a, 3);
|
||||
assert_chunk_empty(a);
|
||||
|
||||
a = foobar;
|
||||
a = chunk_skip(a, 6);
|
||||
assert_chunk_empty(a);
|
||||
|
||||
a = foobar;
|
||||
a = chunk_skip(a, 10);
|
||||
assert_chunk_empty(a);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_chunk_skip_zero)
|
||||
{
|
||||
chunk_t foobar, a;
|
||||
|
||||
a = chunk_empty;
|
||||
a = chunk_skip_zero(a);
|
||||
assert_chunk_empty(a);
|
||||
|
||||
foobar = chunk_from_str("foobar");
|
||||
a = foobar;
|
||||
a = chunk_skip_zero(a);
|
||||
ck_assert(chunk_equals(a, foobar));
|
||||
|
||||
a = chunk_from_chars(0x00, 0xaa, 0xbb, 0xcc);
|
||||
a = chunk_skip_zero(a);
|
||||
ck_assert(chunk_equals(a, chunk_from_chars(0xaa, 0xbb, 0xcc)));
|
||||
a = chunk_skip_zero(a);
|
||||
ck_assert(chunk_equals(a, chunk_from_chars(0xaa, 0xbb, 0xcc)));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* BASE16 encoding test
|
||||
*/
|
||||
|
||||
START_TEST(test_base16)
|
||||
{
|
||||
/* test vectors from RFC 4648:
|
||||
*
|
||||
* BASE16("") = ""
|
||||
* BASE16("f") = "66"
|
||||
* BASE16("fo") = "666F"
|
||||
* BASE16("foo") = "666F6F"
|
||||
* BASE16("foob") = "666F6F62"
|
||||
* BASE16("fooba") = "666F6F6261"
|
||||
* BASE16("foobar") = "666F6F626172"
|
||||
*/
|
||||
typedef struct {
|
||||
bool upper;
|
||||
char *in;
|
||||
char *out;
|
||||
} testdata_t;
|
||||
|
||||
testdata_t test[] = {
|
||||
{TRUE, "", ""},
|
||||
{TRUE, "f", "66"},
|
||||
{TRUE, "fo", "666F"},
|
||||
{TRUE, "foo", "666F6F"},
|
||||
{TRUE, "foob", "666F6F62"},
|
||||
{TRUE, "fooba", "666F6F6261"},
|
||||
{TRUE, "foobar", "666F6F626172"},
|
||||
{FALSE, "", ""},
|
||||
{FALSE, "f", "66"},
|
||||
{FALSE, "fo", "666f"},
|
||||
{FALSE, "foo", "666f6f"},
|
||||
{FALSE, "foob", "666f6f62"},
|
||||
{FALSE, "fooba", "666f6f6261"},
|
||||
{FALSE, "foobar", "666f6f626172"},
|
||||
};
|
||||
testdata_t test_colon[] = {
|
||||
{TRUE, "", ""},
|
||||
{TRUE, "f", "66"},
|
||||
{TRUE, "fo", "66:6F"},
|
||||
{TRUE, "foo", "66:6F:6F"},
|
||||
{FALSE, "foob", "66:6f:6f:62"},
|
||||
{FALSE, "fooba", "66:6f:6f:62:61"},
|
||||
{FALSE, "foobar", "66:6f:6f:62:61:72"},
|
||||
{FALSE, "foobar", "66:6f6f:6261:72"},
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < countof(test); i++)
|
||||
{
|
||||
chunk_t out;
|
||||
|
||||
out = chunk_to_hex(chunk_create(test[i].in, strlen(test[i].in)), NULL,
|
||||
test[i].upper);
|
||||
ck_assert_str_eq(out.ptr, test[i].out);
|
||||
free(out.ptr);
|
||||
}
|
||||
|
||||
for (i = 0; i < countof(test); i++)
|
||||
{
|
||||
chunk_t out;
|
||||
|
||||
out = chunk_from_hex(chunk_create(test[i].out, strlen(test[i].out)), NULL);
|
||||
fail_unless(strneq(out.ptr, test[i].in, out.len),
|
||||
"base16 conversion error - should '%s', is %#B",
|
||||
test[i].in, &out);
|
||||
free(out.ptr);
|
||||
}
|
||||
|
||||
for (i = 0; i < countof(test_colon); i++)
|
||||
{
|
||||
chunk_t out;
|
||||
|
||||
out = chunk_from_hex(chunk_create(test_colon[i].out, strlen(test_colon[i].out)), NULL);
|
||||
fail_unless(strneq(out.ptr, test_colon[i].in, out.len),
|
||||
"base16 conversion error - should '%s', is %#B",
|
||||
test_colon[i].in, &out);
|
||||
free(out.ptr);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* BASE64 encoding test
|
||||
*/
|
||||
|
||||
START_TEST(test_base64)
|
||||
{
|
||||
/* test vectors from RFC 4648:
|
||||
*
|
||||
* BASE64("") = ""
|
||||
* BASE64("f") = "Zg=="
|
||||
* BASE64("fo") = "Zm8="
|
||||
* BASE64("foo") = "Zm9v"
|
||||
* BASE64("foob") = "Zm9vYg=="
|
||||
* BASE64("fooba") = "Zm9vYmE="
|
||||
* BASE64("foobar") = "Zm9vYmFy"
|
||||
*/
|
||||
typedef struct {
|
||||
char *in;
|
||||
char *out;
|
||||
} testdata_t;
|
||||
|
||||
testdata_t test[] = {
|
||||
{"", ""},
|
||||
{"f", "Zg=="},
|
||||
{"fo", "Zm8="},
|
||||
{"foo", "Zm9v"},
|
||||
{"foob", "Zm9vYg=="},
|
||||
{"fooba", "Zm9vYmE="},
|
||||
{"foobar", "Zm9vYmFy"},
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < countof(test); i++)
|
||||
{
|
||||
chunk_t out;
|
||||
|
||||
out = chunk_to_base64(chunk_create(test[i].in, strlen(test[i].in)), NULL);
|
||||
ck_assert_str_eq(out.ptr, test[i].out);
|
||||
free(out.ptr);
|
||||
}
|
||||
|
||||
for (i = 0; i < countof(test); i++)
|
||||
{
|
||||
chunk_t out;
|
||||
|
||||
out = chunk_from_base64(chunk_create(test[i].out, strlen(test[i].out)), NULL);
|
||||
fail_unless(strneq(out.ptr, test[i].in, out.len),
|
||||
"base64 conversion error - should '%s', is %#B",
|
||||
test[i].in, &out);
|
||||
free(out.ptr);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* BASE32 encoding test
|
||||
*/
|
||||
|
||||
START_TEST(test_base32)
|
||||
{
|
||||
/* test vectors from RFC 4648:
|
||||
*
|
||||
* BASE32("") = ""
|
||||
* BASE32("f") = "MY======"
|
||||
* BASE32("fo") = "MZXQ===="
|
||||
* BASE32("foo") = "MZXW6==="
|
||||
* BASE32("foob") = "MZXW6YQ="
|
||||
* BASE32("fooba") = "MZXW6YTB"
|
||||
* BASE32("foobar") = "MZXW6YTBOI======"
|
||||
*/
|
||||
typedef struct {
|
||||
char *in;
|
||||
char *out;
|
||||
} testdata_t;
|
||||
|
||||
testdata_t test[] = {
|
||||
{"", ""},
|
||||
{"f", "MY======"},
|
||||
{"fo", "MZXQ===="},
|
||||
{"foo", "MZXW6==="},
|
||||
{"foob", "MZXW6YQ="},
|
||||
{"fooba", "MZXW6YTB"},
|
||||
{"foobar", "MZXW6YTBOI======"},
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < countof(test); i++)
|
||||
{
|
||||
chunk_t out;
|
||||
|
||||
out = chunk_to_base32(chunk_create(test[i].in, strlen(test[i].in)), NULL);
|
||||
ck_assert_str_eq(out.ptr, test[i].out);
|
||||
free(out.ptr);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* chunk_increment test
|
||||
*/
|
||||
|
||||
static struct {
|
||||
bool overflow;
|
||||
chunk_t in;
|
||||
chunk_t out;
|
||||
} increment_data[] = {
|
||||
{TRUE, { NULL, 0 }, { NULL, 0 }},
|
||||
{FALSE, chunk_from_chars(0x00), chunk_from_chars(0x01)},
|
||||
{FALSE, chunk_from_chars(0xfe), chunk_from_chars(0xff)},
|
||||
{TRUE, chunk_from_chars(0xff), chunk_from_chars(0x00)},
|
||||
{FALSE, chunk_from_chars(0x00, 0x00), chunk_from_chars(0x00, 0x01)},
|
||||
{FALSE, chunk_from_chars(0x00, 0xff), chunk_from_chars(0x01, 0x00)},
|
||||
{FALSE, chunk_from_chars(0xfe, 0xff), chunk_from_chars(0xff, 0x00)},
|
||||
{TRUE, chunk_from_chars(0xff, 0xff), chunk_from_chars(0x00, 0x00)},
|
||||
};
|
||||
|
||||
START_TEST(test_increment)
|
||||
{
|
||||
chunk_t chunk;
|
||||
bool overflow;
|
||||
|
||||
chunk = chunk_clonea(increment_data[_i].in);
|
||||
overflow = chunk_increment(chunk);
|
||||
ck_assert(overflow == increment_data[_i].overflow);
|
||||
ck_assert(!increment_data[_i].out.ptr ||
|
||||
chunk_equals(chunk, increment_data[_i].out));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* chunk_printable tests
|
||||
*/
|
||||
|
||||
static struct {
|
||||
bool printable;
|
||||
chunk_t in;
|
||||
char *out;
|
||||
} printable_data[] = {
|
||||
{TRUE, chunk_from_chars(0x31), "1"},
|
||||
{FALSE, chunk_from_chars(0x00), "?"},
|
||||
{FALSE, chunk_from_chars(0x31, 0x00), "1?"},
|
||||
{FALSE, chunk_from_chars(0x00, 0x31), "?1"},
|
||||
{TRUE, chunk_from_chars(0x3f, 0x31), "?1"},
|
||||
{FALSE, chunk_from_chars(0x00, 0x31, 0x00), "?1?"},
|
||||
{FALSE, chunk_from_chars(0x00, 0x31, 0x00, 0x32), "?1?2"},
|
||||
};
|
||||
|
||||
START_TEST(test_printable)
|
||||
{
|
||||
bool printable;
|
||||
|
||||
printable = chunk_printable(printable_data[_i].in, NULL, ' ');
|
||||
ck_assert(printable == printable_data[_i].printable);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_printable_sanitize)
|
||||
{
|
||||
chunk_t sane, expected;
|
||||
bool printable;
|
||||
|
||||
printable = chunk_printable(printable_data[_i].in, &sane, '?');
|
||||
ck_assert(printable == printable_data[_i].printable);
|
||||
expected = chunk_from_str(printable_data[_i].out);
|
||||
ck_assert(chunk_equals(sane, expected));
|
||||
chunk_free(&sane);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_printable_empty)
|
||||
{
|
||||
chunk_t sane;
|
||||
bool printable;
|
||||
|
||||
printable = chunk_printable(chunk_empty, NULL, ' ');
|
||||
ck_assert(printable);
|
||||
|
||||
sane.ptr = (void*)1;
|
||||
sane.len = 1;
|
||||
printable = chunk_printable(chunk_empty, &sane, ' ');
|
||||
ck_assert(printable);
|
||||
assert_chunk_empty(sane);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* test for chunk_mac(), i.e. SipHash-2-4
|
||||
*/
|
||||
|
||||
/**
|
||||
* SipHash-2-4 output with
|
||||
* k = 00 01 02 ...
|
||||
* and
|
||||
* in = (empty string)
|
||||
* in = 00 (1 byte)
|
||||
* in = 00 01 (2 bytes)
|
||||
* in = 00 01 02 (3 bytes)
|
||||
* ...
|
||||
* in = 00 01 02 ... 3e (63 bytes)
|
||||
*/
|
||||
static const u_char sip_vectors[64][8] =
|
||||
{
|
||||
{ 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, },
|
||||
{ 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, },
|
||||
{ 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, },
|
||||
{ 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, },
|
||||
{ 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, },
|
||||
{ 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, },
|
||||
{ 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, },
|
||||
{ 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, },
|
||||
{ 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, },
|
||||
{ 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, },
|
||||
{ 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, },
|
||||
{ 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, },
|
||||
{ 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, },
|
||||
{ 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, },
|
||||
{ 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, },
|
||||
{ 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, },
|
||||
{ 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, },
|
||||
{ 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, },
|
||||
{ 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, },
|
||||
{ 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, },
|
||||
{ 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, },
|
||||
{ 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, },
|
||||
{ 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, },
|
||||
{ 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, },
|
||||
{ 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, },
|
||||
{ 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, },
|
||||
{ 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, },
|
||||
{ 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, },
|
||||
{ 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, },
|
||||
{ 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, },
|
||||
{ 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, },
|
||||
{ 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, },
|
||||
{ 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, },
|
||||
{ 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, },
|
||||
{ 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, },
|
||||
{ 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, },
|
||||
{ 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, },
|
||||
{ 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, },
|
||||
{ 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, },
|
||||
{ 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, },
|
||||
{ 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, },
|
||||
{ 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, },
|
||||
{ 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, },
|
||||
{ 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, },
|
||||
{ 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, },
|
||||
{ 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, },
|
||||
{ 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, },
|
||||
{ 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, },
|
||||
{ 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, },
|
||||
{ 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, },
|
||||
{ 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, },
|
||||
{ 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, },
|
||||
{ 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, },
|
||||
{ 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, },
|
||||
{ 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, },
|
||||
{ 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, },
|
||||
{ 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, },
|
||||
{ 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, },
|
||||
{ 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, },
|
||||
{ 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, },
|
||||
{ 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, },
|
||||
{ 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, },
|
||||
{ 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, },
|
||||
{ 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, }
|
||||
};
|
||||
|
||||
START_TEST(test_chunk_mac)
|
||||
{
|
||||
chunk_t in;
|
||||
u_char key[16];
|
||||
u_int64_t out;
|
||||
int i, count;
|
||||
|
||||
count = countof(sip_vectors);
|
||||
in = chunk_alloca(count);
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
key[i] = i;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
in.ptr[i] = i;
|
||||
in.len = i;
|
||||
out = chunk_mac(in, key);
|
||||
fail_unless(memeq(&out, sip_vectors[i], 8),
|
||||
"test vector failed for %d bytes", i);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* test for chunk_hash[_inc]()
|
||||
*/
|
||||
|
||||
START_TEST(test_chunk_hash)
|
||||
{
|
||||
chunk_t chunk;
|
||||
u_int32_t hash_a, hash_b, hash_c;
|
||||
|
||||
chunk = chunk_from_str("asdf");
|
||||
|
||||
/* output is randomized, so there are no test-vectors we could use */
|
||||
hash_a = chunk_hash(chunk);
|
||||
hash_b = chunk_hash(chunk);
|
||||
ck_assert(hash_a == hash_b);
|
||||
hash_b = chunk_hash_inc(chunk, hash_a);
|
||||
ck_assert(hash_a != hash_b);
|
||||
hash_c = chunk_hash_inc(chunk, hash_a);
|
||||
ck_assert(hash_b == hash_c);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* test for chunk_hash_static[_inc]()
|
||||
*/
|
||||
|
||||
START_TEST(test_chunk_hash_static)
|
||||
{
|
||||
chunk_t in;
|
||||
u_int32_t out, hash_a, hash_b, hash_inc = 0x7b891a95;
|
||||
int i, count;
|
||||
|
||||
count = countof(sip_vectors);
|
||||
in = chunk_alloca(count);
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
in.ptr[i] = i;
|
||||
in.len = i;
|
||||
/* compared to chunk_mac() we only get half the value back */
|
||||
out = chunk_hash_static(in);
|
||||
fail_unless(memeq(&out, sip_vectors[i], 4),
|
||||
"test vector failed for %d bytes", i);
|
||||
}
|
||||
hash_a = chunk_hash_static_inc(in, out);
|
||||
ck_assert_int_eq(hash_a, hash_inc);
|
||||
hash_b = chunk_hash_static_inc(in, out);
|
||||
ck_assert_int_eq(hash_a, hash_b);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* printf_hook tests
|
||||
*/
|
||||
|
||||
static struct {
|
||||
chunk_t in;
|
||||
char *out;
|
||||
char *out_plus;
|
||||
} printf_hook_data[] = {
|
||||
{chunk_from_chars(), "", ""},
|
||||
{chunk_from_chars(0x00), "00", "00"},
|
||||
{chunk_from_chars(0x00, 0x01), "00:01", "0001"},
|
||||
{chunk_from_chars(0x00, 0x01, 0x02), "00:01:02", "000102"},
|
||||
};
|
||||
|
||||
START_TEST(test_printf_hook_hash)
|
||||
{
|
||||
char buf[16];
|
||||
int len;
|
||||
|
||||
len = snprintf(buf, sizeof(buf), "%#B", &printf_hook_data[_i].in);
|
||||
ck_assert(len >= 0 && len < sizeof(buf));
|
||||
ck_assert_str_eq(buf, printf_hook_data[_i].out);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_printf_hook_plus)
|
||||
{
|
||||
char buf[16];
|
||||
int len;
|
||||
|
||||
len = snprintf(buf, sizeof(buf), "%+B", &printf_hook_data[_i].in);
|
||||
ck_assert(len >= 0 && len < sizeof(buf));
|
||||
ck_assert_str_eq(buf, printf_hook_data[_i].out_plus);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_printf_hook)
|
||||
{
|
||||
char buf[128], mem[128];
|
||||
int len;
|
||||
|
||||
/* %B should be the same as %b, which is what we check, comparing the
|
||||
* acutal result could be tricky as %b prints the chunk's memory address */
|
||||
len = snprintf(buf, sizeof(buf), "%B", &printf_hook_data[_i].in);
|
||||
ck_assert(len >= 0 && len < sizeof(buf));
|
||||
len = snprintf(mem, sizeof(mem), "%b", printf_hook_data[_i].in.ptr,
|
||||
(u_int)printf_hook_data[_i].in.len);
|
||||
ck_assert(len >= 0 && len < sizeof(mem));
|
||||
ck_assert_str_eq(buf, mem);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *chunk_suite_create()
|
||||
{
|
||||
Suite *s;
|
||||
TCase *tc;
|
||||
|
||||
s = suite_create("chunk");
|
||||
|
||||
tc = tcase_create("equals");
|
||||
tcase_add_test(tc, test_chunk_equals);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("chunk_compare");
|
||||
tcase_add_loop_test(tc, test_compare, 0, countof(compare_data));
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("clear");
|
||||
tcase_add_test(tc, test_chunk_clear);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("chunk_length");
|
||||
tcase_add_test(tc, test_chunk_length);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("chunk_create_cat");
|
||||
tcase_add_test(tc, test_chunk_create_cat);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("chunk_split");
|
||||
tcase_add_test(tc, test_chunk_split);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("chunk_skip");
|
||||
tcase_add_test(tc, test_chunk_skip);
|
||||
tcase_add_test(tc, test_chunk_skip_zero);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("chunk_increment");
|
||||
tcase_add_loop_test(tc, test_increment, 0, countof(increment_data));
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("chunk_printable");
|
||||
tcase_add_loop_test(tc, test_printable, 0, countof(printable_data));
|
||||
tcase_add_loop_test(tc, test_printable_sanitize, 0, countof(printable_data));
|
||||
tcase_add_test(tc, test_printable_empty);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("baseXX");
|
||||
tcase_add_test(tc, test_base64);
|
||||
tcase_add_test(tc, test_base32);
|
||||
tcase_add_test(tc, test_base16);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("chunk_mac");
|
||||
tcase_add_test(tc, test_chunk_mac);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("chunk_hash");
|
||||
tcase_add_test(tc, test_chunk_hash);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("chunk_hash_static");
|
||||
tcase_add_test(tc, test_chunk_hash_static);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("printf_hook");
|
||||
tcase_add_loop_test(tc, test_printf_hook_hash, 0, countof(printf_hook_data));
|
||||
tcase_add_loop_test(tc, test_printf_hook_plus, 0, countof(printf_hook_data));
|
||||
tcase_add_loop_test(tc, test_printf_hook, 0, countof(printf_hook_data));
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Martin Willi
|
||||
* Copyright (C) 2013 revosec AG
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_suite.h"
|
||||
|
||||
#include <plugins/plugin_feature.h>
|
||||
|
||||
/**
|
||||
* Signature schemes to test
|
||||
*/
|
||||
static struct {
|
||||
/* key size for scheme, 0 for any */
|
||||
int key_size;
|
||||
signature_scheme_t scheme;
|
||||
} schemes[] = {
|
||||
{ 0, SIGN_ECDSA_WITH_SHA1_DER },
|
||||
{ 0, SIGN_ECDSA_WITH_SHA256_DER },
|
||||
{ 0, SIGN_ECDSA_WITH_SHA384_DER },
|
||||
{ 0, SIGN_ECDSA_WITH_SHA512_DER },
|
||||
{ 0, SIGN_ECDSA_WITH_NULL },
|
||||
{ 256, SIGN_ECDSA_256 },
|
||||
{ 384, SIGN_ECDSA_384 },
|
||||
{ 521, SIGN_ECDSA_521 },
|
||||
};
|
||||
|
||||
/**
|
||||
* Perform a signature verification "good" test having a keypair
|
||||
*/
|
||||
static void test_good_sig(private_key_t *privkey, public_key_t *pubkey)
|
||||
{
|
||||
chunk_t sig, data = chunk_from_chars(0x01,0x02,0x03,0xFD,0xFE,0xFF);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < countof(schemes); i++)
|
||||
{
|
||||
if (!lib->plugins->has_feature(lib->plugins,
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, schemes[i].scheme)) ||
|
||||
!lib->plugins->has_feature(lib->plugins,
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, schemes[i].scheme)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (schemes[i].key_size != 0 &&
|
||||
schemes[i].scheme != privkey->get_keysize(privkey))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
fail_unless(privkey->sign(privkey, schemes[i].scheme, data, &sig),
|
||||
"sign %N", signature_scheme_names, schemes[i].scheme);
|
||||
fail_unless(pubkey->verify(pubkey, schemes[i].scheme, data, sig),
|
||||
"verify %N", signature_scheme_names, schemes[i].scheme);
|
||||
free(sig.ptr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Some special signatures that should never validate successfully
|
||||
*/
|
||||
static chunk_t invalid_sigs[] = {
|
||||
chunk_from_chars(),
|
||||
chunk_from_chars(0x00),
|
||||
chunk_from_chars(0x00,0x00),
|
||||
chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
|
||||
chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
|
||||
chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
|
||||
chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
|
||||
chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
|
||||
chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
|
||||
};
|
||||
|
||||
/**
|
||||
* Check public key that it properly fails against some crafted sigs
|
||||
*/
|
||||
static void test_bad_sigs(public_key_t *pubkey)
|
||||
{
|
||||
chunk_t data = chunk_from_chars(0x01,0x02,0x03,0xFD,0xFE,0xFF);
|
||||
int s, i;
|
||||
|
||||
for (s = 0; s < countof(schemes); s++)
|
||||
{
|
||||
if (schemes[s].key_size != 0 &&
|
||||
schemes[s].scheme != pubkey->get_keysize(pubkey))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!lib->plugins->has_feature(lib->plugins,
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, schemes[s].scheme)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (i = 0; i < countof(invalid_sigs); i++)
|
||||
{
|
||||
fail_if(
|
||||
pubkey->verify(pubkey, schemes[s].scheme, data, invalid_sigs[i]),
|
||||
"bad %N sig accepted %B",
|
||||
signature_scheme_names, schemes[s].scheme,
|
||||
&invalid_sigs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ECDSA key sizes to test
|
||||
*/
|
||||
static int key_sizes[] = {
|
||||
256, 384, 521,
|
||||
};
|
||||
|
||||
START_TEST(test_gen)
|
||||
{
|
||||
private_key_t *privkey;
|
||||
public_key_t *pubkey;
|
||||
|
||||
privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
|
||||
BUILD_KEY_SIZE, key_sizes[_i], BUILD_END);
|
||||
ck_assert(privkey != NULL);
|
||||
pubkey = privkey->get_public_key(privkey);
|
||||
ck_assert(pubkey != NULL);
|
||||
|
||||
test_good_sig(privkey, pubkey);
|
||||
|
||||
test_bad_sigs(pubkey);
|
||||
|
||||
pubkey->destroy(pubkey);
|
||||
privkey->destroy(privkey);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/**
|
||||
* Private keys to load
|
||||
*/
|
||||
static chunk_t keys[] = {
|
||||
chunk_from_chars( /* ECDSA-256 */
|
||||
0x30,0x77,0x02,0x01,0x01,0x04,0x20,0x42,0xc6,0x8c,0xff,0x2b,0x8b,0x87,0xa1,0xfb,
|
||||
0x50,0xf6,0xfe,0xd6,0x88,0xb3,0x0a,0x48,0xb2,0xc5,0x8f,0x50,0xe0,0xcf,0x40,0xfa,
|
||||
0x57,0xd1,0xc6,0x6c,0x20,0x64,0xc5,0xa0,0x0a,0x06,0x08,0x2a,0x86,0x48,0xce,0x3d,
|
||||
0x03,0x01,0x07,0xa1,0x44,0x03,0x42,0x00,0x04,0x9c,0xb2,0x52,0xcb,0xc0,0x5c,0xcf,
|
||||
0x97,0xdd,0xd6,0xe7,0x49,0x32,0x47,0x0c,0x8e,0xdb,0x6d,0xbf,0xc8,0x1a,0x0a,0x01,
|
||||
0xe8,0x5e,0x3f,0x8e,0x64,0x33,0xb4,0x15,0xbb,0x1b,0xa5,0xed,0xf9,0x4b,0xa7,0xe8,
|
||||
0x5e,0x6f,0x49,0x24,0xf7,0x32,0xf4,0x9b,0x4c,0x47,0xdc,0xf1,0x28,0x44,0x1c,0x37,
|
||||
0xdb,0xee,0xfb,0xd8,0xbd,0x4e,0x5c,0xeb,0x07),
|
||||
chunk_from_chars( /* ECDSA-384 */
|
||||
0x30,0x81,0xa4,0x02,0x01,0x01,0x04,0x30,0x4b,0xbf,0x6c,0xf5,0x24,0x78,0x53,0x4b,
|
||||
0x1a,0x91,0x23,0xae,0x30,0xc8,0xb3,0xc9,0xc2,0x9b,0x23,0x07,0x10,0x6f,0x1b,0x47,
|
||||
0x7c,0xa0,0xd4,0x79,0x3c,0xc4,0x83,0x10,0xd1,0x44,0x07,0xc2,0x1b,0x66,0xff,0xae,
|
||||
0x76,0x57,0x72,0x90,0x53,0xc2,0xf5,0x29,0xa0,0x07,0x06,0x05,0x2b,0x81,0x04,0x00,
|
||||
0x22,0xa1,0x64,0x03,0x62,0x00,0x04,0x1e,0xcf,0x1c,0x85,0x9d,0x06,0xa0,0x54,0xa2,
|
||||
0x24,0x2f,0xd8,0x63,0x56,0x7b,0x70,0x0b,0x7f,0x81,0x96,0xce,0xb9,0x2e,0x35,0x03,
|
||||
0x9c,0xf9,0x0a,0x5d,0x3b,0x10,0xf7,0x13,0x7a,0x0d,0xca,0x56,0xda,0x1d,0x44,0x84,
|
||||
0x07,0x6f,0x58,0xdc,0x34,0x7b,0x1d,0x4c,0xdd,0x28,0x10,0xc0,0xe2,0xae,0xf4,0xd6,
|
||||
0xda,0xea,0xaf,0xfc,0x7a,0xaf,0x59,0x5f,0xbc,0x91,0x65,0xd3,0x21,0x19,0x61,0xbb,
|
||||
0xfe,0x3c,0xdb,0x47,0xcb,0x7a,0xe7,0x5d,0xbd,0x28,0xde,0x25,0x64,0x9e,0x3a,0xa9,
|
||||
0x18,0xed,0x24,0xe1,0x1f,0x73,0xcc),
|
||||
chunk_from_chars( /* ECDSA-521 */
|
||||
0x30,0x81,0xdc,0x02,0x01,0x01,0x04,0x42,0x01,0xcf,0x38,0xaa,0xa7,0x7a,0x79,0x48,
|
||||
0xa9,0x60,0x55,0x24,0xa8,0x7e,0xe1,0xbc,0x45,0x35,0x16,0xff,0x18,0xce,0x44,0xa2,
|
||||
0x0b,0x72,0x6b,0xca,0x0a,0x40,0xb4,0x97,0x13,0x17,0x90,0x50,0x15,0xb9,0xba,0xfc,
|
||||
0x08,0x0e,0xdb,0xf8,0xfc,0x06,0x35,0x37,0xbf,0xfb,0x25,0x74,0xfe,0x0f,0xe1,0x3c,
|
||||
0x3a,0xf0,0x0d,0xe0,0x52,0x15,0xa8,0x07,0x6f,0x3e,0xa0,0x07,0x06,0x05,0x2b,0x81,
|
||||
0x04,0x00,0x23,0xa1,0x81,0x89,0x03,0x81,0x86,0x00,0x04,0x00,0x56,0x81,0x28,0xd6,
|
||||
0xac,0xe9,0xc8,0x82,0x2c,0xac,0x61,0x6d,0xdd,0x88,0x79,0x00,0xe3,0x7a,0x4d,0x25,
|
||||
0xc4,0xea,0x05,0x80,0x75,0x48,0xbc,0x75,0x73,0xc4,0xe9,0x76,0x68,0xba,0x51,0xc3,
|
||||
0x29,0xce,0x7d,0x1b,0xb0,0x8b,0xac,0xc1,0xcc,0x23,0xa7,0x2d,0xa7,0x2c,0x95,0xf6,
|
||||
0x01,0x40,0x26,0x01,0x1c,0x1c,0x9c,0xe7,0xa7,0xb4,0x0f,0x8e,0xba,0x01,0x07,0xb3,
|
||||
0xf7,0xbe,0x45,0x20,0xa9,0x9e,0x70,0xf0,0xcf,0x9b,0xa0,0x91,0xe3,0x88,0x8f,0x04,
|
||||
0x69,0x3d,0x0f,0x2b,0xf3,0xb4,0x03,0x19,0x89,0xcf,0xfa,0x77,0x04,0x15,0xaf,0xdd,
|
||||
0xf7,0x32,0x76,0x25,0x25,0x05,0x8d,0xfd,0x18,0x8a,0xda,0xd6,0xbc,0x71,0xb8,0x9f,
|
||||
0x39,0xb0,0xaf,0xcc,0x54,0xb0,0x9c,0x4d,0x54,0xfb,0x46,0x53,0x5f,0xf8,0x45),
|
||||
};
|
||||
|
||||
START_TEST(test_load)
|
||||
{
|
||||
private_key_t *privkey;
|
||||
public_key_t *pubkey;
|
||||
|
||||
privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
|
||||
BUILD_BLOB_ASN1_DER, keys[_i], BUILD_END);
|
||||
ck_assert(privkey != NULL);
|
||||
pubkey = privkey->get_public_key(privkey);
|
||||
ck_assert(pubkey != NULL);
|
||||
|
||||
test_good_sig(privkey, pubkey);
|
||||
|
||||
test_bad_sigs(pubkey);
|
||||
|
||||
pubkey->destroy(pubkey);
|
||||
privkey->destroy(privkey);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *ecdsa_suite_create()
|
||||
{
|
||||
Suite *s;
|
||||
TCase *tc;
|
||||
|
||||
s = suite_create("ecdsa");
|
||||
|
||||
tc = tcase_create("generate");
|
||||
tcase_add_loop_test(tc, test_gen, 0, countof(key_sizes));
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("load");
|
||||
tcase_add_loop_test(tc, test_load, 0, countof(keys));
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_suite.h"
|
||||
|
||||
#include <utils/enum.h>
|
||||
#include <utils/utils.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* continuous enum
|
||||
*/
|
||||
enum {
|
||||
CONT1,
|
||||
CONT2,
|
||||
CONT3,
|
||||
CONT4,
|
||||
CONT5,
|
||||
} test_enum_cont;
|
||||
|
||||
/* can't be static */
|
||||
enum_name_t *test_enum_cont_names;
|
||||
|
||||
ENUM_BEGIN(test_enum_cont_names, CONT1, CONT5,
|
||||
"CONT1", "CONT2", "CONT3", "CONT4", "CONT5");
|
||||
ENUM_END(test_enum_cont_names, CONT5);
|
||||
|
||||
/*******************************************************************************
|
||||
* split enum
|
||||
*/
|
||||
enum {
|
||||
SPLIT1 = 1,
|
||||
SPLIT2,
|
||||
SPLIT3 = 5,
|
||||
SPLIT4,
|
||||
SPLIT5 = 255,
|
||||
} test_enum_split;
|
||||
|
||||
/* can't be static */
|
||||
enum_name_t *test_enum_split_names;
|
||||
|
||||
ENUM_BEGIN(test_enum_split_names, SPLIT1, SPLIT2,
|
||||
"SPLIT1", "SPLIT2");
|
||||
ENUM_NEXT(test_enum_split_names, SPLIT3, SPLIT4, SPLIT2,
|
||||
"SPLIT3", "SPLIT4");
|
||||
ENUM_NEXT(test_enum_split_names, SPLIT5, SPLIT5, SPLIT4,
|
||||
"SPLIT5");
|
||||
ENUM_END(test_enum_split_names, SPLIT5);
|
||||
|
||||
/*******************************************************************************
|
||||
* enum_to_name
|
||||
*/
|
||||
|
||||
static struct {
|
||||
int val;
|
||||
char *str;
|
||||
} name_tests_cont[] = {
|
||||
{-1, NULL},
|
||||
{CONT1, "CONT1"},
|
||||
{CONT2, "CONT2"},
|
||||
{CONT3, "CONT3"},
|
||||
{CONT4, "CONT4"},
|
||||
{CONT5, "CONT5"},
|
||||
{5, NULL},
|
||||
}, name_tests_split[] = {
|
||||
{-1, NULL},
|
||||
{0, NULL},
|
||||
{SPLIT1, "SPLIT1"},
|
||||
{SPLIT2, "SPLIT2"},
|
||||
{3, NULL},
|
||||
{4, NULL},
|
||||
{SPLIT3, "SPLIT3"},
|
||||
{SPLIT4, "SPLIT4"},
|
||||
{7, NULL},
|
||||
{254, NULL},
|
||||
{SPLIT5, "SPLIT5"},
|
||||
{256, NULL},
|
||||
};
|
||||
|
||||
START_TEST(test_enum_to_name_cont)
|
||||
{
|
||||
char *str = enum_to_name(test_enum_cont_names, name_tests_cont[_i].val);
|
||||
if (str)
|
||||
{
|
||||
ck_assert_str_eq(str, name_tests_cont[_i].str);
|
||||
}
|
||||
else
|
||||
{
|
||||
ck_assert(str == name_tests_cont[_i].str);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_enum_to_name_split)
|
||||
{
|
||||
char *str = enum_to_name(test_enum_split_names, name_tests_split[_i].val);
|
||||
if (str)
|
||||
{
|
||||
ck_assert_str_eq(str, name_tests_split[_i].str);
|
||||
}
|
||||
else
|
||||
{
|
||||
ck_assert(str == name_tests_split[_i].str);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* enum_from_name
|
||||
*/
|
||||
|
||||
static struct {
|
||||
int val;
|
||||
char *str;
|
||||
} enum_tests_cont[] = {
|
||||
{CONT1, "CONT1"},
|
||||
{CONT2, "CONT2"},
|
||||
{CONT2, "CoNt2"},
|
||||
{CONT3, "CONT3"},
|
||||
{CONT4, "CONT4"},
|
||||
{CONT5, "CONT5"},
|
||||
{-1, "asdf"},
|
||||
{-1, ""},
|
||||
{-1, NULL},
|
||||
}, enum_tests_split[] = {
|
||||
{SPLIT1, "SPLIT1"},
|
||||
{SPLIT1, "split1"},
|
||||
{SPLIT2, "SPLIT2"},
|
||||
{SPLIT2, "SpLiT2"},
|
||||
{SPLIT3, "SPLIT3"},
|
||||
{SPLIT4, "SPLIT4"},
|
||||
{SPLIT5, "SPLIT5"},
|
||||
{-1, "asdf"},
|
||||
{-1, ""},
|
||||
{-1, NULL},
|
||||
};
|
||||
|
||||
START_TEST(test_enum_from_name_cont)
|
||||
{
|
||||
int val = enum_from_name(test_enum_cont_names, enum_tests_cont[_i].str);
|
||||
ck_assert_int_eq(val, enum_tests_cont[_i].val);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_enum_from_name_split)
|
||||
{
|
||||
int val = enum_from_name(test_enum_split_names, enum_tests_split[_i].str);
|
||||
ck_assert_int_eq(val, enum_tests_split[_i].val);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* enum_printf_hook
|
||||
*/
|
||||
|
||||
static struct {
|
||||
int val;
|
||||
char *str;
|
||||
} printf_tests_cont[] = {
|
||||
{-1, "(-1)"},
|
||||
{CONT1, "CONT1"},
|
||||
{CONT2, "CONT2"},
|
||||
{CONT3, "CONT3"},
|
||||
{CONT4, "CONT4"},
|
||||
{CONT5, "CONT5"},
|
||||
{5, "(5)"},
|
||||
}, printf_tests_split[] = {
|
||||
{-1, "(-1)"},
|
||||
{0, "(0)"},
|
||||
{SPLIT1, "SPLIT1"},
|
||||
{SPLIT2, "SPLIT2"},
|
||||
{3, "(3)"},
|
||||
{4, "(4)"},
|
||||
{SPLIT3, "SPLIT3"},
|
||||
{SPLIT4, "SPLIT4"},
|
||||
{7, "(7)"},
|
||||
{254, "(254)"},
|
||||
{SPLIT5, "SPLIT5"},
|
||||
{256, "(256)"},
|
||||
};
|
||||
|
||||
START_TEST(test_enum_printf_hook_cont)
|
||||
{
|
||||
char buf[128];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%N", test_enum_cont_names, printf_tests_cont[_i].val);
|
||||
ck_assert_str_eq(printf_tests_cont[_i].str, buf);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_enum_printf_hook_split)
|
||||
{
|
||||
char buf[128];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%N", test_enum_split_names, printf_tests_split[_i].val);
|
||||
ck_assert_str_eq(printf_tests_split[_i].str, buf);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_enum_printf_hook_width)
|
||||
{
|
||||
char buf[128];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%10N", test_enum_cont_names, CONT1);
|
||||
ck_assert_str_eq(" CONT1", buf);
|
||||
snprintf(buf, sizeof(buf), "%-*N", 10, test_enum_cont_names, CONT2);
|
||||
ck_assert_str_eq("CONT2 ", buf);
|
||||
snprintf(buf, sizeof(buf), "%3N", test_enum_cont_names, CONT3);
|
||||
ck_assert_str_eq("CONT3", buf);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *enum_suite_create()
|
||||
{
|
||||
Suite *s;
|
||||
TCase *tc;
|
||||
|
||||
s = suite_create("enum");
|
||||
|
||||
tc = tcase_create("enum_to_name");
|
||||
tcase_add_loop_test(tc, test_enum_to_name_cont, 0, countof(name_tests_cont));
|
||||
tcase_add_loop_test(tc, test_enum_to_name_split, 0, countof(name_tests_split));
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("enum_from_name");
|
||||
tcase_add_loop_test(tc, test_enum_from_name_cont, 0, countof(enum_tests_cont));
|
||||
tcase_add_loop_test(tc, test_enum_from_name_split, 0, countof(enum_tests_split));
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("enum_printf_hook");
|
||||
tcase_add_loop_test(tc, test_enum_printf_hook_cont, 0, countof(printf_tests_cont));
|
||||
tcase_add_loop_test(tc, test_enum_printf_hook_split, 0, countof(printf_tests_split));
|
||||
tcase_add_test(tc, test_enum_printf_hook_width);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,409 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_suite.h"
|
||||
|
||||
#include <collections/enumerator.h>
|
||||
#include <collections/linked_list.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* token test
|
||||
*/
|
||||
|
||||
static const char *token_results1[] = { "abc", "cde", "efg" };
|
||||
static const char *token_results2[] = { "a", "b", "c" };
|
||||
|
||||
static struct {
|
||||
char *string;
|
||||
char *sep;
|
||||
char *trim;
|
||||
const char **results;
|
||||
} token_tests[] = {
|
||||
{"abc, cde, efg", ",", " ", token_results1},
|
||||
{" abc 1:2 cde;3 4efg5. ", ":;.,", " 12345", token_results1},
|
||||
{"abc.cde,efg", ",.", "", token_results1},
|
||||
{" abc cde efg ", " ", " ", token_results1},
|
||||
{"a'abc' c 'cde' cefg", " ", " abcd", token_results1},
|
||||
{"'abc' abc 'cde'd 'efg'", " ", " abcd", token_results1},
|
||||
|
||||
{"a, b, c", ",", " ", token_results2},
|
||||
{"a,b,c", ",", " ", token_results2},
|
||||
{" a 1:2 b;3 4c5. ", ":;.,", " 12345", token_results2},
|
||||
{"a.b,c", ",.", "", token_results2},
|
||||
{" a b c ", " ", " ", token_results2},
|
||||
};
|
||||
|
||||
START_TEST(test_token)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
const char **results;
|
||||
char *token;
|
||||
int tok = 0;
|
||||
|
||||
enumerator = enumerator_create_token(token_tests[_i].string,
|
||||
token_tests[_i].sep, token_tests[_i].trim);
|
||||
results = token_tests[_i].results;
|
||||
while (enumerator->enumerate(enumerator, &token))
|
||||
{
|
||||
switch (tok)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
ck_assert_str_eq(token, results[tok]);
|
||||
break;
|
||||
default:
|
||||
fail("unexpected token '%s'", token);
|
||||
}
|
||||
tok++;
|
||||
}
|
||||
fail_if(tok != 3, "not enough tokens (%d) extracted from '%s'",
|
||||
tok, token_tests[_i].string);
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* utilities for filtered, nested and cleaner tests
|
||||
*/
|
||||
|
||||
static int destroy_data_called;
|
||||
|
||||
START_SETUP(setup_destroy_data)
|
||||
{
|
||||
destroy_data_called = 0;
|
||||
}
|
||||
END_SETUP
|
||||
|
||||
START_TEARDOWN(teardown_destroy_data)
|
||||
{
|
||||
ck_assert_int_eq(destroy_data_called, 1);
|
||||
}
|
||||
END_TEARDOWN
|
||||
|
||||
static void destroy_data(void *data)
|
||||
{
|
||||
fail_if(data != (void*)101, "data does not match '101' in destructor");
|
||||
destroy_data_called++;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* filtered test
|
||||
*/
|
||||
|
||||
static bool filter(void *data, int *v, int *vo, int *w, int *wo,
|
||||
int *x, int *xo, int *y, int *yo, int *z, int *zo)
|
||||
{
|
||||
int val = *v;
|
||||
|
||||
*vo = val++;
|
||||
*wo = val++;
|
||||
*xo = val++;
|
||||
*yo = val++;
|
||||
*zo = val++;
|
||||
fail_if(data != (void*)101, "data does not match '101' in filter function");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bool filter_odd(void *data, int *item, int *out)
|
||||
{
|
||||
fail_if(data != (void*)101, "data does not match '101' in filter function");
|
||||
*out = *item;
|
||||
return *item % 2 == 0;
|
||||
}
|
||||
|
||||
START_TEST(test_filtered)
|
||||
{
|
||||
int round, v, w, x, y, z;
|
||||
linked_list_t *list;
|
||||
enumerator_t *enumerator;
|
||||
|
||||
list = linked_list_create_with_items((void*)1, (void*)2, (void*)3, (void*)4,
|
||||
(void*)5, NULL);
|
||||
|
||||
round = 1;
|
||||
enumerator = enumerator_create_filter(list->create_enumerator(list),
|
||||
(void*)filter, (void*)101, destroy_data);
|
||||
while (enumerator->enumerate(enumerator, &v, &w, &x, &y, &z))
|
||||
{
|
||||
ck_assert_int_eq(v, round);
|
||||
ck_assert_int_eq(w, round + 1);
|
||||
ck_assert_int_eq(x, round + 2);
|
||||
ck_assert_int_eq(y, round + 3);
|
||||
ck_assert_int_eq(z, round + 4);
|
||||
round++;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
ck_assert_int_eq(round, 6);
|
||||
|
||||
list->destroy(list);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_filtered_filter)
|
||||
{
|
||||
int count, x;
|
||||
linked_list_t *list;
|
||||
enumerator_t *enumerator;
|
||||
|
||||
list = linked_list_create_with_items((void*)1, (void*)2, (void*)3, (void*)4,
|
||||
(void*)5, NULL);
|
||||
|
||||
count = 0;
|
||||
/* should also work without destructor, so set this manually */
|
||||
destroy_data_called = 1;
|
||||
enumerator = enumerator_create_filter(list->create_enumerator(list),
|
||||
(void*)filter_odd, (void*)101, NULL);
|
||||
while (enumerator->enumerate(enumerator, &x))
|
||||
{
|
||||
ck_assert(x % 2 == 0);
|
||||
count++;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
ck_assert_int_eq(count, 2);
|
||||
|
||||
list->destroy(list);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* nested test
|
||||
*/
|
||||
|
||||
static enumerator_t* create_inner(linked_list_t *outer, void *data)
|
||||
{
|
||||
fail_if(data != (void*)101, "data does not match '101' in nested constr.");
|
||||
return outer->create_enumerator(outer);
|
||||
}
|
||||
|
||||
static enumerator_t* create_inner_null(void *outer, void *data)
|
||||
{
|
||||
ck_assert(outer == (void*)1);
|
||||
fail_if(data != (void*)101, "data does not match '101' in nested constr.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
START_TEST(test_nested)
|
||||
{
|
||||
linked_list_t *list, *l1, *l2, *l3;
|
||||
enumerator_t *enumerator;
|
||||
intptr_t x;
|
||||
int round;
|
||||
|
||||
l1 = linked_list_create_with_items((void*)1, (void*)2, NULL);
|
||||
l2 = linked_list_create();
|
||||
l3 = linked_list_create_with_items((void*)3, (void*)4, (void*)5, NULL);
|
||||
list = linked_list_create_with_items(l1, l2, l3, NULL);
|
||||
|
||||
round = 1;
|
||||
enumerator = enumerator_create_nested(list->create_enumerator(list),
|
||||
(void*)create_inner, (void*)101, destroy_data);
|
||||
while (enumerator->enumerate(enumerator, &x))
|
||||
{
|
||||
ck_assert_int_eq(round, x);
|
||||
round++;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
ck_assert_int_eq(round, 6);
|
||||
|
||||
list->destroy(list);
|
||||
l1->destroy(l1);
|
||||
l2->destroy(l2);
|
||||
l3->destroy(l3);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_nested_reset)
|
||||
{
|
||||
linked_list_t *list, *l1, *l2, *l3;
|
||||
enumerator_t *outer, *enumerator;
|
||||
intptr_t x;
|
||||
int count = 0;
|
||||
|
||||
l1 = linked_list_create_with_items((void*)1, (void*)2, NULL);
|
||||
l2 = linked_list_create();
|
||||
l3 = linked_list_create_with_items((void*)3, (void*)4, (void*)5, NULL);
|
||||
list = linked_list_create_with_items(l1, l2, l3, NULL);
|
||||
|
||||
outer = list->create_enumerator(list);
|
||||
enumerator = enumerator_create_nested(outer, (void*)create_inner,
|
||||
(void*)101, destroy_data);
|
||||
while (enumerator->enumerate(enumerator, &x))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
ck_assert_int_eq(count, 5);
|
||||
|
||||
list->reset_enumerator(list, outer);
|
||||
ck_assert(enumerator->enumerate(enumerator, &x));
|
||||
ck_assert_int_eq(x, 1);
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
list->destroy(list);
|
||||
l1->destroy(l1);
|
||||
l2->destroy(l2);
|
||||
l3->destroy(l3);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_nested_empty)
|
||||
{
|
||||
linked_list_t *list;
|
||||
enumerator_t *enumerator;
|
||||
intptr_t x;
|
||||
int count;
|
||||
|
||||
list = linked_list_create();
|
||||
count = 0;
|
||||
enumerator = enumerator_create_nested(list->create_enumerator(list),
|
||||
(void*)create_inner, (void*)101, destroy_data);
|
||||
while (enumerator->enumerate(enumerator, &x))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
ck_assert_int_eq(count, 0);
|
||||
|
||||
list->destroy(list);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_nested_null)
|
||||
{
|
||||
linked_list_t *list;
|
||||
enumerator_t *enumerator;
|
||||
intptr_t x;
|
||||
int count;
|
||||
|
||||
list = linked_list_create_with_items((void*)1, NULL);
|
||||
|
||||
count = 0;
|
||||
/* should also work without destructor, so set this manually */
|
||||
destroy_data_called = 1;
|
||||
enumerator = enumerator_create_nested(list->create_enumerator(list),
|
||||
(void*)create_inner_null, (void*)101, NULL);
|
||||
while (enumerator->enumerate(enumerator, &x))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
ck_assert_int_eq(count, 0);
|
||||
|
||||
list->destroy(list);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* cleaner test
|
||||
*/
|
||||
|
||||
START_TEST(test_cleaner)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
linked_list_t *list;
|
||||
intptr_t x;
|
||||
int round;
|
||||
|
||||
list = linked_list_create_with_items((void*)1, (void*)2, NULL);
|
||||
|
||||
round = 1;
|
||||
enumerator = enumerator_create_cleaner(list->create_enumerator(list),
|
||||
destroy_data, (void*)101);
|
||||
while (enumerator->enumerate(enumerator, &x))
|
||||
{
|
||||
ck_assert_int_eq(round, x);
|
||||
round++;
|
||||
}
|
||||
ck_assert_int_eq(round, 3);
|
||||
enumerator->destroy(enumerator);
|
||||
list->destroy(list);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* single test
|
||||
*/
|
||||
|
||||
static void single_cleanup(void *data)
|
||||
{
|
||||
ck_assert_int_eq((intptr_t)data, 1);
|
||||
}
|
||||
|
||||
static void do_test_single(enumerator_t *enumerator)
|
||||
{
|
||||
intptr_t x;
|
||||
|
||||
ck_assert(enumerator->enumerate(enumerator, &x));
|
||||
ck_assert_int_eq(x, 1);
|
||||
ck_assert(!enumerator->enumerate(enumerator, &x));
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
START_TEST(test_single)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
|
||||
enumerator = enumerator_create_single((void*)1, NULL);
|
||||
do_test_single(enumerator);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_single_cleanup)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
|
||||
enumerator = enumerator_create_single((void*)1, single_cleanup);
|
||||
do_test_single(enumerator);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *enumerator_suite_create()
|
||||
{
|
||||
Suite *s;
|
||||
TCase *tc;
|
||||
|
||||
s = suite_create("enumerator");
|
||||
|
||||
tc = tcase_create("tokens");
|
||||
tcase_add_loop_test(tc, test_token, 0, countof(token_tests));
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("filtered");
|
||||
tcase_add_checked_fixture(tc, setup_destroy_data, teardown_destroy_data);
|
||||
tcase_add_test(tc, test_filtered);
|
||||
tcase_add_test(tc, test_filtered_filter);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("nested");
|
||||
tcase_add_checked_fixture(tc, setup_destroy_data, teardown_destroy_data);
|
||||
tcase_add_test(tc, test_nested);
|
||||
tcase_add_test(tc, test_nested_reset);
|
||||
tcase_add_test(tc, test_nested_empty);
|
||||
tcase_add_test(tc, test_nested_null);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("cleaner");
|
||||
tcase_add_checked_fixture(tc, setup_destroy_data, teardown_destroy_data);
|
||||
tcase_add_test(tc, test_cleaner);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("single");
|
||||
tcase_add_test(tc, test_single);
|
||||
tcase_add_test(tc, test_single_cleanup);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,346 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 Tobias Brunner
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_suite.h"
|
||||
|
||||
#include <collections/hashtable.h>
|
||||
#include <utils/chunk.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* string hash table functions
|
||||
*/
|
||||
|
||||
static u_int hash(char *key)
|
||||
{
|
||||
return chunk_hash(chunk_from_str(key));
|
||||
}
|
||||
|
||||
static bool equals(char *key1, char *key2)
|
||||
{
|
||||
return streq(key1, key2);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* test fixture
|
||||
*/
|
||||
|
||||
static hashtable_t *ht;
|
||||
|
||||
START_SETUP(setup_ht)
|
||||
{
|
||||
ht = hashtable_create((hashtable_hash_t)hash,
|
||||
(hashtable_equals_t)equals, 0);
|
||||
ck_assert_int_eq(ht->get_count(ht), 0);
|
||||
}
|
||||
END_SETUP
|
||||
|
||||
START_TEARDOWN(teardown_ht)
|
||||
{
|
||||
ht->destroy(ht);
|
||||
}
|
||||
END_TEARDOWN
|
||||
|
||||
/*******************************************************************************
|
||||
* put/get
|
||||
*/
|
||||
|
||||
START_TEST(test_put_get)
|
||||
{
|
||||
char *k1 = "key1", *k2 = "key2", *k3 = "key3";
|
||||
char *v1 = "val1", *v2 = "val2", *v3 = "val3", *value;
|
||||
|
||||
value = ht->put(ht, k1, v1);
|
||||
ck_assert_int_eq(ht->get_count(ht), 1);
|
||||
ck_assert(streq(ht->get(ht, k1), v1));
|
||||
ck_assert(ht->get(ht, k2) == NULL);
|
||||
ck_assert(ht->get(ht, k3) == NULL);
|
||||
ck_assert(value == NULL);
|
||||
|
||||
ht->put(ht, k2, v2);
|
||||
ht->put(ht, k3, v3);
|
||||
ck_assert_int_eq(ht->get_count(ht), 3);
|
||||
ck_assert(streq(ht->get(ht, k1), v1));
|
||||
ck_assert(streq(ht->get(ht, k2), v2));
|
||||
ck_assert(streq(ht->get(ht, k3), v3));
|
||||
|
||||
value = ht->put(ht, k2, v1);
|
||||
ck_assert_int_eq(ht->get_count(ht), 3);
|
||||
ck_assert(streq(value, v2));
|
||||
ck_assert(streq(ht->get(ht, k2), v1));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* get_match
|
||||
*/
|
||||
|
||||
static u_int hash_match(char *key)
|
||||
{
|
||||
return chunk_hash(chunk_create(key, 4));
|
||||
}
|
||||
|
||||
static bool equal_match(char *key1, char *key2)
|
||||
{
|
||||
if (!strneq(key1, key2, 4))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
/* look for an item with a key < than what we look for */
|
||||
return strcmp(key1, key2) >= 0;
|
||||
}
|
||||
|
||||
START_TEST(test_get_match)
|
||||
{
|
||||
char *k1 = "key1_a", *k2 = "key2", *k3 = "key1_b", *k4 = "key1_c";
|
||||
char *v1 = "val1", *v2 = "val2", *v3 = "val3", *value;
|
||||
|
||||
ht = hashtable_create((hashtable_hash_t)hash_match,
|
||||
(hashtable_equals_t)equals, 0);
|
||||
|
||||
ht->put(ht, k1, v1);
|
||||
ht->put(ht, k2, v2);
|
||||
value = ht->put(ht, k3, v3);
|
||||
ck_assert_int_eq(ht->get_count(ht), 3);
|
||||
ck_assert(streq(ht->get(ht, k1), v1));
|
||||
ck_assert(streq(ht->get(ht, k2), v2));
|
||||
ck_assert(streq(ht->get(ht, k3), v3));
|
||||
ck_assert(value == NULL);
|
||||
|
||||
value = ht->get_match(ht, k1, (hashtable_equals_t)equal_match);
|
||||
ck_assert(value != NULL);
|
||||
ck_assert(streq(value, v1));
|
||||
value = ht->get_match(ht, k2, (hashtable_equals_t)equal_match);
|
||||
ck_assert(value != NULL);
|
||||
ck_assert(streq(value, v2));
|
||||
value = ht->get_match(ht, k3, (hashtable_equals_t)equal_match);
|
||||
ck_assert(value != NULL);
|
||||
ck_assert(streq(value, v1));
|
||||
value = ht->get_match(ht, k4, (hashtable_equals_t)equal_match);
|
||||
ck_assert(value != NULL);
|
||||
ck_assert(streq(value, v1));
|
||||
|
||||
ht->destroy(ht);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* remove
|
||||
*/
|
||||
|
||||
static void do_remove(char *k1, char *k2, char *k3)
|
||||
{
|
||||
char *v1 = "val1", *v2 = "val2", *v3 = "val3", *value;
|
||||
|
||||
ht->put(ht, k1, v1);
|
||||
ht->put(ht, k2, v2);
|
||||
ht->put(ht, k3, v3);
|
||||
|
||||
value = ht->remove(ht, k2);
|
||||
ck_assert_int_eq(ht->get_count(ht), 2);
|
||||
ck_assert(streq(ht->get(ht, k1), v1));
|
||||
ck_assert(streq(ht->get(ht, k3), v3));
|
||||
ck_assert(streq(value, v2));
|
||||
ck_assert(ht->get(ht, k2) == NULL);
|
||||
|
||||
value = ht->remove(ht, k2);
|
||||
ck_assert_int_eq(ht->get_count(ht), 2);
|
||||
ck_assert(value == NULL);
|
||||
|
||||
value = ht->remove(ht, k1);
|
||||
value = ht->remove(ht, k3);
|
||||
ck_assert_int_eq(ht->get_count(ht), 0);
|
||||
ck_assert(ht->get(ht, k1) == NULL);
|
||||
ck_assert(ht->get(ht, k2) == NULL);
|
||||
ck_assert(ht->get(ht, k3) == NULL);
|
||||
}
|
||||
|
||||
START_TEST(test_remove)
|
||||
{
|
||||
char *k1 = "key1", *k2 = "key2", *k3 = "key3";
|
||||
|
||||
do_remove(k1, k2, k3);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_remove_one_bucket)
|
||||
{
|
||||
char *k1 = "key1_a", *k2 = "key1_b", *k3 = "key1_c";
|
||||
|
||||
ht->destroy(ht);
|
||||
/* set a capacity to avoid rehashing, which would change the items' order */
|
||||
ht = hashtable_create((hashtable_hash_t)hash_match,
|
||||
(hashtable_equals_t)equals, 8);
|
||||
|
||||
do_remove(k1, k2, k3);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* enumerator
|
||||
*/
|
||||
|
||||
START_TEST(test_enumerator)
|
||||
{
|
||||
char *k1 = "key1", *k2 = "key2", *k3 = "key3", *key;
|
||||
char *v1 = "val1", *v2 = "val2", *v3 = "val3", *value;
|
||||
enumerator_t *enumerator;
|
||||
int count;
|
||||
|
||||
ht->put(ht, k1, v1);
|
||||
ht->put(ht, k2, v2);
|
||||
ht->put(ht, k3, v3);
|
||||
|
||||
count = 0;
|
||||
enumerator = ht->create_enumerator(ht);
|
||||
while (enumerator->enumerate(enumerator, &key, &value))
|
||||
{
|
||||
ck_assert(streq(key, k1) || streq(key, k2) || streq(key, k3));
|
||||
ck_assert(streq(value, v1) || streq(value, v2) || streq(value, v3));
|
||||
ck_assert(!streq(key, k1) || streq(value, v1));
|
||||
ck_assert(!streq(key, k2) || streq(value, v2));
|
||||
ck_assert(!streq(key, k3) || streq(value, v3));
|
||||
count++;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
ck_assert_int_eq(count, 3);
|
||||
|
||||
count = 0;
|
||||
enumerator = ht->create_enumerator(ht);
|
||||
while (enumerator->enumerate(enumerator, NULL, NULL))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
ck_assert_int_eq(count, 3);
|
||||
|
||||
value = ht->remove(ht, k1);
|
||||
value = ht->remove(ht, k2);
|
||||
value = ht->remove(ht, k3);
|
||||
|
||||
count = 0;
|
||||
enumerator = ht->create_enumerator(ht);
|
||||
while (enumerator->enumerate(enumerator, &key, &value))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
ck_assert_int_eq(count, 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* remove_at
|
||||
*/
|
||||
|
||||
static void do_remove_at(char *k1, char *k2, char *k3)
|
||||
{
|
||||
char *v1 = "val1", *v2 = "val2", *v3 = "val3", *value, *key;
|
||||
enumerator_t *enumerator;
|
||||
|
||||
ht->put(ht, k1, v1);
|
||||
ht->put(ht, k2, v2);
|
||||
ht->put(ht, k3, v3);
|
||||
|
||||
enumerator = ht->create_enumerator(ht);
|
||||
ht->remove_at(ht, enumerator);
|
||||
while (enumerator->enumerate(enumerator, &key, &value))
|
||||
{
|
||||
if (streq(key, k2))
|
||||
{
|
||||
ht->remove_at(ht, enumerator);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
ck_assert_int_eq(ht->get_count(ht), 2);
|
||||
ck_assert(ht->get(ht, k1) != NULL);
|
||||
ck_assert(ht->get(ht, k3) != NULL);
|
||||
ck_assert(ht->get(ht, k2) == NULL);
|
||||
|
||||
ht->put(ht, k2, v2);
|
||||
|
||||
ck_assert_int_eq(ht->get_count(ht), 3);
|
||||
ck_assert(ht->get(ht, k1) != NULL);
|
||||
ck_assert(ht->get(ht, k2) != NULL);
|
||||
ck_assert(ht->get(ht, k3) != NULL);
|
||||
|
||||
enumerator = ht->create_enumerator(ht);
|
||||
while (enumerator->enumerate(enumerator, &key, &value))
|
||||
{
|
||||
ht->remove_at(ht, enumerator);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
ck_assert_int_eq(ht->get_count(ht), 0);
|
||||
ck_assert(ht->get(ht, k1) == NULL);
|
||||
ck_assert(ht->get(ht, k2) == NULL);
|
||||
ck_assert(ht->get(ht, k3) == NULL);
|
||||
}
|
||||
|
||||
START_TEST(test_remove_at)
|
||||
{
|
||||
char *k1 = "key1", *k2 = "key2", *k3 = "key3";
|
||||
|
||||
do_remove_at(k1, k2, k3);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_remove_at_one_bucket)
|
||||
{
|
||||
char *k1 = "key1_a", *k2 = "key1_b", *k3 = "key1_c";
|
||||
|
||||
ht->destroy(ht);
|
||||
/* set a capacity to avoid rehashing, which would change the items' order */
|
||||
ht = hashtable_create((hashtable_hash_t)hash_match,
|
||||
(hashtable_equals_t)equals, 8);
|
||||
do_remove_at(k1, k2, k3);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *hashtable_suite_create()
|
||||
{
|
||||
Suite *s;
|
||||
TCase *tc;
|
||||
|
||||
s = suite_create("hashtable");
|
||||
|
||||
tc = tcase_create("put/get");
|
||||
tcase_add_checked_fixture(tc, setup_ht, teardown_ht);
|
||||
tcase_add_test(tc, test_put_get);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("get_match");
|
||||
tcase_add_test(tc, test_get_match);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("remove");
|
||||
tcase_add_checked_fixture(tc, setup_ht, teardown_ht);
|
||||
tcase_add_test(tc, test_remove);
|
||||
tcase_add_test(tc, test_remove_one_bucket);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("enumerator");
|
||||
tcase_add_checked_fixture(tc, setup_ht, teardown_ht);
|
||||
tcase_add_test(tc, test_enumerator);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("remove_at");
|
||||
tcase_add_checked_fixture(tc, setup_ht, teardown_ht);
|
||||
tcase_add_test(tc, test_remove_at);
|
||||
tcase_add_test(tc, test_remove_at_one_bucket);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,651 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_suite.h"
|
||||
|
||||
#include <networking/host.h>
|
||||
|
||||
/**
|
||||
* Verify a netmask (a number of set bits starting at byte 0)
|
||||
* Can also be used to check for %any (mask == 0)
|
||||
*/
|
||||
static void verify_netmask(chunk_t addr, int mask)
|
||||
{
|
||||
int byte, bit;
|
||||
|
||||
for (byte = 0; byte < addr.len; byte++)
|
||||
{
|
||||
for (bit = 7; bit >= 0; bit--)
|
||||
{
|
||||
int val = (addr.ptr[byte] >> bit) & 0x01;
|
||||
if (mask-- > 0)
|
||||
{
|
||||
ck_assert_int_eq(val, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ck_assert_int_eq(val, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* host_create_any
|
||||
*/
|
||||
|
||||
static void verify_any(host_t *host, int family, u_int16_t port)
|
||||
{
|
||||
verify_netmask(host->get_address(host), 0);
|
||||
ck_assert(host->is_anyaddr(host));
|
||||
ck_assert_int_eq(host->get_port(host), port);
|
||||
ck_assert_int_eq(host->get_family(host), family);
|
||||
}
|
||||
|
||||
static void test_create_any(int family)
|
||||
{
|
||||
host_t *host;
|
||||
|
||||
host = host_create_any(family);
|
||||
verify_any(host, family, 0);
|
||||
host->destroy(host);
|
||||
}
|
||||
|
||||
START_TEST(test_create_any_v4)
|
||||
{
|
||||
test_create_any(AF_INET);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_create_any_v6)
|
||||
{
|
||||
test_create_any(AF_INET6);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_create_any_other)
|
||||
{
|
||||
host_t *host;
|
||||
|
||||
host = host_create_any(AF_UNSPEC);
|
||||
ck_assert(host == NULL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* host_create_from_string
|
||||
*/
|
||||
|
||||
static void verify_address(host_t *host, chunk_t addr, int family, u_int16_t port)
|
||||
{
|
||||
ck_assert(chunk_equals(host->get_address(host), addr));
|
||||
ck_assert(!host->is_anyaddr(host));
|
||||
ck_assert_int_eq(host->get_port(host), port);
|
||||
ck_assert_int_eq(host->get_family(host), family);
|
||||
}
|
||||
|
||||
static const chunk_t addr_v4 = chunk_from_chars(0xc0, 0xa8, 0x00, 0x01);
|
||||
static const chunk_t addr_v6 = chunk_from_chars(0xfe, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01);
|
||||
|
||||
START_TEST(test_create_from_string_v4)
|
||||
{
|
||||
host_t *host;
|
||||
|
||||
host = host_create_from_string("%any", 500);
|
||||
verify_any(host, AF_INET, 500);
|
||||
host->destroy(host);
|
||||
|
||||
host = host_create_from_string("%any4", 500);
|
||||
verify_any(host, AF_INET, 500);
|
||||
host->destroy(host);
|
||||
|
||||
host = host_create_from_string("0.0.0.0", 500);
|
||||
verify_any(host, AF_INET, 500);
|
||||
host->destroy(host);
|
||||
|
||||
host = host_create_from_string("192.168.0.1", 500);
|
||||
verify_address(host, addr_v4, AF_INET, 500);
|
||||
host->destroy(host);
|
||||
|
||||
host = host_create_from_string("192.168.0.1::500", 500);
|
||||
ck_assert(host == NULL);
|
||||
host = host_create_from_string("123.456.789.012", 500);
|
||||
ck_assert(host == NULL);
|
||||
host = host_create_from_string("1.1.1.1.1.1.1.1", 500);
|
||||
ck_assert(host == NULL);
|
||||
host = host_create_from_string("foo.b.a.r", 500);
|
||||
ck_assert(host == NULL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_create_from_string_any_v6)
|
||||
{
|
||||
host_t *host;
|
||||
|
||||
host = host_create_from_string("%any6", 500);
|
||||
verify_any(host, AF_INET6, 500);
|
||||
host->destroy(host);
|
||||
|
||||
host = host_create_from_string("::", 500);
|
||||
verify_any(host, AF_INET6, 500);
|
||||
host->destroy(host);
|
||||
|
||||
host = host_create_from_string("fec1::1", 500);
|
||||
verify_address(host, addr_v6, AF_INET6, 500);
|
||||
host->destroy(host);
|
||||
|
||||
host = host_create_from_string("fec1::1.500", 500);
|
||||
ck_assert(host == NULL);
|
||||
host = host_create_from_string("f::e::c::1::1", 500);
|
||||
ck_assert(host == NULL);
|
||||
host = host_create_from_string("foo::bar", 500);
|
||||
ck_assert(host == NULL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* host_create_from_string_and_family
|
||||
*/
|
||||
|
||||
static void test_create_from_string_and_family_any(char *string, int family,
|
||||
int expected)
|
||||
{
|
||||
host_t *host;
|
||||
|
||||
host = host_create_from_string_and_family(string, family, 500);
|
||||
if (expected == AF_UNSPEC)
|
||||
{
|
||||
ck_assert(host == NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
verify_any(host, expected, 500);
|
||||
host->destroy(host);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_create_from_string_and_family_addr(char *string, chunk_t addr,
|
||||
int family, int expected)
|
||||
{
|
||||
host_t *host;
|
||||
|
||||
host = host_create_from_string_and_family(string, family, 500);
|
||||
if (expected == AF_UNSPEC)
|
||||
{
|
||||
ck_assert(host == NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
verify_address(host, addr, expected, 500);
|
||||
host->destroy(host);
|
||||
}
|
||||
}
|
||||
|
||||
START_TEST(test_create_from_string_and_family_v4)
|
||||
{
|
||||
test_create_from_string_and_family_any("%any", AF_INET, AF_INET);
|
||||
test_create_from_string_and_family_any("%any4", AF_INET, AF_INET);
|
||||
test_create_from_string_and_family_any("0.0.0.0", AF_INET, AF_INET);
|
||||
|
||||
test_create_from_string_and_family_any("%any4", AF_INET6, AF_UNSPEC);
|
||||
test_create_from_string_and_family_any("0.0.0.0", AF_INET6, AF_UNSPEC);
|
||||
|
||||
test_create_from_string_and_family_addr("192.168.0.1", addr_v4, AF_INET, AF_INET);
|
||||
test_create_from_string_and_family_addr("192.168.0.1", addr_v4, AF_INET6, AF_UNSPEC);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_create_from_string_and_family_v6)
|
||||
{
|
||||
test_create_from_string_and_family_any("%any", AF_INET6, AF_INET6);
|
||||
test_create_from_string_and_family_any("%any6", AF_INET6, AF_INET6);
|
||||
test_create_from_string_and_family_any("::", AF_INET6, AF_INET6);
|
||||
|
||||
test_create_from_string_and_family_any("%any6", AF_INET, AF_UNSPEC);
|
||||
test_create_from_string_and_family_any("::", AF_INET, AF_UNSPEC);
|
||||
|
||||
test_create_from_string_and_family_addr("fec1::1", addr_v6, AF_INET6, AF_INET6);
|
||||
test_create_from_string_and_family_addr("fec1::1", addr_v6, AF_INET, AF_UNSPEC);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_create_from_string_and_family_other)
|
||||
{
|
||||
test_create_from_string_and_family_any("%any", AF_UNSPEC, AF_INET);
|
||||
test_create_from_string_and_family_any("%any4", AF_UNSPEC, AF_INET);
|
||||
test_create_from_string_and_family_any("0.0.0.0", AF_UNSPEC, AF_INET);
|
||||
|
||||
test_create_from_string_and_family_any("%any6", AF_UNSPEC, AF_INET6);
|
||||
test_create_from_string_and_family_any("::", AF_UNSPEC, AF_INET6);
|
||||
|
||||
test_create_from_string_and_family_addr("192.168.0.1", addr_v4, AF_UNSPEC, AF_INET);
|
||||
test_create_from_string_and_family_addr("fec1::1", addr_v6, AF_UNSPEC, AF_INET6);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* host_create_from_sockaddr
|
||||
*/
|
||||
|
||||
START_TEST(test_create_from_sockaddr_v4)
|
||||
{
|
||||
struct sockaddr_in addr = {
|
||||
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
|
||||
.sin_len = sizeof(struct sockaddr_in),
|
||||
#endif
|
||||
.sin_family = AF_INET,
|
||||
.sin_port = htons(500),
|
||||
}, *val;
|
||||
socklen_t *socklen;
|
||||
host_t *host;
|
||||
|
||||
host = host_create_from_sockaddr((sockaddr_t*)&addr);
|
||||
verify_any(host, AF_INET, 500);
|
||||
val = (struct sockaddr_in*)host->get_sockaddr(host);
|
||||
ck_assert(memeq(&addr, val, sizeof(addr)));
|
||||
socklen = host->get_sockaddr_len(host);
|
||||
ck_assert(*socklen == sizeof(addr));
|
||||
host->destroy(host);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_create_from_sockaddr_v6)
|
||||
{
|
||||
struct sockaddr_in6 addr = {
|
||||
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
|
||||
.sin6_len = sizeof(struct sockaddr_in6),
|
||||
#endif
|
||||
.sin6_family = AF_INET6,
|
||||
.sin6_port = htons(500),
|
||||
}, *val;
|
||||
socklen_t *socklen;
|
||||
host_t *host;
|
||||
|
||||
host = host_create_from_sockaddr((sockaddr_t*)&addr);
|
||||
verify_any(host, AF_INET6, 500);
|
||||
val = (struct sockaddr_in6*)host->get_sockaddr(host);
|
||||
ck_assert(memeq(&addr, val, sizeof(addr)));
|
||||
socklen = host->get_sockaddr_len(host);
|
||||
ck_assert(*socklen == sizeof(addr));
|
||||
host->destroy(host);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_create_from_sockaddr_other)
|
||||
{
|
||||
struct sockaddr_un addr = {
|
||||
.sun_family = AF_UNIX,
|
||||
};
|
||||
host_t *host;
|
||||
|
||||
host = host_create_from_sockaddr((sockaddr_t*)&addr);
|
||||
ck_assert(host == NULL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* host_create_from_chunk
|
||||
*/
|
||||
|
||||
START_TEST(test_create_from_chunk_v4)
|
||||
{
|
||||
host_t *host;
|
||||
|
||||
host = host_create_from_chunk(AF_INET, addr_v4, 500);
|
||||
verify_address(host, addr_v4, AF_INET, 500);
|
||||
host->destroy(host);
|
||||
|
||||
host = host_create_from_chunk(AF_UNSPEC, addr_v4, 500);
|
||||
verify_address(host, addr_v4, AF_INET, 500);
|
||||
host->destroy(host);
|
||||
|
||||
host = host_create_from_chunk(AF_INET, chunk_empty, 500);
|
||||
ck_assert(host == NULL);
|
||||
host = host_create_from_chunk(AF_UNSPEC, chunk_empty, 500);
|
||||
ck_assert(host == NULL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_create_from_chunk_v6)
|
||||
{
|
||||
host_t *host;
|
||||
|
||||
host = host_create_from_chunk(AF_INET6, addr_v6, 500);
|
||||
verify_address(host, addr_v6, AF_INET6, 500);
|
||||
host->destroy(host);
|
||||
|
||||
host = host_create_from_chunk(AF_UNSPEC, addr_v6, 500);
|
||||
verify_address(host, addr_v6, AF_INET6, 500);
|
||||
host->destroy(host);
|
||||
|
||||
host = host_create_from_chunk(AF_INET6, chunk_empty, 500);
|
||||
ck_assert(host == NULL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_create_from_chunk_other)
|
||||
{
|
||||
host_t *host;
|
||||
|
||||
host = host_create_from_chunk(AF_UNIX, addr_v6, 500);
|
||||
ck_assert(host == NULL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* host_create_from_subnet
|
||||
*/
|
||||
|
||||
START_TEST(test_create_from_subnet_v4)
|
||||
{
|
||||
host_t *host;
|
||||
int bits = -1;
|
||||
|
||||
host = host_create_from_subnet("0.0.0.0/0", &bits);
|
||||
verify_any(host, AF_INET, 0);
|
||||
ck_assert_int_eq(bits, 0);
|
||||
host->destroy(host);
|
||||
|
||||
host = host_create_from_subnet("192.168.0.1", &bits);
|
||||
verify_address(host, addr_v4, AF_INET, 0);
|
||||
ck_assert_int_eq(bits, 32);
|
||||
host->destroy(host);
|
||||
|
||||
host = host_create_from_subnet("192.168.0.1/24", &bits);
|
||||
verify_address(host, addr_v4, AF_INET, 0);
|
||||
ck_assert_int_eq(bits, 24);
|
||||
host->destroy(host);
|
||||
|
||||
host = host_create_from_subnet("foo.b.a.r", &bits);
|
||||
ck_assert(host == NULL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_create_from_subnet_v6)
|
||||
{
|
||||
host_t *host;
|
||||
int bits = -1;
|
||||
|
||||
host = host_create_from_subnet("::/0", &bits);
|
||||
verify_any(host, AF_INET6, 0);
|
||||
ck_assert_int_eq(bits, 0);
|
||||
host->destroy(host);
|
||||
|
||||
host = host_create_from_subnet("fec1::1", &bits);
|
||||
verify_address(host, addr_v6, AF_INET6, 0);
|
||||
ck_assert_int_eq(bits, 128);
|
||||
host->destroy(host);
|
||||
|
||||
host = host_create_from_subnet("fec1::1/64", &bits);
|
||||
verify_address(host, addr_v6, AF_INET6, 0);
|
||||
ck_assert_int_eq(bits, 64);
|
||||
host->destroy(host);
|
||||
|
||||
host = host_create_from_subnet("foo::bar", &bits);
|
||||
ck_assert(host == NULL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* host_create_netmask
|
||||
*/
|
||||
|
||||
static void test_create_netmask(int family)
|
||||
{
|
||||
host_t *netmask;
|
||||
int i, len = (family == AF_INET) ? 32 : 128;
|
||||
|
||||
netmask = host_create_netmask(family, -1);
|
||||
ck_assert(netmask == NULL);
|
||||
for (i = 0; i <= len; i++)
|
||||
{
|
||||
netmask = host_create_netmask(family, i);
|
||||
verify_netmask(netmask->get_address(netmask), i);
|
||||
netmask->destroy(netmask);
|
||||
}
|
||||
netmask = host_create_netmask(family, len + 1);
|
||||
ck_assert(netmask == NULL);
|
||||
}
|
||||
|
||||
START_TEST(test_create_netmask_v4)
|
||||
{
|
||||
test_create_netmask(AF_INET);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_create_netmask_v6)
|
||||
{
|
||||
test_create_netmask(AF_INET6);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_create_netmask_other)
|
||||
{
|
||||
host_t *netmask;
|
||||
|
||||
netmask = host_create_netmask(AF_UNSPEC, 0);
|
||||
ck_assert(netmask == NULL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* equals, ip_equals
|
||||
*/
|
||||
|
||||
START_TEST(test_equals)
|
||||
{
|
||||
host_t *a, *b;
|
||||
|
||||
a = host_create_from_string("192.168.0.1", 500);
|
||||
b = host_create_from_string("192.168.0.1", 0);
|
||||
ck_assert(!a->equals(a, b));
|
||||
ck_assert(!b->equals(b, a));
|
||||
ck_assert(a->ip_equals(a, b));
|
||||
ck_assert(b->ip_equals(b, a));
|
||||
b->set_port(b, 500);
|
||||
ck_assert(a->equals(a, b));
|
||||
ck_assert(b->equals(b, a));
|
||||
ck_assert(a->ip_equals(a, b));
|
||||
ck_assert(b->ip_equals(b, a));
|
||||
b->destroy(b);
|
||||
b = host_create_from_string("192.168.0.2", 500);
|
||||
ck_assert(!a->ip_equals(a, b));
|
||||
ck_assert(!a->equals(a, b));
|
||||
b->destroy(b);
|
||||
|
||||
b = host_create_from_string("fec1::1", 500);
|
||||
ck_assert(!a->ip_equals(a, b));
|
||||
ck_assert(!a->equals(a, b));
|
||||
a->destroy(a);
|
||||
a = host_create_from_string("fec1::1", 500);
|
||||
ck_assert(a->equals(a, b));
|
||||
ck_assert(a->ip_equals(a, b));
|
||||
a->destroy(a);
|
||||
b->destroy(b);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_equals_any)
|
||||
{
|
||||
host_t *a, *b;
|
||||
|
||||
a = host_create_from_string("%any", 500);
|
||||
b = host_create_from_string("%any", 0);
|
||||
ck_assert(!a->equals(a, b));
|
||||
ck_assert(a->ip_equals(a, b));
|
||||
b->set_port(b, 500);
|
||||
ck_assert(a->equals(a, b));
|
||||
ck_assert(a->ip_equals(a, b));
|
||||
b->destroy(b);
|
||||
b = host_create_from_string("%any6", 0);
|
||||
ck_assert(a->ip_equals(a, b));
|
||||
ck_assert(!a->equals(a, b));
|
||||
b->set_port(b, 500);
|
||||
ck_assert(a->ip_equals(a, b));
|
||||
ck_assert(a->equals(a, b));
|
||||
a->destroy(a);
|
||||
b->destroy(b);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* clone
|
||||
*/
|
||||
|
||||
START_TEST(test_clone)
|
||||
{
|
||||
host_t *a, *b;
|
||||
|
||||
a = host_create_from_string("192.168.0.1", 500);
|
||||
b = a->clone(a);
|
||||
ck_assert(a != b);
|
||||
ck_assert(a->equals(a, b));
|
||||
a->destroy(a);
|
||||
b->destroy(b);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* printf hook
|
||||
*/
|
||||
|
||||
static struct {
|
||||
char *addr;
|
||||
u_int16_t port;
|
||||
/* results for %H, %+H, %#H (falls back to [0]) */
|
||||
char *result[3];
|
||||
} printf_data[] = {
|
||||
{NULL, 0, { "(null)" }},
|
||||
{NULL, 500, { "(null)" }},
|
||||
{"%any", 0, { "%any", "0.0.0.0", "0.0.0.0[0]" }},
|
||||
{"%any", 500, { "%any", "0.0.0.0", "0.0.0.0[500]" }},
|
||||
{"%any6", 0, { "%any6", "::", "::[0]" }},
|
||||
{"%any6", 500, { "%any6", "::", "::[500]" }},
|
||||
{"192.168.0.1", 0, { "192.168.0.1", "192.168.0.1", "192.168.0.1[0]" }},
|
||||
{"192.168.0.1", 500, { "192.168.0.1", "192.168.0.1", "192.168.0.1[500]" }},
|
||||
{"fec1::1", 0, { "fec1::1", "fec1::1", "fec1::1[0]" }},
|
||||
{"fec1::1", 500, { "fec1::1", "fec1::1", "fec1::1[500]" }},
|
||||
};
|
||||
|
||||
static void verify_printf(host_t *host, const char *format, char *expected)
|
||||
{
|
||||
char buf[64];
|
||||
|
||||
snprintf(buf, sizeof(buf), format, host);
|
||||
ck_assert_str_eq(expected, buf);
|
||||
}
|
||||
|
||||
START_TEST(test_printf_hook)
|
||||
{
|
||||
static const char *formats[] = { "%H", "%+H", "%#H" };
|
||||
host_t *host = NULL;
|
||||
char *expected;
|
||||
int i;
|
||||
|
||||
if (printf_data[_i].addr)
|
||||
{
|
||||
host = host_create_from_string(printf_data[_i].addr,
|
||||
printf_data[_i].port);
|
||||
}
|
||||
for (i = 0; i < countof(formats); i++)
|
||||
{
|
||||
expected = printf_data[_i].result[i];
|
||||
expected = expected ?: printf_data[_i].result[0];
|
||||
verify_printf(host, formats[i], expected);
|
||||
}
|
||||
DESTROY_IF(host);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_printf_hook_align)
|
||||
{
|
||||
host_t *host;
|
||||
|
||||
verify_printf(NULL, "%14H", " (null)");
|
||||
verify_printf(NULL, "%-14H", "(null) ");
|
||||
|
||||
host = host_create_from_string("192.168.0.1", 0);
|
||||
verify_printf(host, "%14H", " 192.168.0.1");
|
||||
verify_printf(host, "%-14H", "192.168.0.1 ");
|
||||
verify_printf(host, "%4H", "192.168.0.1");
|
||||
verify_printf(host, "%-4H", "192.168.0.1");
|
||||
host->destroy(host);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *host_suite_create()
|
||||
{
|
||||
Suite *s;
|
||||
TCase *tc;
|
||||
|
||||
s = suite_create("host");
|
||||
|
||||
tc = tcase_create("host_create_any");
|
||||
tcase_add_test(tc, test_create_any_v4);
|
||||
tcase_add_test(tc, test_create_any_v6);
|
||||
tcase_add_test(tc, test_create_any_other);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("host_create_from_string");
|
||||
tcase_add_test(tc, test_create_from_string_v4);
|
||||
tcase_add_test(tc, test_create_from_string_any_v6);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("host_create_from_string_and_family");
|
||||
tcase_add_test(tc, test_create_from_string_and_family_v4);
|
||||
tcase_add_test(tc, test_create_from_string_and_family_v6);
|
||||
tcase_add_test(tc, test_create_from_string_and_family_other);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("host_create_from_sockaddr");
|
||||
tcase_add_test(tc, test_create_from_sockaddr_v4);
|
||||
tcase_add_test(tc, test_create_from_sockaddr_v6);
|
||||
tcase_add_test(tc, test_create_from_sockaddr_other);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("host_create_from_chunk");
|
||||
tcase_add_test(tc, test_create_from_chunk_v4);
|
||||
tcase_add_test(tc, test_create_from_chunk_v6);
|
||||
tcase_add_test(tc, test_create_from_chunk_other);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("host_create_from_subnet");
|
||||
tcase_add_test(tc, test_create_from_subnet_v4);
|
||||
tcase_add_test(tc, test_create_from_subnet_v6);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("host_create_netmask");
|
||||
tcase_add_test(tc, test_create_netmask_v4);
|
||||
tcase_add_test(tc, test_create_netmask_v6);
|
||||
tcase_add_test(tc, test_create_netmask_other);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("equals, ip_equals");
|
||||
tcase_add_test(tc, test_equals);
|
||||
tcase_add_test(tc, test_equals_any);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("clone");
|
||||
tcase_add_test(tc, test_clone);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("printf hook");
|
||||
tcase_add_loop_test(tc, test_printf_hook, 0, countof(printf_data));
|
||||
tcase_add_test(tc, test_printf_hook_align);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,857 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Copyright (C) 2009 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_suite.h"
|
||||
|
||||
#include <utils/identification.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* create (_from_encoding, _from_data, _from_string, _from_sockaddr)
|
||||
*/
|
||||
|
||||
START_TEST(test_from_encoding)
|
||||
{
|
||||
identification_t *a;
|
||||
chunk_t expected, encoding;
|
||||
|
||||
/* only ID_ANY is handled differently, for all other types the following
|
||||
* applies. should we perhaps test that this is in fact the case? */
|
||||
expected = chunk_from_str("[email protected]");
|
||||
a = identification_create_from_encoding(ID_RFC822_ADDR, expected);
|
||||
ck_assert(ID_RFC822_ADDR == a->get_type(a));
|
||||
encoding = a->get_encoding(a);
|
||||
ck_assert(expected.ptr != encoding.ptr);
|
||||
ck_assert(chunk_equals(expected, encoding));
|
||||
a->destroy(a);
|
||||
|
||||
a = identification_create_from_encoding(ID_ANY, expected);
|
||||
ck_assert(ID_ANY == a->get_type(a));
|
||||
encoding = a->get_encoding(a);
|
||||
ck_assert(encoding.ptr == NULL);
|
||||
ck_assert(encoding.len == 0);
|
||||
a->destroy(a);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_from_data)
|
||||
{
|
||||
identification_t *a;
|
||||
chunk_t expected, encoding;
|
||||
|
||||
/* this uses the DN parser (C=CH) */
|
||||
expected = chunk_from_chars(0x30, 0x0d, 0x31, 0x0b, 0x30, 0x09, 0x06,
|
||||
0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48);
|
||||
a = identification_create_from_data(expected);
|
||||
ck_assert(ID_DER_ASN1_DN == a->get_type(a));
|
||||
encoding = a->get_encoding(a);
|
||||
ck_assert(expected.ptr != encoding.ptr);
|
||||
ck_assert(chunk_equals(expected, encoding));
|
||||
a->destroy(a);
|
||||
|
||||
/* everything else is handled by the string parser */
|
||||
expected = chunk_from_str("[email protected]");
|
||||
a = identification_create_from_data(expected);
|
||||
ck_assert(ID_RFC822_ADDR == a->get_type(a));
|
||||
encoding = a->get_encoding(a);
|
||||
ck_assert(expected.ptr != encoding.ptr);
|
||||
ck_assert(chunk_equals(expected, encoding));
|
||||
a->destroy(a);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_from_sockaddr)
|
||||
{
|
||||
identification_t *a;
|
||||
chunk_t expected, encoding;
|
||||
struct sockaddr_in in = {
|
||||
.sin_family = AF_INET,
|
||||
};
|
||||
struct sockaddr_in6 in6 = {
|
||||
.sin6_family = AF_INET6,
|
||||
};
|
||||
|
||||
expected = chunk_from_chars(0xc0, 0xa8, 0x01, 0x01);
|
||||
memcpy(&in.sin_addr, expected.ptr, sizeof(in.sin_addr));
|
||||
a = identification_create_from_sockaddr((sockaddr_t*)&in);
|
||||
ck_assert(ID_IPV4_ADDR == a->get_type(a));
|
||||
encoding = a->get_encoding(a);
|
||||
ck_assert(chunk_equals(expected, encoding));
|
||||
a->destroy(a);
|
||||
|
||||
expected = chunk_from_chars(0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01);
|
||||
memcpy(&in6.sin6_addr, expected.ptr, sizeof(in6.sin6_addr));
|
||||
a = identification_create_from_sockaddr((sockaddr_t*)&in6);
|
||||
ck_assert(ID_IPV6_ADDR == a->get_type(a));
|
||||
encoding = a->get_encoding(a);
|
||||
ck_assert(chunk_equals(expected, encoding));
|
||||
a->destroy(a);
|
||||
|
||||
in6.sin6_family = AF_UNSPEC;
|
||||
a = identification_create_from_sockaddr((sockaddr_t*)&in6);
|
||||
ck_assert(ID_ANY == a->get_type(a));
|
||||
a->destroy(a);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static struct {
|
||||
char *id;
|
||||
id_type_t type;
|
||||
struct {
|
||||
enum {
|
||||
ENC_CHUNK,
|
||||
ENC_STRING,
|
||||
ENC_SIMPLE,
|
||||
} type;
|
||||
union {
|
||||
chunk_t c;
|
||||
char *s;
|
||||
} data;
|
||||
} result;
|
||||
} string_data[] = {
|
||||
{NULL, ID_ANY, { .type = ENC_CHUNK }},
|
||||
{"", ID_ANY, { .type = ENC_CHUNK }},
|
||||
{"%any", ID_ANY, { .type = ENC_CHUNK }},
|
||||
{"%any6", ID_ANY, { .type = ENC_CHUNK }},
|
||||
{"0.0.0.0", ID_ANY, { .type = ENC_CHUNK }},
|
||||
{"0::0", ID_ANY, { .type = ENC_CHUNK }},
|
||||
{"::", ID_ANY, { .type = ENC_CHUNK }},
|
||||
{"*", ID_ANY, { .type = ENC_CHUNK }},
|
||||
{"any", ID_FQDN, { .type = ENC_SIMPLE }},
|
||||
{"any6", ID_FQDN, { .type = ENC_SIMPLE }},
|
||||
{"0", ID_FQDN, { .type = ENC_SIMPLE }},
|
||||
{"**", ID_FQDN, { .type = ENC_SIMPLE }},
|
||||
{"192.168.1.1", ID_IPV4_ADDR, { .type = ENC_CHUNK,
|
||||
.data.c = chunk_from_chars(0xc0, 0xa8, 0x01, 0x01) }},
|
||||
{"192.168.",ID_FQDN, { .type = ENC_SIMPLE }},
|
||||
{".", ID_FQDN, { .type = ENC_SIMPLE }},
|
||||
{"fec0::1", ID_IPV6_ADDR, { .type = ENC_CHUNK,
|
||||
.data.c = chunk_from_chars(0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01) }},
|
||||
{"fec0::", ID_IPV6_ADDR, { .type = ENC_CHUNK,
|
||||
.data.c = chunk_from_chars(0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) }},
|
||||
{"fec0:", ID_KEY_ID, { .type = ENC_SIMPLE }},
|
||||
{":", ID_KEY_ID, { .type = ENC_SIMPLE }},
|
||||
{"[email protected]", ID_RFC822_ADDR, { .type = ENC_SIMPLE }},
|
||||
{"alice@strongswan", ID_RFC822_ADDR, { .type = ENC_SIMPLE }},
|
||||
{"alice@", ID_RFC822_ADDR, { .type = ENC_SIMPLE }},
|
||||
{"alice", ID_FQDN, { .type = ENC_SIMPLE }},
|
||||
{"@", ID_FQDN, { .type = ENC_CHUNK }},
|
||||
{" @", ID_RFC822_ADDR, { .type = ENC_SIMPLE }},
|
||||
{"@strongswan.org", ID_FQDN, { .type = ENC_STRING,
|
||||
.data.s = "strongswan.org" }},
|
||||
{"@#deadbeef", ID_KEY_ID, { .type = ENC_CHUNK,
|
||||
.data.c = chunk_from_chars(0xde, 0xad, 0xbe, 0xef) }},
|
||||
{"@#deadbee", ID_KEY_ID, { .type = ENC_CHUNK,
|
||||
.data.c = chunk_from_chars(0x0d, 0xea, 0xdb, 0xee) }},
|
||||
{"foo=bar", ID_KEY_ID, { .type = ENC_SIMPLE }},
|
||||
{"foo=", ID_KEY_ID, { .type = ENC_SIMPLE }},
|
||||
{"=bar", ID_KEY_ID, { .type = ENC_SIMPLE }},
|
||||
{"C=", ID_DER_ASN1_DN, { .type = ENC_CHUNK,
|
||||
.data.c = chunk_from_chars(0x30, 0x0b, 0x31, 0x09, 0x30, 0x07, 0x06,
|
||||
0x03, 0x55, 0x04, 0x06, 0x13, 0x00)}},
|
||||
{"C=CH", ID_DER_ASN1_DN, { .type = ENC_CHUNK,
|
||||
.data.c = chunk_from_chars(0x30, 0x0d, 0x31, 0x0b, 0x30, 0x09, 0x06,
|
||||
0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48)}},
|
||||
{"C=CH,", ID_DER_ASN1_DN, { .type = ENC_CHUNK,
|
||||
.data.c = chunk_from_chars(0x30, 0x0d, 0x31, 0x0b, 0x30, 0x09, 0x06,
|
||||
0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48)}},
|
||||
{"C=CH, ", ID_DER_ASN1_DN, { .type = ENC_CHUNK,
|
||||
.data.c = chunk_from_chars(0x30, 0x0d, 0x31, 0x0b, 0x30, 0x09, 0x06,
|
||||
0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48)}},
|
||||
{"C=CH, O", ID_KEY_ID, { .type = ENC_SIMPLE }},
|
||||
};
|
||||
|
||||
START_TEST(test_from_string)
|
||||
{
|
||||
identification_t *a;
|
||||
chunk_t encoding, expected;
|
||||
char *id;
|
||||
|
||||
id = string_data[_i].id;
|
||||
a = identification_create_from_string(id);
|
||||
fail_unless(a->get_type(a) == string_data[_i].type,
|
||||
"type of id '%s' is %N, %N expected", id,
|
||||
id_type_names, a->get_type(a),
|
||||
id_type_names, string_data[_i].type);
|
||||
|
||||
encoding = a->get_encoding(a);
|
||||
switch (string_data[_i].result.type)
|
||||
{
|
||||
case ENC_SIMPLE:
|
||||
expected = chunk_from_str(string_data[_i].id);
|
||||
break;
|
||||
case ENC_STRING:
|
||||
expected = chunk_from_str(string_data[_i].result.data.s);
|
||||
break;
|
||||
case ENC_CHUNK:
|
||||
expected = string_data[_i].result.data.c;
|
||||
break;
|
||||
default:
|
||||
fail("unexpected result type");
|
||||
}
|
||||
|
||||
ck_assert(!id || (char*)encoding.ptr != id);
|
||||
if (expected.ptr)
|
||||
{
|
||||
fail_unless(chunk_equals(encoding, expected),
|
||||
"parsing '%s' failed\nencoding %B\nexpected %B\n",
|
||||
id, &encoding, &expected);
|
||||
}
|
||||
else
|
||||
{
|
||||
ck_assert(encoding.ptr == NULL);
|
||||
ck_assert(encoding.len == 0);
|
||||
}
|
||||
a->destroy(a);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* printf_hook
|
||||
*/
|
||||
|
||||
static void string_equals(char *a_str, char *b_str)
|
||||
{
|
||||
identification_t *b;
|
||||
char buf[128];
|
||||
|
||||
b = b_str ? identification_create_from_string(b_str) : NULL;
|
||||
snprintf(buf, sizeof(buf), "%Y", b);
|
||||
DESTROY_IF(b);
|
||||
ck_assert_str_eq(a_str, buf);
|
||||
}
|
||||
|
||||
static void string_equals_id(char *a_str, identification_t *b)
|
||||
{
|
||||
char buf[128];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%Y", b);
|
||||
DESTROY_IF(b);
|
||||
ck_assert_str_eq(a_str, buf);
|
||||
}
|
||||
|
||||
START_TEST(test_printf_hook)
|
||||
{
|
||||
string_equals("(null)", NULL);
|
||||
string_equals("%any", "");
|
||||
string_equals("%any", "%any");
|
||||
string_equals("%any", "*");
|
||||
|
||||
string_equals("192.168.1.1", "192.168.1.1");
|
||||
string_equals_id("(invalid ID_IPV4_ADDR)",
|
||||
identification_create_from_encoding(ID_IPV4_ADDR, chunk_empty));
|
||||
string_equals("fec0::1", "fec0::1");
|
||||
string_equals("fec0::1", "fec0:0:0::1");
|
||||
string_equals_id("(invalid ID_IPV6_ADDR)",
|
||||
identification_create_from_encoding(ID_IPV6_ADDR, chunk_empty));
|
||||
|
||||
string_equals_id("(unknown ID type: 255)",
|
||||
identification_create_from_encoding(255, chunk_empty));
|
||||
|
||||
string_equals("[email protected]", "[email protected]");
|
||||
string_equals("[email protected]", "[email protected]");
|
||||
/* non-printable characters */
|
||||
string_equals_id("[email protected]", identification_create_from_encoding(ID_RFC822_ADDR,
|
||||
chunk_from_chars(0xfa, 0xfb, 0xfc, 0xfd, 0x40, 0x73, 0x74, 0x72,
|
||||
0x6f, 0x6e, 0x67, 0x73, 0x77, 0x61, 0x6e, 0x2e,
|
||||
0x6f, 0x72, 0x67)));
|
||||
|
||||
/* not a DN => ID_KEY_ID => no normalization */
|
||||
string_equals("C=CH, AsdF=asdf", "C=CH, AsdF=asdf");
|
||||
string_equals_id("[email protected]", identification_create_from_encoding(ID_KEY_ID,
|
||||
chunk_from_str("[email protected]")));
|
||||
/* non-printable characters */
|
||||
string_equals_id("de:ad:be:ef", identification_create_from_encoding(ID_KEY_ID,
|
||||
chunk_from_chars(0xde, 0xad, 0xbe, 0xef)));
|
||||
/* printable characters */
|
||||
string_equals_id("ABCDEFGHIJKLMNOPQRS",
|
||||
identification_create_from_encoding(ID_KEY_ID,
|
||||
chunk_from_chars(0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
|
||||
0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
|
||||
0x51, 0x52, 0x53)));
|
||||
/* ABCDEFGHIJKLMNOPQRST is printable but has the length of a SHA1 hash */
|
||||
string_equals_id("41:42:43:44:45:46:47:48:49:4a:4b:4c:4d:4e:4f:50:51:52:53:54",
|
||||
identification_create_from_encoding(ID_KEY_ID,
|
||||
chunk_from_chars(0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
|
||||
0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
|
||||
0x51, 0x52, 0x53, 0x54)));
|
||||
|
||||
string_equals_id("", identification_create_from_encoding(ID_DER_ASN1_DN, chunk_empty));
|
||||
string_equals("C=", "C=");
|
||||
string_equals("C=", "C=,");
|
||||
string_equals("C=", "C=, ");
|
||||
string_equals("C=", "C= , ");
|
||||
string_equals("C=, O=strongSwan", "C=, O=strongSwan");
|
||||
string_equals("C=CH, O=", "C=CH, O=");
|
||||
string_equals("C=CH, O=strongSwan, CN=strongswan.org",
|
||||
"C=CH, O=strongSwan, CN=strongswan.org");
|
||||
string_equals("CN=strongswan.org, O=strongSwan, C=CH",
|
||||
"cn=strongswan.org, o=strongSwan, c=CH");
|
||||
string_equals("C=CH, O=strongSwan, CN=strongswan.org",
|
||||
"C=CH,O=strongSwan,CN=strongswan.org");
|
||||
string_equals("C=CH, O=strongSwan, CN=strongswan.org",
|
||||
"/C=CH/O=strongSwan/CN=strongswan.org");
|
||||
string_equals("CN=strongswan.org, O=strongSwan, C=CH",
|
||||
"CN=strongswan.org,O=strongSwan,C=CH");
|
||||
|
||||
string_equals("C=CH, [email protected], CN=moon",
|
||||
"C=CH, [email protected], CN=moon");
|
||||
string_equals("C=CH, [email protected], CN=moon",
|
||||
"C=CH, [email protected], CN=moon");
|
||||
|
||||
/* C=CH, pseudonym=ANO (pseudonym is currently not recognized) */
|
||||
string_equals_id("C=CH, 55:04:41=ANO", identification_create_from_encoding(ID_DER_ASN1_DN,
|
||||
chunk_from_chars(0x30, 0x19, 0x31, 0x17, 0x30, 0x09, 0x06, 0x03, 0x55,
|
||||
0x04, 0x06, 0x13, 0x02, 0x43, 0x48, 0x30, 0x0a, 0x06,
|
||||
0x03, 0x55, 0x04, 0x41, 0x13, 0x03, 0x41, 0x4e, 0x4f)));
|
||||
/* C=CH, O=strongSwan (but instead of a 2nd OID -0x06- we got NULL -0x05) */
|
||||
string_equals_id("C=CH, (invalid ID_DER_ASN1_DN)", identification_create_from_encoding(ID_DER_ASN1_DN,
|
||||
chunk_from_chars(0x30, 0x20, 0x31, 0x1e, 0x30, 0x09, 0x06, 0x03, 0x55,
|
||||
0x04, 0x06, 0x13, 0x02, 0x43, 0x48, 0x30, 0x11, 0x05,
|
||||
0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x73, 0x74, 0x72,
|
||||
0x6f, 0x6e, 0x67, 0x53, 0x77, 0x61, 0x6e)));
|
||||
/* [email protected] as GN */
|
||||
string_equals_id("(ASN.1 general name)", identification_create_from_encoding(ID_DER_ASN1_GN,
|
||||
chunk_from_chars(0x81, 0x14, 0x6d, 0x6f, 0x6f, 0x6e, 0x40, 0x73, 0x74,
|
||||
0x72, 0x6f, 0x6e, 0x67, 0x73, 0x77, 0x61, 0x6e, 0x2e,
|
||||
0x6f, 0x72, 0x67)));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_printf_hook_width)
|
||||
{
|
||||
identification_t *a;
|
||||
char buf[128];
|
||||
|
||||
a = identification_create_from_string("[email protected]");
|
||||
snprintf(buf, sizeof(buf), "%25Y", a);
|
||||
ck_assert_str_eq(" [email protected]", buf);
|
||||
snprintf(buf, sizeof(buf), "%-*Y", 25, a);
|
||||
ck_assert_str_eq("[email protected] ", buf);
|
||||
snprintf(buf, sizeof(buf), "%5Y", a);
|
||||
ck_assert_str_eq("[email protected]", buf);
|
||||
DESTROY_IF(a);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* equals
|
||||
*/
|
||||
|
||||
static bool id_equals(identification_t *a, char *b_str)
|
||||
{
|
||||
identification_t *b;
|
||||
bool equals;
|
||||
|
||||
b = identification_create_from_string(b_str);
|
||||
equals = a->equals(a, b);
|
||||
ck_assert_int_eq(equals, b->equals(b, a));
|
||||
b->destroy(b);
|
||||
return equals;
|
||||
}
|
||||
|
||||
START_TEST(test_equals)
|
||||
{
|
||||
identification_t *a;
|
||||
chunk_t encoding, fuzzed;
|
||||
int i;
|
||||
|
||||
/* this test also tests identification_create_from_string with DNs */
|
||||
a = identification_create_from_string(
|
||||
"C=CH, [email protected], CN=moon");
|
||||
|
||||
ck_assert(id_equals(a, "C=CH, [email protected], CN=moon"));
|
||||
ck_assert(id_equals(a, "C==CH, [email protected],,, CN==moon"));
|
||||
ck_assert(id_equals(a, " C=CH, [email protected], CN=moon "));
|
||||
ck_assert(id_equals(a, "C=ch, [email protected], CN=Moon"));
|
||||
ck_assert(id_equals(a, "/C=CH/[email protected]/CN=moon"));
|
||||
ck_assert(id_equals(a, "C=CH/[email protected]/CN=moon"));
|
||||
ck_assert(id_equals(a, "C=CH/[email protected],CN=moon"));
|
||||
ck_assert(id_equals(a, "C=CH / [email protected] , CN=moon"));
|
||||
|
||||
ck_assert(!id_equals(a, "C=CH [email protected] CN=moon"));
|
||||
ck_assert(!id_equals(a, "C=CN, [email protected], CN=moon"));
|
||||
ck_assert(!id_equals(a, "[email protected], C=CH, CN=moon"));
|
||||
ck_assert(!id_equals(a, "[email protected], C=CH, CN=moon"));
|
||||
|
||||
encoding = chunk_clone(a->get_encoding(a));
|
||||
a->destroy(a);
|
||||
|
||||
/* simple fuzzing, increment each byte of encoding */
|
||||
for (i = 0; i < encoding.len; i++)
|
||||
{
|
||||
if (i == 11 || i == 30 || i == 60)
|
||||
{ /* skip ASN.1 type fields, as equals() handles them graceful */
|
||||
continue;
|
||||
}
|
||||
fuzzed = chunk_clone(encoding);
|
||||
fuzzed.ptr[i]++;
|
||||
a = identification_create_from_encoding(ID_DER_ASN1_DN, fuzzed);
|
||||
if (id_equals(a, "C=CH, [email protected], CN=moon"))
|
||||
{
|
||||
printf("%d %B\n%B\n", i, &fuzzed, &encoding);
|
||||
}
|
||||
ck_assert(!id_equals(a, "C=CH, [email protected], CN=moon"));
|
||||
a->destroy(a);
|
||||
free(fuzzed.ptr);
|
||||
}
|
||||
|
||||
/* and decrement each byte of encoding */
|
||||
for (i = 0; i < encoding.len; i++)
|
||||
{
|
||||
if (i == 11 || i == 30 || i == 60)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
fuzzed = chunk_clone(encoding);
|
||||
fuzzed.ptr[i]--;
|
||||
a = identification_create_from_encoding(ID_DER_ASN1_DN, fuzzed);
|
||||
ck_assert(!id_equals(a, "C=CH, [email protected], CN=moon"));
|
||||
a->destroy(a);
|
||||
free(fuzzed.ptr);
|
||||
}
|
||||
free(encoding.ptr);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_equals_any)
|
||||
{
|
||||
identification_t *a, *b;
|
||||
|
||||
a = identification_create_from_string("%any");
|
||||
b = identification_create_from_encoding(ID_ANY, chunk_empty);
|
||||
ck_assert(a->equals(a, b));
|
||||
ck_assert(b->equals(b, a));
|
||||
b->destroy(b);
|
||||
|
||||
b = identification_create_from_string("C=CH, O=strongSwan, CN=strongswan.org");
|
||||
ck_assert(!a->equals(a, b));
|
||||
ck_assert(!b->equals(b, a));
|
||||
a->destroy(a);
|
||||
b->destroy(b);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_equals_binary)
|
||||
{
|
||||
identification_t *a, *b;
|
||||
chunk_t encoding;
|
||||
|
||||
encoding = chunk_from_str("foobar=");
|
||||
/* strings containing = are parsed as KEY_ID if they aren't valid ASN.1 DNs */
|
||||
a = identification_create_from_string("foobar=");
|
||||
ck_assert(a->get_type(a) == ID_KEY_ID);
|
||||
b = identification_create_from_encoding(ID_KEY_ID, encoding);
|
||||
ck_assert(a->equals(a, b));
|
||||
a->destroy(a);
|
||||
b->destroy(b);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_equals_fqdn)
|
||||
{
|
||||
identification_t *a;
|
||||
|
||||
a = identification_create_from_string("ipsec.strongswan.org");
|
||||
ck_assert(id_equals(a, "IPSEC.strongswan.org"));
|
||||
ck_assert(id_equals(a, "ipsec.strongSwan.org"));
|
||||
ck_assert(id_equals(a, "ipsec.strongSwan.ORG"));
|
||||
ck_assert(!id_equals(a, "strongswan.org"));
|
||||
a->destroy(a);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_equals_empty)
|
||||
{
|
||||
identification_t *a;
|
||||
|
||||
a = identification_create_from_encoding(_i, chunk_empty);
|
||||
|
||||
switch (_i)
|
||||
{
|
||||
case ID_ANY:
|
||||
ck_assert(id_equals(a, "%any"));
|
||||
break;
|
||||
case ID_IPV4_ADDR:
|
||||
ck_assert(!id_equals(a, "192.168.1.1"));
|
||||
break;
|
||||
case ID_FQDN:
|
||||
ck_assert(!id_equals(a, "moon.strongswan.org"));
|
||||
break;
|
||||
case ID_USER_FQDN:
|
||||
ck_assert(!id_equals(a, "[email protected]"));
|
||||
break;
|
||||
case ID_IPV6_ADDR:
|
||||
ck_assert(!id_equals(a, "fec0::1"));
|
||||
break;
|
||||
case ID_DER_ASN1_DN:
|
||||
ck_assert(!id_equals(a, "C=CH, [email protected], CN=moon"));
|
||||
break;
|
||||
case ID_KEY_ID:
|
||||
ck_assert(!id_equals(a, "@#12345678"));
|
||||
break;
|
||||
case ID_DER_ASN1_GN:
|
||||
case ID_IPV4_ADDR_SUBNET:
|
||||
case ID_IPV6_ADDR_SUBNET:
|
||||
case ID_IPV4_ADDR_RANGE:
|
||||
case ID_IPV6_ADDR_RANGE:
|
||||
/* currently not tested */
|
||||
break;
|
||||
}
|
||||
|
||||
a->destroy(a);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* matches
|
||||
*/
|
||||
|
||||
static bool id_matches(identification_t *a, char *b_str, id_match_t expected)
|
||||
{
|
||||
identification_t *b;
|
||||
id_match_t match;
|
||||
|
||||
b = identification_create_from_string(b_str);
|
||||
match = a->matches(a, b);
|
||||
b->destroy(b);
|
||||
return match == expected;
|
||||
}
|
||||
|
||||
START_TEST(test_matches)
|
||||
{
|
||||
identification_t *a;
|
||||
|
||||
a = identification_create_from_string("C=CH, [email protected], CN=moon");
|
||||
|
||||
ck_assert(id_matches(a, "C=CH, [email protected], CN=moon", ID_MATCH_PERFECT));
|
||||
ck_assert(id_matches(a, "C=CH, E=*, CN=moon", ID_MATCH_ONE_WILDCARD));
|
||||
ck_assert(id_matches(a, "C=CH, E=*, CN=*", ID_MATCH_ONE_WILDCARD - 1));
|
||||
ck_assert(id_matches(a, "C=*, E=*, CN=*", ID_MATCH_ONE_WILDCARD - 2));
|
||||
ck_assert(id_matches(a, "C=*, E=*, CN=*, O=BADInc", ID_MATCH_NONE));
|
||||
ck_assert(id_matches(a, "C=*, E=*", ID_MATCH_NONE));
|
||||
ck_assert(id_matches(a, "C=*, [email protected], CN=*", ID_MATCH_NONE));
|
||||
ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
|
||||
|
||||
a->destroy(a);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_matches_any)
|
||||
{
|
||||
identification_t *a;
|
||||
|
||||
a = identification_create_from_string("%any");
|
||||
|
||||
ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
|
||||
ck_assert(id_matches(a, "", ID_MATCH_ANY));
|
||||
ck_assert(id_matches(a, "*", ID_MATCH_ANY));
|
||||
ck_assert(id_matches(a, "[email protected]", ID_MATCH_NONE));
|
||||
ck_assert(id_matches(a, "vpn.strongswan.org", ID_MATCH_NONE));
|
||||
a->destroy(a);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_matches_binary)
|
||||
{
|
||||
identification_t *a;
|
||||
|
||||
/* strings containing = are parsed as KEY_ID if they aren't valid ASN.1 DNs */
|
||||
a = identification_create_from_string("foo=bar");
|
||||
ck_assert(a->get_type(a) == ID_KEY_ID);
|
||||
ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
|
||||
ck_assert(id_matches(a, "foo=bar", ID_MATCH_PERFECT));
|
||||
ck_assert(id_matches(a, "bar=foo", ID_MATCH_NONE));
|
||||
ck_assert(id_matches(a, "*=bar", ID_MATCH_NONE));
|
||||
ck_assert(id_matches(a, "foo=*", ID_MATCH_NONE));
|
||||
ck_assert(id_matches(a, "foo@bar", ID_MATCH_NONE));
|
||||
a->destroy(a);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_matches_string)
|
||||
{
|
||||
identification_t *a;
|
||||
|
||||
a = identification_create_from_string("[email protected]");
|
||||
|
||||
ck_assert(id_matches(a, "[email protected]", ID_MATCH_PERFECT));
|
||||
ck_assert(id_matches(a, "*@strongswan.org", ID_MATCH_ONE_WILDCARD));
|
||||
ck_assert(id_matches(a, "*@*.org", ID_MATCH_NONE));
|
||||
ck_assert(id_matches(a, "*@*", ID_MATCH_NONE));
|
||||
/* the following two are parsed as ID_FQDN, so no match */
|
||||
ck_assert(id_matches(a, "*strongswan.org", ID_MATCH_NONE));
|
||||
ck_assert(id_matches(a, "*.org", ID_MATCH_NONE));
|
||||
ck_assert(id_matches(a, "moon@*", ID_MATCH_NONE));
|
||||
ck_assert(id_matches(a, "**", ID_MATCH_NONE));
|
||||
ck_assert(id_matches(a, "*", ID_MATCH_ANY));
|
||||
ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
|
||||
a->destroy(a);
|
||||
|
||||
a = identification_create_from_string("vpn.strongswan.org");
|
||||
|
||||
ck_assert(id_matches(a, "vpn.strongswan.org", ID_MATCH_PERFECT));
|
||||
ck_assert(id_matches(a, "*.strongswan.org", ID_MATCH_ONE_WILDCARD));
|
||||
ck_assert(id_matches(a, "*strongswan.org", ID_MATCH_ONE_WILDCARD));
|
||||
ck_assert(id_matches(a, "*.org", ID_MATCH_ONE_WILDCARD));
|
||||
ck_assert(id_matches(a, "*.strongswan.*", ID_MATCH_NONE));
|
||||
ck_assert(id_matches(a, "*vpn.strongswan.org", ID_MATCH_NONE));
|
||||
ck_assert(id_matches(a, "vpn.strongswan.*", ID_MATCH_NONE));
|
||||
ck_assert(id_matches(a, "**", ID_MATCH_NONE));
|
||||
ck_assert(id_matches(a, "*", ID_MATCH_ANY));
|
||||
ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
|
||||
a->destroy(a);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_matches_empty)
|
||||
{
|
||||
identification_t *a;
|
||||
|
||||
a = identification_create_from_encoding(_i, chunk_empty);
|
||||
|
||||
switch (_i)
|
||||
{
|
||||
case ID_ANY:
|
||||
ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
|
||||
break;
|
||||
case ID_IPV4_ADDR:
|
||||
ck_assert(id_matches(a, "192.168.1.1", ID_MATCH_NONE));
|
||||
break;
|
||||
case ID_FQDN:
|
||||
ck_assert(id_matches(a, "moon.strongswan.org", ID_MATCH_NONE));
|
||||
break;
|
||||
case ID_USER_FQDN:
|
||||
ck_assert(id_matches(a, "[email protected]", ID_MATCH_NONE));
|
||||
break;
|
||||
case ID_IPV6_ADDR:
|
||||
ck_assert(id_matches(a, "fec0::1", ID_MATCH_NONE));
|
||||
break;
|
||||
case ID_DER_ASN1_DN:
|
||||
ck_assert(id_matches(a, "C=CH, [email protected], CN=moon",
|
||||
ID_MATCH_NONE));
|
||||
break;
|
||||
case ID_KEY_ID:
|
||||
ck_assert(id_matches(a, "@#12345678", ID_MATCH_NONE));
|
||||
break;
|
||||
case ID_DER_ASN1_GN:
|
||||
case ID_IPV4_ADDR_SUBNET:
|
||||
case ID_IPV6_ADDR_SUBNET:
|
||||
case ID_IPV4_ADDR_RANGE:
|
||||
case ID_IPV6_ADDR_RANGE:
|
||||
/* currently not tested */
|
||||
break;
|
||||
}
|
||||
|
||||
a->destroy(a);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static bool id_matches_rev(identification_t *a, char *b_str, id_match_t expected)
|
||||
{
|
||||
identification_t *b;
|
||||
id_match_t match;
|
||||
|
||||
b = identification_create_from_string(b_str);
|
||||
match = b->matches(b, a);
|
||||
b->destroy(b);
|
||||
return match == expected;
|
||||
}
|
||||
|
||||
START_TEST(test_matches_empty_reverse)
|
||||
{
|
||||
identification_t *a;
|
||||
|
||||
a = identification_create_from_encoding(_i, chunk_empty);
|
||||
|
||||
switch (_i)
|
||||
{
|
||||
case ID_ANY:
|
||||
ck_assert(id_matches_rev(a, "%any", ID_MATCH_ANY));
|
||||
break;
|
||||
case ID_IPV4_ADDR:
|
||||
ck_assert(id_matches_rev(a, "192.168.1.1", ID_MATCH_NONE));
|
||||
break;
|
||||
case ID_FQDN:
|
||||
ck_assert(id_matches_rev(a, "moon.strongswan.org", ID_MATCH_NONE));
|
||||
break;
|
||||
case ID_USER_FQDN:
|
||||
ck_assert(id_matches_rev(a, "[email protected]", ID_MATCH_NONE));
|
||||
break;
|
||||
case ID_IPV6_ADDR:
|
||||
ck_assert(id_matches_rev(a, "fec0::1", ID_MATCH_NONE));
|
||||
break;
|
||||
case ID_DER_ASN1_DN:
|
||||
ck_assert(id_matches_rev(a, "C=CH, [email protected], CN=moon",
|
||||
ID_MATCH_NONE));
|
||||
break;
|
||||
case ID_KEY_ID:
|
||||
ck_assert(id_matches_rev(a, "@#12345678", ID_MATCH_NONE));
|
||||
break;
|
||||
case ID_DER_ASN1_GN:
|
||||
case ID_IPV4_ADDR_SUBNET:
|
||||
case ID_IPV6_ADDR_SUBNET:
|
||||
case ID_IPV4_ADDR_RANGE:
|
||||
case ID_IPV6_ADDR_RANGE:
|
||||
/* currently not tested */
|
||||
break;
|
||||
}
|
||||
|
||||
a->destroy(a);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* identification part enumeration
|
||||
*/
|
||||
|
||||
START_TEST(test_parts)
|
||||
{
|
||||
identification_t *id;
|
||||
enumerator_t *enumerator;
|
||||
id_part_t part;
|
||||
chunk_t data;
|
||||
int i = 0;
|
||||
|
||||
id = identification_create_from_string("C=CH, O=strongSwan, CN=tester");
|
||||
|
||||
enumerator = id->create_part_enumerator(id);
|
||||
while (enumerator->enumerate(enumerator, &part, &data))
|
||||
{
|
||||
switch (i++)
|
||||
{
|
||||
case 0:
|
||||
ck_assert(part == ID_PART_RDN_C &&
|
||||
chunk_equals(data, chunk_create("CH", 2)));
|
||||
break;
|
||||
case 1:
|
||||
ck_assert(part == ID_PART_RDN_O &&
|
||||
chunk_equals(data, chunk_from_str("strongSwan")));
|
||||
break;
|
||||
case 2:
|
||||
ck_assert(part == ID_PART_RDN_CN &&
|
||||
chunk_equals(data, chunk_from_str("tester")));
|
||||
break;
|
||||
default:
|
||||
fail("unexpected identification part %d", part);
|
||||
}
|
||||
}
|
||||
ck_assert_int_eq(i, 3);
|
||||
enumerator->destroy(enumerator);
|
||||
id->destroy(id);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* wildcards
|
||||
*/
|
||||
|
||||
static bool id_contains_wildcards(char *string)
|
||||
{
|
||||
identification_t *id;
|
||||
bool contains;
|
||||
|
||||
id = identification_create_from_string(string);
|
||||
contains = id->contains_wildcards(id);
|
||||
id->destroy(id);
|
||||
return contains;
|
||||
}
|
||||
|
||||
START_TEST(test_contains_wildcards)
|
||||
{
|
||||
ck_assert(id_contains_wildcards("%any"));
|
||||
ck_assert(id_contains_wildcards("C=*, O=strongSwan, CN=gw"));
|
||||
ck_assert(id_contains_wildcards("C=CH, O=strongSwan, CN=*"));
|
||||
ck_assert(id_contains_wildcards("*@strongswan.org"));
|
||||
ck_assert(id_contains_wildcards("*.strongswan.org"));
|
||||
ck_assert(!id_contains_wildcards("C=**, O=a*, CN=*a"));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* clone
|
||||
*/
|
||||
|
||||
START_TEST(test_clone)
|
||||
{
|
||||
identification_t *a, *b;
|
||||
chunk_t a_enc, b_enc;
|
||||
|
||||
a = identification_create_from_string("[email protected]");
|
||||
a_enc = a->get_encoding(a);
|
||||
b = a->clone(a);
|
||||
ck_assert(b != NULL);
|
||||
ck_assert(a != b);
|
||||
b_enc = b->get_encoding(b);
|
||||
ck_assert(a_enc.ptr != b_enc.ptr);
|
||||
ck_assert(chunk_equals(a_enc, b_enc));
|
||||
a->destroy(a);
|
||||
b->destroy(b);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *identification_suite_create()
|
||||
{
|
||||
Suite *s;
|
||||
TCase *tc;
|
||||
|
||||
s = suite_create("identification");
|
||||
|
||||
tc = tcase_create("create");
|
||||
tcase_add_test(tc, test_from_encoding);
|
||||
tcase_add_test(tc, test_from_data);
|
||||
tcase_add_test(tc, test_from_sockaddr);
|
||||
tcase_add_loop_test(tc, test_from_string, 0, countof(string_data));
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("printf_hook");
|
||||
tcase_add_test(tc, test_printf_hook);
|
||||
tcase_add_test(tc, test_printf_hook_width);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("equals");
|
||||
tcase_add_test(tc, test_equals);
|
||||
tcase_add_test(tc, test_equals_any);
|
||||
tcase_add_test(tc, test_equals_binary);
|
||||
tcase_add_test(tc, test_equals_fqdn);
|
||||
tcase_add_loop_test(tc, test_equals_empty, ID_ANY, ID_KEY_ID + 1);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("matches");
|
||||
tcase_add_test(tc, test_matches);
|
||||
tcase_add_test(tc, test_matches_any);
|
||||
tcase_add_test(tc, test_matches_binary);
|
||||
tcase_add_test(tc, test_matches_string);
|
||||
tcase_add_loop_test(tc, test_matches_empty, ID_ANY, ID_KEY_ID + 1);
|
||||
tcase_add_loop_test(tc, test_matches_empty_reverse, ID_ANY, ID_KEY_ID + 1);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("part enumeration");
|
||||
tcase_add_test(tc, test_parts);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("wildcards");
|
||||
tcase_add_test(tc, test_contains_wildcards);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("clone");
|
||||
tcase_add_test(tc, test_clone);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,386 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_suite.h"
|
||||
|
||||
#include <collections/linked_list.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* test fixture
|
||||
*/
|
||||
|
||||
static linked_list_t *list;
|
||||
|
||||
START_SETUP(setup_list)
|
||||
{
|
||||
void *x = NULL;
|
||||
|
||||
list = linked_list_create();
|
||||
ck_assert_int_eq(list->get_count(list), 0);
|
||||
ck_assert(list->get_first(list, &x) == NOT_FOUND);
|
||||
ck_assert(list->get_last(list, &x) == NOT_FOUND);
|
||||
}
|
||||
END_SETUP
|
||||
|
||||
START_TEARDOWN(teardown_list)
|
||||
{
|
||||
list->destroy(list);
|
||||
}
|
||||
END_TEARDOWN
|
||||
|
||||
/*******************************************************************************
|
||||
* insert first/last
|
||||
*/
|
||||
|
||||
START_TEST(test_insert_first)
|
||||
{
|
||||
void *a = (void*)1, *b = (void*)2, *x = NULL;
|
||||
|
||||
list->insert_first(list, a);
|
||||
ck_assert_int_eq(list->get_count(list), 1);
|
||||
ck_assert(list->get_first(list, &x) == SUCCESS);
|
||||
ck_assert(x == a);
|
||||
ck_assert(list->get_last(list, &x) == SUCCESS);
|
||||
ck_assert(x == a);
|
||||
|
||||
list->insert_first(list, b);
|
||||
ck_assert_int_eq(list->get_count(list), 2);
|
||||
ck_assert(list->get_first(list, &x) == SUCCESS);
|
||||
ck_assert(x == b);
|
||||
ck_assert(list->get_last(list, &x) == SUCCESS);
|
||||
ck_assert(x == a);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_insert_last)
|
||||
{
|
||||
void *a = (void*)1, *b = (void*)2, *x = NULL;
|
||||
|
||||
list->insert_last(list, a);
|
||||
ck_assert_int_eq(list->get_count(list), 1);
|
||||
ck_assert(list->get_first(list, &x) == SUCCESS);
|
||||
ck_assert(x == a);
|
||||
ck_assert(list->get_last(list, &x) == SUCCESS);
|
||||
ck_assert(x == a);
|
||||
|
||||
list->insert_last(list, b);
|
||||
ck_assert_int_eq(list->get_count(list), 2);
|
||||
ck_assert(list->get_first(list, &x) == SUCCESS);
|
||||
ck_assert(x == a);
|
||||
ck_assert(list->get_last(list, &x) == SUCCESS);
|
||||
ck_assert(x == b);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* remove first/last
|
||||
*/
|
||||
|
||||
START_TEST(test_remove_first)
|
||||
{
|
||||
void *a = (void*)1, *b = (void*)2, *x = NULL;
|
||||
|
||||
list->insert_first(list, a);
|
||||
list->insert_first(list, b);
|
||||
ck_assert(list->remove_first(list, &x) == SUCCESS);
|
||||
ck_assert_int_eq(list->get_count(list), 1);
|
||||
ck_assert(x == b);
|
||||
ck_assert(list->remove_first(list, &x) == SUCCESS);
|
||||
ck_assert_int_eq(list->get_count(list), 0);
|
||||
ck_assert(x == a);
|
||||
ck_assert(list->remove_first(list, &x) == NOT_FOUND);
|
||||
ck_assert(list->remove_last(list, &x) == NOT_FOUND);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_remove_last)
|
||||
{
|
||||
void *a = (void*)1, *b = (void*)2, *x = NULL;
|
||||
|
||||
list->insert_first(list, a);
|
||||
list->insert_first(list, b);
|
||||
ck_assert(list->remove_last(list, &x) == SUCCESS);
|
||||
ck_assert_int_eq(list->get_count(list), 1);
|
||||
ck_assert(x == a);
|
||||
ck_assert(list->remove_last(list, &x) == SUCCESS);
|
||||
ck_assert_int_eq(list->get_count(list), 0);
|
||||
ck_assert(x == b);
|
||||
ck_assert(list->remove_first(list, &x) == NOT_FOUND);
|
||||
ck_assert(list->remove_last(list, &x) == NOT_FOUND);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* helper function for remove and find tests
|
||||
*/
|
||||
|
||||
static bool match_a(void *item, void *a)
|
||||
{
|
||||
ck_assert(a == (void*)1);
|
||||
return item == a;
|
||||
}
|
||||
|
||||
static bool match_b(void *item, void *b)
|
||||
{
|
||||
ck_assert(b == (void*)2);
|
||||
return item == b;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* remove
|
||||
*/
|
||||
|
||||
START_TEST(test_remove)
|
||||
{
|
||||
void *a = (void*)1, *b = (void*)2;
|
||||
|
||||
list->insert_first(list, a);
|
||||
ck_assert(list->remove(list, a, NULL) == 1);
|
||||
ck_assert_int_eq(list->get_count(list), 0);
|
||||
|
||||
list->insert_last(list, a);
|
||||
list->insert_last(list, a);
|
||||
list->insert_last(list, a);
|
||||
list->insert_last(list, b);
|
||||
ck_assert(list->remove(list, a, NULL) == 3);
|
||||
ck_assert(list->remove(list, a, NULL) == 0);
|
||||
ck_assert_int_eq(list->get_count(list), 1);
|
||||
ck_assert(list->remove(list, b, NULL) == 1);
|
||||
ck_assert(list->remove(list, b, NULL) == 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_remove_callback)
|
||||
{
|
||||
void *a = (void*)1, *b = (void*)2;
|
||||
|
||||
list->insert_last(list, a);
|
||||
list->insert_last(list, b);
|
||||
list->insert_last(list, a);
|
||||
list->insert_last(list, b);
|
||||
ck_assert(list->remove(list, a, match_a) == 2);
|
||||
ck_assert(list->remove(list, a, match_a) == 0);
|
||||
ck_assert_int_eq(list->get_count(list), 2);
|
||||
ck_assert(list->remove(list, b, match_b) == 2);
|
||||
ck_assert(list->remove(list, b, match_b) == 0);
|
||||
ck_assert_int_eq(list->get_count(list), 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* find
|
||||
*/
|
||||
|
||||
static bool match_a_b(void *item, void *a, void *b)
|
||||
{
|
||||
ck_assert(a == (void*)1);
|
||||
ck_assert(b == (void*)2);
|
||||
return item == a || item == b;
|
||||
}
|
||||
|
||||
START_TEST(test_find)
|
||||
{
|
||||
void *a = (void*)1, *b = (void*)2;
|
||||
|
||||
ck_assert(list->find_first(list, NULL, &a) == NOT_FOUND);
|
||||
list->insert_last(list, a);
|
||||
ck_assert(list->find_first(list, NULL, &a) == SUCCESS);
|
||||
ck_assert(list->find_first(list, NULL, &b) == NOT_FOUND);
|
||||
list->insert_last(list, b);
|
||||
ck_assert(list->find_first(list, NULL, &a) == SUCCESS);
|
||||
ck_assert(list->find_first(list, NULL, &b) == SUCCESS);
|
||||
|
||||
ck_assert(list->find_first(list, NULL, NULL) == NOT_FOUND);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_find_callback)
|
||||
{
|
||||
void *a = (void*)1, *b = (void*)2, *x = NULL;
|
||||
|
||||
ck_assert(list->find_first(list, (linked_list_match_t)match_a_b, &x, a, b) == NOT_FOUND);
|
||||
list->insert_last(list, a);
|
||||
ck_assert(list->find_first(list, (linked_list_match_t)match_a, NULL, a) == SUCCESS);
|
||||
x = NULL;
|
||||
ck_assert(list->find_first(list, (linked_list_match_t)match_a, &x, a) == SUCCESS);
|
||||
ck_assert(a == x);
|
||||
ck_assert(list->find_first(list, (linked_list_match_t)match_b, &x, b) == NOT_FOUND);
|
||||
ck_assert(a == x);
|
||||
x = NULL;
|
||||
ck_assert(list->find_first(list, (linked_list_match_t)match_a_b, &x, a, b) == SUCCESS);
|
||||
ck_assert(a == x);
|
||||
|
||||
list->insert_last(list, b);
|
||||
ck_assert(list->find_first(list, (linked_list_match_t)match_a, &x, a) == SUCCESS);
|
||||
ck_assert(a == x);
|
||||
ck_assert(list->find_first(list, (linked_list_match_t)match_b, &x, b) == SUCCESS);
|
||||
ck_assert(b == x);
|
||||
x = NULL;
|
||||
ck_assert(list->find_first(list, (linked_list_match_t)match_a_b, &x, a, b) == SUCCESS);
|
||||
ck_assert(a == x);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* invoke
|
||||
*/
|
||||
|
||||
typedef struct invoke_t invoke_t;
|
||||
|
||||
struct invoke_t {
|
||||
int val;
|
||||
void (*invoke)(invoke_t *item, void *a, void *b, void *c, void *d, int *sum);
|
||||
};
|
||||
|
||||
static void invoke(intptr_t item, void *a, void *b, void *c, void *d, int *sum)
|
||||
{
|
||||
ck_assert(a == (void*)1);
|
||||
ck_assert(b == (void*)2);
|
||||
ck_assert(c == (void*)3);
|
||||
ck_assert(d == (void*)4);
|
||||
*sum += item;
|
||||
}
|
||||
|
||||
static void invoke_offset(invoke_t *item, void *a, void *b, void *c, void *d, int *sum)
|
||||
{
|
||||
invoke(item->val, a, b, c, d, sum);
|
||||
}
|
||||
|
||||
START_TEST(test_invoke_function)
|
||||
{
|
||||
int sum = 0;
|
||||
|
||||
list->insert_last(list, (void*)1);
|
||||
list->insert_last(list, (void*)2);
|
||||
list->insert_last(list, (void*)3);
|
||||
list->insert_last(list, (void*)4);
|
||||
list->insert_last(list, (void*)5);
|
||||
list->invoke_function(list, (linked_list_invoke_t)invoke, 1, 2, 3, 4, &sum);
|
||||
ck_assert_int_eq(sum, 15);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_invoke_offset)
|
||||
{
|
||||
invoke_t items[] = {
|
||||
{ .val = 1, .invoke = invoke_offset, },
|
||||
{ .val = 2, .invoke = invoke_offset, },
|
||||
{ .val = 3, .invoke = invoke_offset, },
|
||||
{ .val = 4, .invoke = invoke_offset, },
|
||||
{ .val = 5, .invoke = invoke_offset, },
|
||||
};
|
||||
int i, sum = 0;
|
||||
|
||||
for (i = 0; i < countof(items); i++)
|
||||
{
|
||||
list->insert_last(list, &items[i]);
|
||||
}
|
||||
list->invoke_offset(list, offsetof(invoke_t, invoke), 1, 2, 3, 4, &sum);
|
||||
ck_assert_int_eq(sum, 15);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* clone
|
||||
*/
|
||||
|
||||
typedef struct clone_t clone_t;
|
||||
|
||||
struct clone_t {
|
||||
void *val;
|
||||
void *(*clone)(clone_t *item);
|
||||
};
|
||||
|
||||
static void *clone(clone_t *item)
|
||||
{
|
||||
return item->val;
|
||||
}
|
||||
|
||||
static void test_clone(linked_list_t *list)
|
||||
{
|
||||
intptr_t x;
|
||||
int round = 1;
|
||||
|
||||
ck_assert_int_eq(list->get_count(list), 5);
|
||||
while (list->remove_first(list, (void*)&x) == SUCCESS)
|
||||
{
|
||||
ck_assert_int_eq(round, x);
|
||||
round++;
|
||||
}
|
||||
ck_assert_int_eq(round, 6);
|
||||
}
|
||||
|
||||
START_TEST(test_clone_offset)
|
||||
{
|
||||
linked_list_t *other;
|
||||
clone_t items[] = {
|
||||
{ .val = (void*)1, .clone = clone, },
|
||||
{ .val = (void*)2, .clone = clone, },
|
||||
{ .val = (void*)3, .clone = clone, },
|
||||
{ .val = (void*)4, .clone = clone, },
|
||||
{ .val = (void*)5, .clone = clone, },
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < countof(items); i++)
|
||||
{
|
||||
list->insert_last(list, &items[i]);
|
||||
}
|
||||
other = list->clone_offset(list, offsetof(clone_t, clone));
|
||||
test_clone(other);
|
||||
other->destroy(other);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *linked_list_suite_create()
|
||||
{
|
||||
Suite *s;
|
||||
TCase *tc;
|
||||
|
||||
s = suite_create("linked list");
|
||||
|
||||
tc = tcase_create("insert/get");
|
||||
tcase_add_checked_fixture(tc, setup_list, teardown_list);
|
||||
tcase_add_test(tc, test_insert_first);
|
||||
tcase_add_test(tc, test_insert_last);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("remove");
|
||||
tcase_add_checked_fixture(tc, setup_list, teardown_list);
|
||||
tcase_add_test(tc, test_remove_first);
|
||||
tcase_add_test(tc, test_remove_last);
|
||||
tcase_add_test(tc, test_remove);
|
||||
tcase_add_test(tc, test_remove_callback);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("find");
|
||||
tcase_add_checked_fixture(tc, setup_list, teardown_list);
|
||||
tcase_add_test(tc, test_find);
|
||||
tcase_add_test(tc, test_find_callback);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("invoke");
|
||||
tcase_add_checked_fixture(tc, setup_list, teardown_list);
|
||||
tcase_add_test(tc, test_invoke_function);
|
||||
tcase_add_test(tc, test_invoke_offset);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("clone");
|
||||
tcase_add_checked_fixture(tc, setup_list, teardown_list);
|
||||
tcase_add_test(tc, test_clone_offset);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,361 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_suite.h"
|
||||
|
||||
#include <collections/linked_list.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* test fixture
|
||||
*/
|
||||
|
||||
static linked_list_t *list;
|
||||
|
||||
START_SETUP(setup_list)
|
||||
{
|
||||
list = linked_list_create_with_items((void*)1, (void*)2, (void*)3, (void*)4,
|
||||
(void*)5, NULL);
|
||||
ck_assert_int_eq(list->get_count(list), 5);
|
||||
}
|
||||
END_SETUP
|
||||
|
||||
START_TEARDOWN(teardown_list)
|
||||
{
|
||||
list->destroy(list);
|
||||
}
|
||||
END_TEARDOWN
|
||||
|
||||
/*******************************************************************************
|
||||
* enumeration
|
||||
*/
|
||||
|
||||
START_TEST(test_enumerate)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
intptr_t x;
|
||||
int round;
|
||||
|
||||
round = 1;
|
||||
enumerator = list->create_enumerator(list);
|
||||
while (enumerator->enumerate(enumerator, &x))
|
||||
{
|
||||
ck_assert_int_eq(round, x);
|
||||
round++;
|
||||
}
|
||||
ck_assert_int_eq(round, 6);
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_enumerate_null)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
int round;
|
||||
|
||||
round = 1;
|
||||
enumerator = list->create_enumerator(list);
|
||||
while (enumerator->enumerate(enumerator, NULL))
|
||||
{
|
||||
round++;
|
||||
}
|
||||
ck_assert_int_eq(round, 6);
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_reset_enumerator)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
intptr_t x;
|
||||
int round;
|
||||
|
||||
enumerator = list->create_enumerator(list);
|
||||
while (enumerator->enumerate(enumerator, &x))
|
||||
{
|
||||
}
|
||||
list->reset_enumerator(list, enumerator);
|
||||
round = 1;
|
||||
while (enumerator->enumerate(enumerator, &x))
|
||||
{
|
||||
ck_assert_int_eq(round, x);
|
||||
round++;
|
||||
}
|
||||
ck_assert_int_eq(round, 6);
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* insert before
|
||||
*/
|
||||
|
||||
START_TEST(test_insert_before)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
intptr_t x;
|
||||
int round;
|
||||
|
||||
round = 1;
|
||||
enumerator = list->create_enumerator(list);
|
||||
while (enumerator->enumerate(enumerator, &x))
|
||||
{
|
||||
ck_assert_int_eq(round, x);
|
||||
round++;
|
||||
if (x == _i)
|
||||
{
|
||||
list->insert_before(list, enumerator, (void*)6);
|
||||
}
|
||||
}
|
||||
ck_assert_int_eq(list->get_count(list), 6);
|
||||
list->reset_enumerator(list, enumerator);
|
||||
round = 1;
|
||||
while (enumerator->enumerate(enumerator, &x))
|
||||
{
|
||||
if (round == _i && x != _i)
|
||||
{
|
||||
ck_assert_int_eq(6, x);
|
||||
}
|
||||
else
|
||||
{
|
||||
ck_assert_int_eq(round, x);
|
||||
round++;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_insert_before_ends)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
intptr_t x;
|
||||
int round;
|
||||
|
||||
enumerator = list->create_enumerator(list);
|
||||
list->insert_before(list, enumerator, (void*)0);
|
||||
ck_assert_int_eq(list->get_count(list), 6);
|
||||
ck_assert(list->get_first(list, (void*)&x) == SUCCESS);
|
||||
ck_assert_int_eq(x, 0);
|
||||
round = 0;
|
||||
while (enumerator->enumerate(enumerator, &x))
|
||||
{
|
||||
ck_assert_int_eq(round, x);
|
||||
round++;
|
||||
}
|
||||
list->insert_before(list, enumerator, (void*)6);
|
||||
ck_assert_int_eq(list->get_count(list), 7);
|
||||
ck_assert(list->get_last(list, (void*)&x) == SUCCESS);
|
||||
ck_assert_int_eq(x, 6);
|
||||
ck_assert(!enumerator->enumerate(enumerator, &x));
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_insert_before_empty)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
intptr_t x;
|
||||
|
||||
list->destroy(list);
|
||||
list = linked_list_create();
|
||||
enumerator = list->create_enumerator(list);
|
||||
list->insert_before(list, enumerator, (void*)1);
|
||||
ck_assert_int_eq(list->get_count(list), 1);
|
||||
ck_assert(list->get_first(list, (void*)&x) == SUCCESS);
|
||||
ck_assert_int_eq(x, 1);
|
||||
ck_assert(list->get_last(list, (void*)&x) == SUCCESS);
|
||||
ck_assert_int_eq(x, 1);
|
||||
ck_assert(enumerator->enumerate(enumerator, &x));
|
||||
ck_assert_int_eq(x, 1);
|
||||
ck_assert(!enumerator->enumerate(enumerator, NULL));
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* remove_at
|
||||
*/
|
||||
|
||||
START_TEST(test_remove_at)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
intptr_t x;
|
||||
int round;
|
||||
|
||||
round = 1;
|
||||
enumerator = list->create_enumerator(list);
|
||||
while (enumerator->enumerate(enumerator, &x))
|
||||
{
|
||||
ck_assert_int_eq(round, x);
|
||||
if (round == 2)
|
||||
{
|
||||
list->remove_at(list, enumerator);
|
||||
}
|
||||
round++;
|
||||
}
|
||||
ck_assert_int_eq(list->get_count(list), 4);
|
||||
list->reset_enumerator(list, enumerator);
|
||||
round = 1;
|
||||
while (enumerator->enumerate(enumerator, &x))
|
||||
{
|
||||
if (round == 2)
|
||||
{ /* skip removed item */
|
||||
round++;
|
||||
}
|
||||
ck_assert_int_eq(round, x);
|
||||
round++;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_remove_at_ends)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
intptr_t x;
|
||||
|
||||
enumerator = list->create_enumerator(list);
|
||||
list->remove_at(list, enumerator);
|
||||
ck_assert_int_eq(list->get_count(list), 5);
|
||||
ck_assert(list->get_first(list, (void*)&x) == SUCCESS);
|
||||
ck_assert_int_eq(x, 1);
|
||||
while (enumerator->enumerate(enumerator, &x))
|
||||
{
|
||||
}
|
||||
list->remove_at(list, enumerator);
|
||||
ck_assert_int_eq(list->get_count(list), 5);
|
||||
ck_assert(list->get_last(list, (void*)&x) == SUCCESS);
|
||||
ck_assert_int_eq(x, 5);
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_insert_before_remove_at)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
intptr_t x;
|
||||
int round;
|
||||
|
||||
round = 1;
|
||||
enumerator = list->create_enumerator(list);
|
||||
while (enumerator->enumerate(enumerator, &x))
|
||||
{
|
||||
ck_assert_int_eq(round, x);
|
||||
if (round == 2)
|
||||
{ /* this replaces the current item, as insert_before does not change
|
||||
* the enumerator position */
|
||||
list->insert_before(list, enumerator, (void*)42);
|
||||
list->remove_at(list, enumerator);
|
||||
}
|
||||
else if (round == 4)
|
||||
{ /* this does not replace the item, as remove_at moves the enumerator
|
||||
* position to the previous item */
|
||||
list->remove_at(list, enumerator);
|
||||
list->insert_before(list, enumerator, (void*)21);
|
||||
}
|
||||
round++;
|
||||
}
|
||||
ck_assert_int_eq(list->get_count(list), 5);
|
||||
list->reset_enumerator(list, enumerator);
|
||||
round = 1;
|
||||
while (enumerator->enumerate(enumerator, &x))
|
||||
{
|
||||
if (round == 2)
|
||||
{ /* check replaced item */
|
||||
ck_assert_int_eq(42, x);
|
||||
}
|
||||
else if (round == 3)
|
||||
{ /* check misplaced item */
|
||||
ck_assert_int_eq(21, x);
|
||||
}
|
||||
else if (round == 4)
|
||||
{ /* check misplaced item */
|
||||
ck_assert_int_eq(3, x);
|
||||
}
|
||||
else
|
||||
{
|
||||
ck_assert_int_eq(round, x);
|
||||
}
|
||||
round++;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* create list from enumerator
|
||||
*/
|
||||
|
||||
START_TEST(test_create_from_enumerator)
|
||||
{
|
||||
enumerator_t *enumerator, *enumerator_other;
|
||||
linked_list_t *other;
|
||||
intptr_t x, y;
|
||||
int count = 0;
|
||||
|
||||
enumerator = list->create_enumerator(list);
|
||||
other = linked_list_create_from_enumerator(enumerator);
|
||||
ck_assert_int_eq(other->get_count(list), 5);
|
||||
|
||||
enumerator = list->create_enumerator(list);
|
||||
enumerator_other = other->create_enumerator(other);
|
||||
while (enumerator->enumerate(enumerator, &x) &&
|
||||
enumerator_other->enumerate(enumerator_other, &y))
|
||||
{
|
||||
ck_assert_int_eq(x, y);
|
||||
count++;
|
||||
}
|
||||
ck_assert_int_eq(count, 5);
|
||||
enumerator_other->destroy(enumerator_other);
|
||||
enumerator->destroy(enumerator);
|
||||
other->destroy(other);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *linked_list_enumerator_suite_create()
|
||||
{
|
||||
Suite *s;
|
||||
TCase *tc;
|
||||
|
||||
s = suite_create("linked list and enumerators");
|
||||
|
||||
tc = tcase_create("enumerate");
|
||||
tcase_add_checked_fixture(tc, setup_list, teardown_list);
|
||||
tcase_add_test(tc, test_enumerate);
|
||||
tcase_add_test(tc, test_enumerate_null);
|
||||
tcase_add_test(tc, test_reset_enumerator);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("insert_before()");
|
||||
tcase_add_checked_fixture(tc, setup_list, teardown_list);
|
||||
tcase_add_loop_test(tc, test_insert_before, 1, 5);
|
||||
tcase_add_test(tc, test_insert_before_ends);
|
||||
tcase_add_test(tc, test_insert_before_empty);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("modify");
|
||||
tcase_add_checked_fixture(tc, setup_list, teardown_list);
|
||||
tcase_add_test(tc, test_remove_at);
|
||||
tcase_add_test(tc, test_remove_at_ends);
|
||||
tcase_add_test(tc, test_insert_before_remove_at);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("create_from_enumerator");
|
||||
tcase_add_checked_fixture(tc, setup_list, teardown_list);
|
||||
tcase_add_test(tc, test_create_from_enumerator);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "test_suite.h"
|
||||
|
||||
#include <pen/pen.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* create
|
||||
*/
|
||||
|
||||
START_TEST(test_pen_type_create)
|
||||
{
|
||||
pen_type_t ita_1 = pen_type_create(PEN_ITA, 100);
|
||||
|
||||
ck_assert(ita_1.vendor_id == PEN_ITA);
|
||||
ck_assert(ita_1.type == 100);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* equals
|
||||
*/
|
||||
|
||||
START_TEST(test_pen_type_equals)
|
||||
{
|
||||
pen_type_t ita_1 = pen_type_create(PEN_ITA, 100);
|
||||
pen_type_t ita_2 = pen_type_create(PEN_ITA, 200);
|
||||
pen_type_t fhh_1 = pen_type_create(PEN_FHH, 100);
|
||||
pen_type_t fhh_2 = pen_type_create(PEN_FHH, 200);
|
||||
|
||||
ck_assert( pen_type_equals(ita_1, ita_1));
|
||||
ck_assert(!pen_type_equals(ita_1, ita_2));
|
||||
ck_assert(!pen_type_equals(ita_1, fhh_1));
|
||||
ck_assert(!pen_type_equals(ita_1, fhh_2));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* is
|
||||
*/
|
||||
|
||||
START_TEST(test_pen_type_is)
|
||||
{
|
||||
pen_type_t ita_1 = pen_type_create(PEN_ITA, 100);
|
||||
|
||||
ck_assert( pen_type_is(ita_1, PEN_ITA, 100));
|
||||
ck_assert(!pen_type_is(ita_1, PEN_ITA, 200));
|
||||
ck_assert(!pen_type_is(ita_1, PEN_FHH, 100));
|
||||
ck_assert(!pen_type_is(ita_1, PEN_FHH, 200));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *pen_suite_create()
|
||||
{
|
||||
Suite *s;
|
||||
TCase *tc;
|
||||
|
||||
s = suite_create("pen");
|
||||
|
||||
tc = tcase_create("create");
|
||||
tcase_add_test(tc, test_pen_type_create);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("equals");
|
||||
tcase_add_test(tc, test_pen_type_equals);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("is");
|
||||
tcase_add_test(tc, test_pen_type_is);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Martin Willi
|
||||
* Copyright (C) 2013 revosec AG
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_suite.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
|
||||
static void verify(char *expected, char *format, ...)
|
||||
{
|
||||
FILE *mem;
|
||||
char buf[128];
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
vsnprintf(buf, sizeof(buf), format, args);
|
||||
ck_assert_str_eq(expected, buf);
|
||||
va_end(args);
|
||||
|
||||
mem = fmemopen(buf, sizeof(buf), "w");
|
||||
va_start(args, format);
|
||||
vfprintf(mem, format, args);
|
||||
va_end(args);
|
||||
fclose(mem);
|
||||
ck_assert_str_eq(expected, buf);
|
||||
}
|
||||
|
||||
START_TEST(test_printf_strings)
|
||||
{
|
||||
verify("a bc def", "%s %s %s", "a", "bc", "def");
|
||||
verify("asd", "%.3s", "asdfg");
|
||||
verify("asdf", "%.*s", (int)4, "asdfg");
|
||||
verify(" asdf", "%6s", "asdf");
|
||||
verify(" asdf", "%+6s", "asdf");
|
||||
verify("asdf ", "%-6s", "asdf");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_printf_err)
|
||||
{
|
||||
errno = EINVAL;
|
||||
verify((char*)strerror(errno), "%m");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_printf_unsigned)
|
||||
{
|
||||
verify("1 23 456", "%u %lu %llu", 1, (u_long)23, (u_int64_t)456);
|
||||
verify("65535 255", "%hu %hhu", 0x1ffff, 0x1ff);
|
||||
verify("123456789", "%zu", (size_t)123456789);
|
||||
verify(" 12", "%5u", 12);
|
||||
verify("12 ", "%-5u", 12);
|
||||
verify("0012", "%04u", 12);
|
||||
verify("0012", "%.4u", 12);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_printf_signed)
|
||||
{
|
||||
verify("-1 -23 -456", "%d %ld %lld", -1, (long)-23, (int64_t)-456);
|
||||
verify("-1 -1", "%hd %hhd", 0x1ffff, 0x1ff);
|
||||
verify("123456789", "%zd", (ssize_t)123456789);
|
||||
verify(" -12", "%5d", -12);
|
||||
verify("-12 ", "%-5d", -12);
|
||||
verify("-012", "%04d", -12);
|
||||
verify("-0012", "%.4d", -12);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_printf_hex)
|
||||
{
|
||||
verify("1 23 456", "%x %lx %llx", 1, (u_long)0x23, (u_int64_t)0x456);
|
||||
verify("12abcdef 12ABCDEF", "%x %X", 0x12ABCDEF, 0x12ABCDEF);
|
||||
verify("ffff ff", "%hx %hhx", 0x1ffff, 0x1ff);
|
||||
verify("23456789", "%zx", (size_t)0x23456789);
|
||||
verify(" ab", "%5x", 0xab);
|
||||
verify("ab ", "%-5x", 0xab);
|
||||
verify("00ab", "%04x", 0xab);
|
||||
verify("00ab", "%.4x", 0xab);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_printf_float)
|
||||
{
|
||||
verify("0.000000", "%f", 0.0);
|
||||
verify("1.000000", "%f", 1.0);
|
||||
verify("12345.1", "%.1f", 12345.123);
|
||||
verify("1", "%.0f", 1.0);
|
||||
verify("1.3", "%.1f", 1.346789);
|
||||
verify("1.23", "%.2f", 1.23456789);
|
||||
verify("1.123", "%.3f", 1.123456789);
|
||||
verify("1.0123", "%.4f", 1.0123456789);
|
||||
|
||||
verify("-1.000000", "%f", -1.0);
|
||||
verify("-12345.1", "%.1f", -12345.123);
|
||||
verify("-1", "%.0f", -1.0);
|
||||
verify("-1.3", "%.1f", -1.3456789);
|
||||
verify("-1.23", "%.2f", -1.23456789);
|
||||
verify("-1.123", "%.3f", -1.123456789);
|
||||
verify("-1.0123", "%.4f", -1.0123456789);
|
||||
|
||||
verify(" 1.2", "%5.1f", 1.234);
|
||||
verify("001.2", "%05.1f", 1.234);
|
||||
verify("1.2 ", "%-5.1f", 1.234);
|
||||
|
||||
verify("12346", "%.0f", 12345.6789);
|
||||
verify("2", "%.0f", 1.5);
|
||||
verify("1", "%.0f", 1.49);
|
||||
verify("1.2", "%.1f", 1.151);
|
||||
verify("1.1", "%.1f", 1.149);
|
||||
verify("1.13", "%.2f", 1.1251);
|
||||
verify("1.12", "%.2f", 1.1249);
|
||||
verify("1.124", "%.3f", 1.12351);
|
||||
verify("1.123", "%.3f", 1.12349);
|
||||
|
||||
verify("-12346", "%.0f", -12345.6789);
|
||||
verify("-2", "%.0f", -1.51);
|
||||
verify("-1", "%.0f", -1.49);
|
||||
verify("-1.2", "%.1f", -1.151);
|
||||
verify("-1.1", "%.1f", -1.149);
|
||||
verify("-1.13", "%.2f", -1.1251);
|
||||
verify("-1.12", "%.2f", -1.1249);
|
||||
verify("-1.124", "%.3f", -1.12351);
|
||||
verify("-1.123", "%.3f", -1.12349);
|
||||
|
||||
#ifdef NAN
|
||||
verify("nan", "%.3f", NAN);
|
||||
verify(" nan", "%5.3f", NAN);
|
||||
verify("NAN", "%.3F", NAN);
|
||||
verify("NAN ", "%-5.3F", NAN);
|
||||
#endif
|
||||
#ifdef INFINITY
|
||||
verify("inf", "%.3f", INFINITY);
|
||||
verify("-inf", "%.4f", -INFINITY);
|
||||
verify("INF", "%.3F", INFINITY);
|
||||
verify("-INF", "%.4F", -INFINITY);
|
||||
#endif
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *printf_suite_create()
|
||||
{
|
||||
Suite *s;
|
||||
TCase *tc;
|
||||
|
||||
s = suite_create("printf");
|
||||
|
||||
tc = tcase_create("strings");
|
||||
tcase_add_test(tc, test_printf_strings);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("err");
|
||||
tcase_add_test(tc, test_printf_err);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("unsiged");
|
||||
tcase_add_test(tc, test_printf_unsigned);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("siged");
|
||||
tcase_add_test(tc, test_printf_signed);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("hex");
|
||||
tcase_add_test(tc, test_printf_hex);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("float");
|
||||
tcase_add_test(tc, test_printf_float);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,393 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Martin Willi
|
||||
* Copyright (C) 2013 revosec AG
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_suite.h"
|
||||
|
||||
#include <plugins/plugin_feature.h>
|
||||
|
||||
/**
|
||||
* Signature schemes to test
|
||||
*/
|
||||
static signature_scheme_t schemes[] = {
|
||||
SIGN_RSA_EMSA_PKCS1_NULL,
|
||||
SIGN_RSA_EMSA_PKCS1_MD5,
|
||||
SIGN_RSA_EMSA_PKCS1_SHA1,
|
||||
SIGN_RSA_EMSA_PKCS1_SHA224,
|
||||
SIGN_RSA_EMSA_PKCS1_SHA256,
|
||||
SIGN_RSA_EMSA_PKCS1_SHA384,
|
||||
SIGN_RSA_EMSA_PKCS1_SHA512,
|
||||
};
|
||||
|
||||
/**
|
||||
* Perform a signature verification "good" test having a keypair
|
||||
*/
|
||||
static void test_good_sig(private_key_t *privkey, public_key_t *pubkey)
|
||||
{
|
||||
chunk_t sig, data = chunk_from_chars(0x01,0x02,0x03,0xFD,0xFE,0xFF);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < countof(schemes); i++)
|
||||
{
|
||||
if (!lib->plugins->has_feature(lib->plugins,
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, schemes[i])) ||
|
||||
!lib->plugins->has_feature(lib->plugins,
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, schemes[i])))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
fail_unless(privkey->sign(privkey, schemes[i], data, &sig),
|
||||
"sign %N", signature_scheme_names, schemes[i]);
|
||||
fail_unless(pubkey->verify(pubkey, schemes[i], data, sig),
|
||||
"verify %N", signature_scheme_names, schemes[i]);
|
||||
free(sig.ptr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Some special signatures that should never validate successfully
|
||||
*/
|
||||
static chunk_t invalid_sigs[] = {
|
||||
chunk_from_chars(),
|
||||
chunk_from_chars(0x00),
|
||||
chunk_from_chars(0x00,0x00),
|
||||
chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
|
||||
chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
|
||||
chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
|
||||
chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
|
||||
chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
|
||||
chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
|
||||
};
|
||||
|
||||
/**
|
||||
* Check public key that it properly fails against some crafted sigs
|
||||
*/
|
||||
static void test_bad_sigs(public_key_t *pubkey)
|
||||
{
|
||||
chunk_t data = chunk_from_chars(0x01,0x02,0x03,0xFD,0xFE,0xFF);
|
||||
int s, i;
|
||||
|
||||
for (s = 0; s < countof(schemes); s++)
|
||||
{
|
||||
if (!lib->plugins->has_feature(lib->plugins,
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, schemes[s])))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (i = 0; i < countof(invalid_sigs); i++)
|
||||
{
|
||||
fail_if(
|
||||
pubkey->verify(pubkey, schemes[s], data, invalid_sigs[i]),
|
||||
"bad %N sig accepted %B", signature_scheme_names, schemes[s],
|
||||
&invalid_sigs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* RSA key sizes to test
|
||||
*/
|
||||
static int key_sizes[] = {
|
||||
786, 1024, 1536, 2048, 3072, 4096,
|
||||
};
|
||||
|
||||
START_TEST(test_gen)
|
||||
{
|
||||
private_key_t *privkey;
|
||||
public_key_t *pubkey;
|
||||
|
||||
privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
|
||||
BUILD_KEY_SIZE, key_sizes[_i], BUILD_END);
|
||||
ck_assert(privkey != NULL);
|
||||
pubkey = privkey->get_public_key(privkey);
|
||||
ck_assert(pubkey != NULL);
|
||||
|
||||
test_good_sig(privkey, pubkey);
|
||||
|
||||
test_bad_sigs(pubkey);
|
||||
|
||||
pubkey->destroy(pubkey);
|
||||
privkey->destroy(privkey);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/**
|
||||
* Private keys to load
|
||||
*/
|
||||
static chunk_t keys[] = {
|
||||
chunk_from_chars( /* RSA-768 */
|
||||
0x30,0x82,0x01,0xcb,0x02,0x01,0x00,0x02,0x61,0x00,0xd1,0x5d,0x98,0x97,0x95,0x98,
|
||||
0x19,0x87,0x20,0x3f,0x10,0xb0,0x05,0x36,0x1e,0x1b,0xcd,0xc8,0x93,0x66,0xd7,0x43,
|
||||
0xed,0x84,0xb0,0x3e,0x96,0xd3,0xe7,0x27,0x0e,0xc0,0xba,0xdf,0x7e,0x32,0x05,0xd3,
|
||||
0x08,0xd6,0x44,0xd5,0x01,0x2b,0x3e,0x5d,0xc0,0x37,0xae,0x4f,0xe0,0xea,0x8d,0x2c,
|
||||
0x42,0x4c,0xa9,0xa2,0x42,0xbe,0xdd,0xdb,0xf7,0xd3,0x28,0x07,0x10,0x88,0x53,0x15,
|
||||
0xb2,0x4f,0xb5,0x9d,0x47,0x9b,0xd6,0xc8,0xfe,0x5b,0xa2,0xd7,0xe1,0x13,0xca,0x0b,
|
||||
0xce,0x7a,0xed,0xa2,0x3e,0xd5,0x9b,0xb8,0x8b,0x4f,0x02,0x03,0x01,0x00,0x01,0x02,
|
||||
0x60,0x2d,0x83,0x82,0x53,0x99,0xb2,0xaa,0x02,0x05,0x11,0x90,0xa8,0x23,0x49,0xe3,
|
||||
0x7b,0xb9,0xdd,0x9b,0xa5,0xa4,0xb0,0x60,0xa7,0x12,0xc5,0x58,0x76,0x92,0x6e,0x9c,
|
||||
0x37,0x6b,0xa8,0x80,0x3f,0x91,0xa2,0x91,0xee,0x3a,0xa2,0x6f,0x91,0x9e,0x0a,0x35,
|
||||
0x69,0xc0,0xa7,0xdc,0xd8,0x46,0xe4,0x29,0x1c,0x3d,0x34,0x30,0xa2,0xb9,0x0d,0x34,
|
||||
0x94,0xa1,0x12,0xa7,0x85,0xd3,0x2c,0x47,0x1b,0xf0,0x78,0xd5,0x22,0xfc,0xa5,0xe0,
|
||||
0x75,0xac,0x71,0x21,0xe8,0xe8,0x19,0x9f,0xbb,0x98,0x5c,0xa6,0x9d,0x42,0xd7,0x9c,
|
||||
0x89,0x02,0x31,0x00,0xee,0xaa,0x9e,0x82,0xe1,0xb2,0xdd,0x05,0xbc,0x2e,0x53,0xe9,
|
||||
0x64,0x4b,0x48,0x06,0x3a,0xfd,0x9e,0x91,0xce,0x1b,0x7f,0x66,0xbc,0xd2,0xc4,0xab,
|
||||
0xbf,0xc5,0x5d,0x1a,0xbd,0xd6,0xb5,0x9c,0x5c,0x18,0x01,0xe6,0x79,0x19,0xf2,0xc3,
|
||||
0x1d,0x66,0x88,0x2d,0x02,0x31,0x00,0xe0,0x92,0x34,0x1e,0x09,0xf2,0x1b,0xf9,0xbf,
|
||||
0x11,0x65,0x3f,0xc8,0x85,0x5a,0xe6,0xc0,0xcf,0x93,0x44,0xb0,0x50,0xe4,0x8b,0x6f,
|
||||
0x30,0xde,0x42,0x0c,0x8a,0x77,0x0d,0x98,0x7f,0x52,0x59,0x9e,0x87,0xb8,0x6e,0xdc,
|
||||
0xed,0x15,0x80,0xbd,0xbb,0xf2,0xeb,0x02,0x31,0x00,0xb0,0x6b,0x36,0x98,0x90,0xb5,
|
||||
0x62,0x63,0xa6,0xe2,0xa7,0xec,0x51,0xd2,0xc3,0xfe,0xb7,0x04,0x5a,0x7e,0x74,0xd8,
|
||||
0x26,0xa8,0x8e,0xd3,0x4d,0xc5,0x97,0x10,0x10,0xee,0x7f,0x7d,0x82,0xe9,0x7d,0xb9,
|
||||
0xd1,0x4d,0xc8,0x1e,0xc2,0x30,0x30,0x3f,0x66,0x51,0x02,0x31,0x00,0xaa,0x75,0x2f,
|
||||
0x4c,0x11,0xbe,0x8d,0x0f,0x8f,0xc1,0x13,0x7a,0x4b,0xa9,0x35,0x6b,0x6b,0xb4,0xe3,
|
||||
0x92,0xc2,0xc6,0x54,0x03,0xa6,0x5d,0x90,0x86,0xcf,0xe0,0x16,0x27,0xe2,0xb5,0xd9,
|
||||
0xfb,0x1e,0x82,0xe4,0x32,0x7a,0x4d,0x17,0x02,0x46,0x82,0x30,0x0b,0x02,0x30,0x09,
|
||||
0xf3,0xce,0x9b,0x02,0xc5,0x53,0xe9,0xa2,0x89,0xe2,0x3b,0x8c,0x8b,0xe9,0xc2,0xba,
|
||||
0x94,0x76,0x60,0x27,0x2b,0xe9,0x92,0xc1,0x5e,0x3c,0xc3,0x77,0x9b,0xc7,0xce,0xc6,
|
||||
0x67,0xd5,0x20,0x2c,0x54,0xa1,0x5d,0x2a,0x17,0x16,0x66,0xdf,0x5a,0xe9,0x87,
|
||||
),
|
||||
chunk_from_chars( /* RSA-1024 */
|
||||
0x30,0x82,0x02,0x5c,0x02,0x01,0x00,0x02,0x81,0x81,0x00,0xc0,0xbd,0x48,0x83,0xbc,
|
||||
0xea,0x0b,0x32,0x06,0x4b,0xf5,0x10,0x54,0x1b,0xba,0x88,0xc4,0x10,0x7e,0x47,0xec,
|
||||
0x0e,0xf9,0xb4,0xcf,0x9a,0x02,0xc6,0xb3,0xaf,0x35,0xc8,0xaf,0x78,0x1a,0xbc,0x37,
|
||||
0x1a,0x25,0x7a,0x37,0x24,0x73,0x53,0x9a,0xf0,0x44,0x64,0x5b,0x6b,0x64,0x4c,0xfa,
|
||||
0x83,0x3a,0x0f,0x77,0x5d,0x7b,0x21,0xa2,0x25,0x00,0x11,0xae,0x72,0x36,0x35,0xd9,
|
||||
0x0d,0xef,0x5a,0xdd,0x98,0x35,0x49,0xaf,0x44,0xa0,0x33,0x29,0xc0,0xca,0xf5,0x6f,
|
||||
0xfe,0xc1,0x06,0x4c,0x80,0x9a,0x54,0xbe,0x46,0x1a,0x96,0xb1,0xf3,0x29,0xb8,0x9d,
|
||||
0x07,0x84,0x03,0x68,0x6b,0x9f,0xbf,0xe5,0xd8,0x14,0x2a,0xe0,0xef,0xbd,0x1a,0x61,
|
||||
0x0d,0x3a,0xc8,0x67,0xcd,0x99,0x90,0xe3,0xe6,0x52,0x83,0x02,0x03,0x01,0x00,0x01,
|
||||
0x02,0x81,0x80,0x13,0xd2,0xa3,0xe5,0xa0,0xb0,0x0a,0xe2,0x0f,0x3c,0x65,0x57,0xa8,
|
||||
0xe9,0x87,0xd5,0x79,0xcc,0xc9,0xca,0xc8,0x8a,0xd5,0xc0,0x74,0x90,0x3e,0x1e,0xda,
|
||||
0x40,0xcd,0x42,0xf7,0x01,0x09,0x9c,0x37,0xfd,0x41,0x6e,0x2b,0x6e,0x5d,0x4a,0x1e,
|
||||
0x52,0x53,0x1b,0xbb,0x3c,0x9f,0xfe,0x91,0x79,0x48,0xfc,0x69,0x90,0xbc,0xbc,0x3d,
|
||||
0xcf,0xee,0x62,0x0a,0xbd,0x57,0x6b,0xa9,0x51,0x3e,0xc2,0x7f,0x26,0xb1,0xaa,0x38,
|
||||
0xeb,0x40,0x91,0x3a,0x3c,0x80,0x1e,0x4e,0xe2,0xff,0xa2,0x8e,0x56,0xbb,0xb3,0xeb,
|
||||
0x24,0x81,0x4c,0x19,0x2c,0x8f,0x51,0x4c,0x04,0x81,0xaf,0x5e,0xc2,0xa6,0xf9,0xd3,
|
||||
0x48,0xee,0xe9,0x6d,0x9b,0xe1,0xe5,0x17,0x4f,0x07,0x18,0xea,0x96,0xd3,0x2c,0xce,
|
||||
0x44,0x71,0x51,0x02,0x41,0x00,0xe9,0xe9,0x46,0x7e,0xe1,0xc2,0x86,0x94,0x65,0x77,
|
||||
0x9c,0xc7,0x76,0x5d,0xa0,0xd3,0xcc,0x1f,0xa3,0xc7,0xfe,0xbb,0x4e,0x27,0xd6,0x43,
|
||||
0x6b,0xbd,0x0d,0x05,0x7a,0x10,0xe8,0x48,0x97,0x30,0xaa,0x53,0x61,0x57,0x1f,0x8a,
|
||||
0xf7,0x39,0x5e,0xa6,0xfe,0xe9,0x2c,0x19,0x5e,0x53,0xea,0xc2,0xb2,0xc2,0x11,0x3c,
|
||||
0x18,0xab,0xcf,0xc4,0x91,0x1b,0x02,0x41,0x00,0xd2,0xf0,0xb1,0x49,0xa1,0x6f,0xf1,
|
||||
0x83,0xa3,0xd2,0xa1,0x0e,0xb3,0xb3,0x33,0x01,0xed,0xd0,0x28,0xc1,0x2f,0x88,0x80,
|
||||
0x9f,0x43,0x7c,0x7e,0x5d,0x4c,0x15,0x05,0x86,0xff,0x75,0x9b,0xf1,0x64,0xde,0x06,
|
||||
0xbf,0xdd,0x98,0x50,0xd9,0x4a,0x3a,0xd6,0x25,0x1c,0xdd,0xc8,0x56,0x12,0x11,0xb9,
|
||||
0x02,0x42,0xc7,0x1d,0x86,0xeb,0xd9,0xc2,0xb9,0x02,0x41,0x00,0x80,0x25,0x8c,0xb9,
|
||||
0x76,0x75,0x5b,0xc5,0x70,0xd1,0x56,0xd2,0xef,0xc5,0xdb,0x96,0x2c,0xfe,0x28,0x7c,
|
||||
0x28,0xd1,0xf4,0xbf,0x5e,0x63,0x11,0x63,0x40,0xfe,0xff,0x20,0xc4,0x21,0x00,0xb3,
|
||||
0x68,0x9c,0xc5,0x77,0x35,0x90,0xac,0x60,0x81,0xba,0x7b,0x6c,0xc2,0xfc,0x22,0xf1,
|
||||
0x56,0x6b,0xd4,0x02,0xfd,0xee,0x2e,0x95,0xf1,0xfd,0x7e,0x81,0x02,0x40,0x47,0xaf,
|
||||
0x84,0x90,0x81,0x4c,0x89,0xc7,0x32,0xe5,0x61,0xd6,0x9d,0x3b,0x49,0x1a,0x5e,0xb7,
|
||||
0x5f,0x22,0x48,0x05,0x1b,0xb1,0x04,0x3e,0x4a,0xb3,0x6a,0x27,0xba,0xb9,0x26,0x17,
|
||||
0xd1,0xe7,0x37,0x60,0x3c,0xea,0xf7,0x63,0xcc,0x16,0x0c,0x23,0xf2,0xa2,0xaa,0x2c,
|
||||
0xb4,0xe8,0x8b,0x3b,0x7a,0xa4,0x4a,0x0d,0x60,0xfb,0x79,0x2b,0x88,0x01,0x02,0x40,
|
||||
0x42,0xee,0x12,0x91,0xf9,0x80,0x1e,0x60,0x0b,0xaa,0xbe,0xfd,0x09,0x84,0x93,0x0d,
|
||||
0x09,0xd3,0x1e,0x37,0x52,0xb0,0xe8,0x51,0x4f,0xd3,0x9e,0xda,0x32,0x38,0x22,0x35,
|
||||
0xdb,0x25,0x8b,0x9f,0x1a,0xb5,0xf1,0x75,0xfa,0x4d,0x09,0x42,0x01,0x64,0xe6,0xc4,
|
||||
0x6e,0xba,0x2d,0x88,0x92,0xbe,0xa9,0x1f,0x85,0x38,0x10,0xa3,0x0e,0x1a,0x92,0x54,
|
||||
),
|
||||
chunk_from_chars( /* RSA-1536 */
|
||||
0x30,0x82,0x03,0x7d,0x02,0x01,0x00,0x02,0x81,0xc1,0x00,0xba,0xe3,0x37,0x93,0x7e,
|
||||
0x42,0x13,0x3c,0xba,0x41,0xc1,0x7b,0xf0,0xcc,0x7a,0x44,0xc6,0x54,0xc8,0x77,0x01,
|
||||
0x70,0x2f,0x6e,0x4a,0xcf,0x2d,0x07,0xab,0x01,0xc0,0x43,0xab,0x8d,0x33,0xb3,0xd4,
|
||||
0xeb,0xe3,0x90,0xf6,0x01,0x03,0x75,0x03,0x1d,0xe8,0x06,0x40,0x15,0xfa,0x96,0x0b,
|
||||
0xd5,0x26,0x64,0xea,0x55,0x82,0x16,0x7b,0xd5,0x1e,0xaa,0x08,0xc7,0x30,0x1a,0x59,
|
||||
0xf8,0xd9,0xe3,0x9e,0x89,0xd9,0x92,0x2c,0x32,0x79,0x0e,0xb3,0x25,0xbc,0x1d,0x7c,
|
||||
0x59,0xde,0x05,0x47,0x8f,0x61,0x77,0xf5,0x4f,0xed,0x82,0x2c,0xf8,0x2a,0x3e,0x02,
|
||||
0xf3,0xc0,0x15,0x51,0xde,0x05,0xc4,0xfc,0x80,0x91,0xae,0x06,0x1b,0xd7,0x39,0x8e,
|
||||
0x9a,0x6d,0xb3,0x2f,0xb0,0xd0,0xc8,0x96,0xa6,0x88,0xb3,0x17,0xca,0x58,0xbe,0x38,
|
||||
0x2c,0x64,0x35,0x5a,0x29,0xb7,0xf8,0x74,0x3d,0xbb,0xec,0x90,0x01,0x04,0x64,0x3d,
|
||||
0x38,0x0f,0x87,0xce,0xd7,0xfc,0xd2,0x96,0x93,0x31,0x85,0x0d,0x2d,0xa5,0x91,0xe2,
|
||||
0xfc,0x7b,0xea,0xb0,0x89,0x24,0xaa,0x00,0x29,0x8c,0x26,0x7c,0x94,0x54,0x74,0xe4,
|
||||
0x11,0xa8,0x04,0x6f,0x40,0xeb,0xaf,0xed,0xac,0x75,0x33,0x02,0x03,0x01,0x00,0x01,
|
||||
0x02,0x81,0xc0,0x0a,0x96,0xec,0x63,0xc1,0xa0,0x39,0xd9,0xd3,0x8d,0xfd,0x4a,0x2a,
|
||||
0x13,0x54,0x0c,0x48,0x96,0xae,0x43,0x3c,0x04,0x20,0xd3,0xe5,0x8e,0x46,0xb5,0x6c,
|
||||
0x05,0xad,0xe0,0xc7,0xbc,0x39,0x05,0x44,0x17,0xd7,0xad,0xb3,0x9a,0xcc,0x18,0xd9,
|
||||
0xc3,0xdc,0x8d,0x5a,0x1d,0x44,0xb5,0x32,0xd7,0x71,0x94,0xff,0x48,0x38,0x16,0x51,
|
||||
0x0e,0xfa,0xed,0x54,0x91,0x00,0xd3,0x45,0x6c,0xd9,0xdf,0xd1,0x70,0x6b,0x31,0x22,
|
||||
0xaa,0xfb,0x7c,0x0f,0x3f,0xa0,0xa0,0xa5,0x16,0xac,0x83,0x6d,0x12,0x1d,0x4a,0x40,
|
||||
0x4e,0xb6,0x9c,0xf4,0x67,0xaa,0xa9,0xb0,0xc8,0xb4,0x0a,0xd5,0x3b,0x5c,0x19,0xed,
|
||||
0x86,0x83,0x5a,0x75,0xbc,0xeb,0x17,0xc8,0x16,0xa0,0x60,0x2e,0xb6,0x25,0xc5,0x4d,
|
||||
0x59,0xba,0x62,0xcb,0x3d,0x91,0x7c,0x79,0x6a,0x4b,0x4a,0x54,0xbd,0xb7,0xa3,0x89,
|
||||
0x7f,0xbf,0x0e,0x77,0xe1,0x54,0x29,0x0d,0x45,0x6d,0xa8,0x15,0xa5,0x17,0x8c,0xcf,
|
||||
0x27,0x9e,0x47,0x4e,0x2a,0x91,0x7e,0x4e,0x14,0x59,0x8c,0x62,0x91,0xa3,0x40,0xa5,
|
||||
0x9e,0x67,0xbb,0x02,0x97,0xb4,0xe7,0x06,0x04,0xbc,0x16,0x24,0x3d,0x49,0xb1,0xf0,
|
||||
0xae,0xfc,0x1d,0x02,0x61,0x00,0xde,0x86,0x5d,0x49,0x88,0xeb,0x5c,0xd3,0xe5,0x11,
|
||||
0x48,0x0b,0x1e,0x52,0x95,0xa9,0x65,0x99,0x89,0xcf,0x51,0xb0,0x08,0xdd,0xb5,0x5b,
|
||||
0x64,0x1a,0x34,0xd2,0xee,0x4b,0x2d,0x8b,0xc1,0xd5,0xd6,0x1d,0x6c,0x0c,0x7e,0xa5,
|
||||
0x66,0x12,0xec,0xaf,0x5d,0xe9,0x33,0xd4,0xba,0x18,0x71,0x84,0x97,0xbe,0xc0,0x75,
|
||||
0x63,0x19,0xae,0xc6,0xc7,0x65,0xf3,0xf6,0xda,0x3f,0x91,0xfa,0x5e,0x87,0xf3,0xbc,
|
||||
0xd2,0x64,0x8d,0xcf,0xfb,0xdd,0x7f,0x9b,0x6c,0x81,0xba,0x9b,0x4e,0x94,0x5e,0x83,
|
||||
0xd1,0xcb,0xb9,0xf4,0x39,0x7f,0x02,0x61,0x00,0xd7,0x00,0x6d,0x8e,0x1b,0xa1,0x44,
|
||||
0xd9,0xff,0xe6,0x42,0x72,0x18,0x55,0x26,0x3e,0x87,0x40,0x71,0xb2,0x67,0x37,0x16,
|
||||
0xe9,0xbd,0x51,0x7f,0x0e,0x79,0x0e,0x75,0xa9,0x1f,0x0f,0x6b,0xa5,0x7c,0x5f,0xc8,
|
||||
0xdc,0x17,0xde,0x53,0x88,0x97,0x90,0x88,0xf2,0x4d,0x66,0x5e,0x0e,0x11,0x16,0x92,
|
||||
0x1e,0x61,0x56,0xe6,0xf0,0x74,0x81,0x58,0x95,0x05,0x29,0x71,0x9b,0xa0,0x69,0xed,
|
||||
0x14,0x23,0xf6,0x36,0x9b,0x8f,0x06,0x3a,0x76,0xab,0xeb,0xce,0xe8,0xdc,0x79,0xc1,
|
||||
0x29,0xb9,0xfc,0x49,0x7a,0x26,0x59,0xd6,0x4d,0x02,0x61,0x00,0xaf,0x3c,0xac,0xd6,
|
||||
0x2d,0xe6,0xfb,0x91,0x3a,0xc1,0x23,0x34,0xee,0x4a,0x26,0xe5,0xe1,0xc6,0xc9,0xc9,
|
||||
0xe4,0x10,0x76,0xca,0xf1,0xf8,0xe8,0x99,0xe2,0xa3,0x81,0x58,0xde,0xa3,0x42,0xa0,
|
||||
0x3d,0x1f,0xaa,0x69,0x24,0x8a,0xe8,0x19,0x5b,0x1e,0xb7,0x1b,0xe0,0xdf,0x53,0x35,
|
||||
0xd0,0x9f,0x94,0x48,0x79,0x93,0x77,0xd9,0x4f,0xd3,0xe6,0x4f,0x19,0x92,0x7a,0x48,
|
||||
0xb9,0x92,0xab,0x42,0xf0,0xe4,0xef,0xe2,0x93,0xf3,0x07,0xeb,0x64,0x84,0x67,0x2c,
|
||||
0xba,0x61,0x77,0xbe,0x4b,0xb8,0x0f,0x4d,0x1a,0x41,0x83,0xcd,0x02,0x60,0x56,0xec,
|
||||
0x55,0x5e,0x9e,0xcd,0x14,0x89,0x0e,0x6c,0x89,0x70,0x97,0x65,0xd5,0x90,0x72,0x1e,
|
||||
0x1b,0xd9,0x84,0xe1,0x40,0xe2,0x3f,0x28,0x33,0xb6,0x26,0x3b,0x32,0x56,0xad,0xb8,
|
||||
0x0e,0x4d,0x59,0x7b,0x60,0x39,0x9b,0x6c,0xc7,0x58,0xf1,0xed,0xfd,0x6f,0xf8,0xda,
|
||||
0xea,0x2b,0xc5,0xbc,0xda,0x56,0x6e,0x04,0x34,0x5a,0x02,0xc0,0x48,0x8f,0xf7,0x06,
|
||||
0x4a,0x68,0x20,0xf2,0xb2,0x66,0xf2,0x23,0x18,0xf0,0xcb,0x62,0x39,0x40,0xc1,0x41,
|
||||
0x14,0xe6,0x10,0x3d,0x29,0x5b,0x35,0x56,0x4a,0x5e,0x98,0x22,0xba,0x01,0x02,0x61,
|
||||
0x00,0xcc,0x80,0xb7,0xb9,0xb9,0x4a,0xaf,0x47,0x00,0x3e,0x21,0x0f,0xb8,0x4e,0x7c,
|
||||
0xb1,0xe4,0x25,0xd6,0x19,0x26,0x54,0xc6,0x8c,0x30,0x88,0x54,0x70,0xcf,0x1f,0x62,
|
||||
0x75,0xcb,0x18,0x58,0x6c,0x14,0xb0,0x9b,0x13,0x90,0xa2,0x1a,0x5a,0x79,0xa3,0x82,
|
||||
0xf0,0x9b,0xba,0xf0,0x90,0xaf,0xa1,0xe8,0xa8,0x70,0xef,0x60,0x6a,0x68,0xed,0x5a,
|
||||
0x21,0x77,0x69,0x7a,0xf2,0xee,0x3e,0xe5,0x90,0xd2,0x33,0x71,0x3b,0x82,0x88,0x75,
|
||||
0xdd,0x8e,0x6e,0xbc,0x17,0x83,0xef,0x37,0x82,0x4e,0x83,0x30,0xcb,0x8a,0xbc,0x6c,
|
||||
0x41,
|
||||
),
|
||||
chunk_from_chars( /* RSA-2048 */
|
||||
0x30,0x82,0x04,0xa2,0x02,0x01,0x00,0x02,0x82,0x01,0x01,0x00,0xba,0xbf,0x27,0x0b,
|
||||
0x22,0x59,0xd8,0x6f,0xff,0x26,0x5d,0x41,0x3d,0xb0,0x94,0x58,0x5d,0xc0,0x46,0xb6,
|
||||
0x77,0xa9,0x78,0x10,0x6d,0xe9,0xbf,0xca,0x6f,0x04,0xe1,0xda,0x85,0x12,0x1e,0xe0,
|
||||
0xa6,0xc7,0xa2,0x71,0x04,0x8b,0x6e,0x84,0xf9,0x86,0x2b,0xeb,0x72,0x01,0x72,0xc8,
|
||||
0x0a,0x83,0xa6,0xf7,0xc0,0xd6,0x76,0x1d,0x28,0x38,0xb5,0x7e,0x6c,0x8c,0x6a,0x13,
|
||||
0xf4,0xf1,0x7f,0xf2,0x79,0xae,0x73,0xba,0x1a,0x3f,0x30,0x65,0xb6,0x23,0xa7,0x94,
|
||||
0x34,0x29,0x87,0xce,0x06,0x99,0xee,0x85,0x10,0xce,0x08,0xe2,0x8d,0xd5,0x47,0xf3,
|
||||
0xc8,0xf0,0x18,0x41,0xc0,0x59,0x66,0x06,0xda,0xb6,0x18,0xd2,0xa3,0xa0,0xbd,0x3a,
|
||||
0x90,0x7f,0x37,0x39,0xdf,0x98,0x55,0xa2,0x19,0x5e,0x37,0xbc,0x86,0xf3,0x02,0xf8,
|
||||
0x68,0x49,0x53,0xf2,0x4b,0x3d,0x7a,0xe3,0x1d,0xa4,0x15,0x10,0xa6,0xce,0x8c,0xb8,
|
||||
0xfd,0x95,0x54,0xa2,0x50,0xa2,0xd9,0x35,0x12,0x56,0xae,0xbc,0x51,0x33,0x6d,0xb8,
|
||||
0x63,0x7c,0x26,0xab,0x19,0x01,0xa5,0xda,0xfa,0x4b,0xb6,0x57,0xd3,0x4b,0xdd,0xc0,
|
||||
0x62,0xc5,0x05,0xb7,0xc3,0x2e,0x1f,0x17,0xc8,0x09,0x87,0x12,0x37,0x21,0xd7,0x7a,
|
||||
0x53,0xb0,0x47,0x60,0xa2,0xb5,0x23,0x3b,0x99,0xdf,0xea,0x8b,0x94,0xea,0x9d,0x53,
|
||||
0x5d,0x02,0x52,0xf7,0x29,0xfb,0x63,0xb0,0xff,0x27,0x5e,0xde,0x54,0x7d,0x95,0xd6,
|
||||
0x4e,0x58,0x12,0x06,0x60,0x22,0x33,0xf2,0x19,0x67,0x65,0xdd,0xf3,0x42,0xb5,0x00,
|
||||
0x51,0x35,0xe5,0x62,0x4d,0x90,0x44,0xfb,0x7f,0x5b,0xb5,0xe5,0x02,0x03,0x01,0x00,
|
||||
0x01,0x02,0x82,0x01,0x00,0x1c,0xf5,0x66,0xf5,0xce,0x4c,0x1d,0xe8,0xd2,0x29,0x6e,
|
||||
0x15,0x1f,0x9e,0x9a,0x06,0x70,0xf5,0x4f,0xd1,0xdc,0x51,0x02,0x8e,0x13,0xa9,0x47,
|
||||
0x85,0x39,0xfd,0x89,0x13,0x74,0x86,0xb8,0x94,0x90,0x30,0x4d,0x73,0x96,0xa7,0x93,
|
||||
0x8a,0x19,0xd2,0x91,0x4d,0x77,0xb6,0x9b,0x48,0xc3,0x7e,0xa2,0x5d,0xf1,0x80,0xa0,
|
||||
0x3c,0xc9,0xbf,0xaf,0x7f,0x4d,0x10,0x62,0x23,0xb9,0x9c,0x58,0x81,0xae,0x96,0x5b,
|
||||
0x9a,0x4c,0x97,0x27,0x67,0x62,0x5c,0xf9,0x8f,0xdd,0x1d,0xe2,0x92,0x13,0x8a,0x7b,
|
||||
0xc7,0x15,0x31,0xca,0x05,0x6d,0xc6,0x98,0xdb,0x88,0x39,0x99,0x1d,0x5b,0x19,0x51,
|
||||
0xdd,0xb6,0xbd,0x3d,0xb0,0xae,0x50,0x8e,0xff,0x7d,0xa8,0x48,0x95,0x58,0x23,0xbc,
|
||||
0x85,0xc0,0x46,0xd0,0xc0,0x0e,0xda,0xdd,0xa4,0x8e,0x8d,0x31,0x8b,0x89,0x0f,0x8b,
|
||||
0x76,0x9a,0xb5,0x99,0x56,0x5e,0xd3,0x0c,0x88,0x0b,0x03,0xf1,0xc9,0xe3,0x05,0x05,
|
||||
0x08,0x75,0xce,0x35,0x52,0xa0,0xc0,0xf2,0xf4,0xb9,0x87,0x22,0x21,0x3f,0x61,0xd6,
|
||||
0x99,0xae,0x0e,0x76,0x5d,0x9c,0x16,0xa3,0xe9,0xde,0x2d,0x2a,0x46,0xf7,0x89,0xbf,
|
||||
0x0d,0xb1,0x60,0xad,0xbc,0x24,0xe2,0xe5,0xb1,0xc1,0x1c,0x00,0x40,0x1c,0xbd,0xfa,
|
||||
0x6e,0xc7,0x0d,0xc1,0xda,0x4d,0x54,0x45,0x96,0xac,0xf7,0xfe,0x1b,0xf2,0x47,0x1e,
|
||||
0xf7,0x8b,0xcf,0x27,0xcc,0xe7,0x08,0xd6,0x43,0x60,0xea,0xda,0x19,0xd7,0x98,0x17,
|
||||
0x7c,0xab,0x0c,0x90,0x60,0x75,0x9f,0x8b,0xaa,0x13,0x63,0x98,0x9e,0xc6,0x41,0x9f,
|
||||
0xd4,0x85,0xa3,0xb2,0xb9,0x02,0x81,0x81,0x00,0xe1,0x20,0xf6,0xac,0xa9,0x01,0xbd,
|
||||
0x31,0xe6,0xb2,0x4e,0xcf,0x66,0xc3,0x11,0x0e,0x5b,0xfe,0x58,0x6b,0xc6,0x2d,0x7a,
|
||||
0x05,0x30,0x9a,0x6f,0xcc,0xcc,0xdf,0xd2,0x2c,0xe1,0x47,0x39,0x9e,0xf3,0x0c,0x81,
|
||||
0xd9,0x76,0x00,0xe2,0xb1,0x08,0x91,0xfb,0x12,0x04,0xf6,0x1f,0xea,0xff,0x82,0xe5,
|
||||
0x64,0x64,0x6f,0x14,0xbe,0x33,0x5f,0x41,0x5f,0x73,0x1f,0xa2,0x32,0xec,0x75,0xb3,
|
||||
0x98,0x4b,0x88,0x4d,0x1e,0xec,0x78,0xda,0x4c,0x2d,0xf8,0xbb,0xcf,0x0e,0x8f,0x2f,
|
||||
0x23,0xae,0xcd,0xe0,0x4c,0x13,0x1c,0x1c,0x16,0x8e,0xb9,0x9f,0x02,0x12,0x12,0xa5,
|
||||
0xf4,0x21,0xfe,0x57,0x08,0x7a,0xe8,0xbe,0x15,0xe9,0xdd,0x2a,0xd1,0x7b,0x39,0xd6,
|
||||
0x4f,0x70,0x74,0x7d,0xfd,0x39,0x97,0x80,0x8d,0x02,0x81,0x81,0x00,0xd4,0x5a,0xce,
|
||||
0x05,0x93,0x51,0x15,0x44,0xdd,0x4d,0x79,0x92,0x04,0xe6,0x64,0x7e,0x6c,0xb5,0x61,
|
||||
0x6b,0xc3,0xb3,0xae,0x4f,0x0a,0x75,0xbf,0x6c,0xec,0x47,0xf2,0xbc,0xea,0x76,0xc4,
|
||||
0xc2,0xe7,0xd2,0x50,0xc4,0xe0,0xaf,0x56,0x05,0x72,0x3c,0x34,0x8c,0x5b,0xae,0xb8,
|
||||
0x0e,0xfb,0x83,0x27,0xcf,0x61,0x05,0x44,0x97,0x3f,0x66,0x6d,0x26,0x7d,0xed,0xcd,
|
||||
0x5a,0x87,0x04,0xbc,0xb3,0x70,0x75,0x15,0x51,0xe9,0x18,0x85,0xf7,0x2a,0x45,0xd5,
|
||||
0xc7,0x93,0x32,0x07,0x2e,0x26,0x34,0x2d,0x18,0x63,0x45,0x06,0x6f,0xa9,0x75,0x5d,
|
||||
0x20,0x6b,0x0b,0x13,0x45,0x81,0x7e,0x5c,0xc5,0x48,0x16,0x4b,0x82,0x7c,0xad,0xbe,
|
||||
0xfd,0xa5,0x0a,0xd6,0xc2,0x21,0xfc,0xa5,0x84,0xaf,0xf3,0x10,0xb9,0x02,0x81,0x80,
|
||||
0x29,0x20,0x20,0x6f,0xc2,0x1f,0xf3,0x33,0xde,0x74,0xcc,0x38,0xcf,0x08,0xeb,0x60,
|
||||
0xb8,0x25,0x6a,0x79,0xa5,0xa6,0x41,0x18,0x19,0x9c,0xdc,0xb7,0x88,0xe5,0x8a,0x3b,
|
||||
0x70,0x9b,0xd6,0x46,0xd7,0x17,0x7d,0xd0,0xff,0xe1,0x81,0x87,0xdd,0x8c,0xed,0x54,
|
||||
0x89,0x5b,0x7c,0xd1,0x2d,0x03,0xf8,0x6b,0xb2,0x7d,0x28,0x48,0xe6,0x91,0x8c,0x1b,
|
||||
0xa7,0xa8,0x2b,0xb5,0x29,0xc5,0x06,0x9d,0xd7,0x8e,0x7a,0xa8,0x1f,0x82,0xa4,0x3e,
|
||||
0x2e,0x57,0xb5,0xd7,0x49,0x4d,0x96,0xca,0xe9,0xef,0xe9,0xfd,0x7b,0xb0,0x32,0xe1,
|
||||
0x5c,0x09,0x44,0xa6,0xd8,0x2e,0x57,0xea,0x95,0x1b,0x25,0x43,0x03,0x50,0xe9,0x08,
|
||||
0x8f,0xc4,0x3b,0x42,0x31,0x44,0x8b,0x85,0xcf,0x81,0x38,0x52,0xbd,0xe6,0x93,0x31,
|
||||
0x02,0x81,0x80,0x18,0x3d,0x79,0x51,0x07,0x9c,0xf4,0xd9,0x94,0x8d,0x78,0x78,0x23,
|
||||
0x99,0x0d,0x15,0xa5,0x61,0x1b,0x0a,0xcb,0x1f,0x22,0xa1,0xa1,0x27,0x09,0xbf,0xec,
|
||||
0x44,0xd6,0x3f,0x9c,0x60,0x0c,0x5b,0xd7,0x4c,0x99,0xad,0xaf,0x9c,0x34,0x2c,0x90,
|
||||
0xfa,0xb0,0x60,0xe9,0x42,0x4b,0x7e,0x62,0x55,0x79,0x60,0xe1,0xc9,0x51,0x28,0x16,
|
||||
0xb3,0xa1,0x78,0x08,0x5d,0xf1,0xd8,0x08,0x9b,0x90,0xd2,0xc6,0xde,0x86,0x9d,0x80,
|
||||
0x07,0x2d,0x9b,0xa6,0x36,0xac,0x8d,0x88,0x8e,0xe8,0x64,0xeb,0x35,0x7f,0x84,0x4e,
|
||||
0x28,0x9d,0xf0,0x77,0x1e,0x8f,0x8f,0xd8,0xc8,0x3d,0xdd,0xec,0x47,0x39,0x5d,0xc7,
|
||||
0xb9,0xcb,0xca,0xcc,0x62,0xa4,0xef,0x9d,0x3c,0x5c,0x81,0x72,0x91,0xbd,0x6f,0x25,
|
||||
0x0a,0x90,0xf9,0x02,0x81,0x80,0x51,0x42,0x23,0x64,0x3d,0xbc,0xcb,0xcb,0x77,0xd4,
|
||||
0x5c,0x6b,0xf4,0x16,0x3a,0x6b,0x05,0x5f,0xd4,0xf8,0x59,0xe6,0x98,0x0c,0x43,0x7e,
|
||||
0x6b,0x17,0x0d,0x01,0x23,0x6e,0x4c,0xff,0x35,0xe4,0xc5,0xba,0xe8,0x9e,0x12,0x94,
|
||||
0x34,0x78,0xe4,0x3d,0x35,0xa1,0xd4,0xa9,0xa3,0x7e,0xe4,0x57,0xef,0xa4,0x9a,0x6a,
|
||||
0x32,0xb3,0x9f,0xf8,0x3a,0xcf,0xea,0xf4,0xc7,0x59,0x92,0xd4,0x2a,0x5b,0x26,0x83,
|
||||
0x78,0x30,0x5f,0xdf,0x46,0xa6,0xb0,0x28,0x37,0x2b,0x55,0x08,0x4c,0xb6,0x6b,0xb8,
|
||||
0xa9,0x11,0x7d,0x0b,0xab,0x97,0x4d,0x8c,0xc3,0xbf,0x3b,0xcd,0x3e,0xad,0x80,0xce,
|
||||
0xe8,0xc6,0x01,0x35,0xd2,0x3e,0x31,0xdc,0x96,0xd7,0xc3,0xab,0x65,0xd1,0xc4,0xa3,
|
||||
0x47,0x14,0xa9,0xba,0xd0,0x30,
|
||||
),
|
||||
};
|
||||
|
||||
START_TEST(test_load)
|
||||
{
|
||||
private_key_t *privkey;
|
||||
public_key_t *pubkey;
|
||||
|
||||
privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
|
||||
BUILD_BLOB_ASN1_DER, keys[_i], BUILD_END);
|
||||
ck_assert(privkey != NULL);
|
||||
pubkey = privkey->get_public_key(privkey);
|
||||
ck_assert(pubkey != NULL);
|
||||
|
||||
test_good_sig(privkey, pubkey);
|
||||
|
||||
test_bad_sigs(pubkey);
|
||||
|
||||
pubkey->destroy(pubkey);
|
||||
privkey->destroy(privkey);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *rsa_suite_create()
|
||||
{
|
||||
Suite *s;
|
||||
TCase *tc;
|
||||
|
||||
s = suite_create("rsa");
|
||||
|
||||
tc = tcase_create("generate");
|
||||
tcase_add_loop_test(tc, test_gen, 0, countof(key_sizes));
|
||||
tcase_set_timeout(tc, 8);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("load");
|
||||
tcase_add_loop_test(tc, test_load, 0, countof(keys));
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sched.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "test_suite.h"
|
||||
|
||||
#include <threading/mutex.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* recursive mutex test
|
||||
*/
|
||||
|
||||
#define THREADS 20
|
||||
|
||||
static mutex_t *mutex;
|
||||
|
||||
static pthread_barrier_t mutex_barrier;
|
||||
|
||||
static int mutex_locked = 0;
|
||||
|
||||
static void *mutex_run(void *data)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* wait for all threads before getting in action */
|
||||
pthread_barrier_wait(&mutex_barrier);
|
||||
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
mutex->lock(mutex);
|
||||
mutex->lock(mutex);
|
||||
mutex->lock(mutex);
|
||||
mutex_locked++;
|
||||
sched_yield();
|
||||
if (mutex_locked > 1)
|
||||
{
|
||||
fail("two threads locked the mutex concurrently");
|
||||
}
|
||||
mutex_locked--;
|
||||
mutex->unlock(mutex);
|
||||
mutex->unlock(mutex);
|
||||
mutex->unlock(mutex);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
START_TEST(test_mutex)
|
||||
{
|
||||
pthread_t threads[THREADS];
|
||||
int i;
|
||||
|
||||
mutex = mutex_create(MUTEX_TYPE_RECURSIVE);
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
mutex->lock(mutex);
|
||||
mutex->unlock(mutex);
|
||||
}
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
mutex->lock(mutex);
|
||||
}
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
mutex->unlock(mutex);
|
||||
}
|
||||
|
||||
pthread_barrier_init(&mutex_barrier, NULL, THREADS);
|
||||
for (i = 0; i < THREADS; i++)
|
||||
{
|
||||
pthread_create(&threads[i], NULL, mutex_run, NULL);
|
||||
}
|
||||
for (i = 0; i < THREADS; i++)
|
||||
{
|
||||
pthread_join(threads[i], NULL);
|
||||
}
|
||||
pthread_barrier_destroy(&mutex_barrier);
|
||||
|
||||
mutex->destroy(mutex);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *threading_suite_create()
|
||||
{
|
||||
Suite *s;
|
||||
TCase *tc;
|
||||
|
||||
s = suite_create("threading");
|
||||
|
||||
tc = tcase_create("recursive mutex");
|
||||
tcase_add_test(tc, test_mutex);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,556 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_suite.h"
|
||||
|
||||
#include <library.h>
|
||||
#include <utils/utils.h>
|
||||
#include <ipsec/ipsec_types.h>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* object storage on lib
|
||||
*/
|
||||
|
||||
START_TEST(test_objects)
|
||||
{
|
||||
char *k1 = "key1", *k2 = "key2";
|
||||
char *v1 = "val1", *val;
|
||||
|
||||
ck_assert(lib->get(lib, k1) == NULL);
|
||||
|
||||
ck_assert(lib->set(lib, k1, v1));
|
||||
ck_assert(!lib->set(lib, k1, v1));
|
||||
|
||||
val = lib->get(lib, k1);
|
||||
ck_assert(val != NULL);
|
||||
ck_assert(streq(val, v1));
|
||||
|
||||
ck_assert(lib->set(lib, k1, NULL));
|
||||
ck_assert(!lib->set(lib, k2, NULL));
|
||||
|
||||
ck_assert(lib->get(lib, k1) == NULL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* test return_... functions
|
||||
*/
|
||||
|
||||
START_TEST(test_return_functions)
|
||||
{
|
||||
ck_assert(return_null() == NULL);
|
||||
ck_assert(return_null("asdf", 5, NULL, 1, "qwer") == NULL);
|
||||
|
||||
ck_assert(return_true() == TRUE);
|
||||
ck_assert(return_true("asdf", 5, NULL, 1, "qwer") == TRUE);
|
||||
|
||||
ck_assert(return_false() == FALSE);
|
||||
ck_assert(return_false("asdf", 5, NULL, 1, "qwer") == FALSE);
|
||||
|
||||
ck_assert(return_failed() == FAILED);
|
||||
ck_assert(return_failed("asdf", 5, NULL, 1, "qwer") == FAILED);
|
||||
|
||||
ck_assert(return_success() == SUCCESS);
|
||||
ck_assert(return_success("asdf", 5, NULL, 1, "qwer") == SUCCESS);
|
||||
|
||||
/* just make sure this works */
|
||||
nop();
|
||||
nop("asdf", 5, NULL, 1, "qwer");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* timeval_add_ms
|
||||
*/
|
||||
|
||||
START_TEST(test_timeval_add_ms)
|
||||
{
|
||||
timeval_t tv;
|
||||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
timeval_add_ms(&tv, 0);
|
||||
ck_assert_int_eq(tv.tv_sec, 0);
|
||||
ck_assert_int_eq(tv.tv_usec, 0);
|
||||
|
||||
timeval_add_ms(&tv, 1);
|
||||
ck_assert_int_eq(tv.tv_sec, 0);
|
||||
ck_assert_int_eq(tv.tv_usec, 1000);
|
||||
|
||||
timeval_add_ms(&tv, 0);
|
||||
ck_assert_int_eq(tv.tv_sec, 0);
|
||||
ck_assert_int_eq(tv.tv_usec, 1000);
|
||||
|
||||
timeval_add_ms(&tv, 999);
|
||||
ck_assert_int_eq(tv.tv_sec, 1);
|
||||
ck_assert_int_eq(tv.tv_usec, 0);
|
||||
|
||||
timeval_add_ms(&tv, 0);
|
||||
ck_assert_int_eq(tv.tv_sec, 1);
|
||||
ck_assert_int_eq(tv.tv_usec, 0);
|
||||
|
||||
timeval_add_ms(&tv, 1000);
|
||||
ck_assert_int_eq(tv.tv_sec, 2);
|
||||
ck_assert_int_eq(tv.tv_usec, 0);
|
||||
|
||||
timeval_add_ms(&tv, 1500);
|
||||
ck_assert_int_eq(tv.tv_sec, 3);
|
||||
ck_assert_int_eq(tv.tv_usec, 500000);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* htoun/untoh
|
||||
*/
|
||||
|
||||
START_TEST(test_htoun)
|
||||
{
|
||||
chunk_t net64, expected;
|
||||
u_int16_t host16 = 513;
|
||||
u_int32_t net16 = 0, host32 = 67305985;
|
||||
u_int64_t net32 = 0, host64 = 578437695752307201ULL;
|
||||
|
||||
net64 = chunk_alloca(16);
|
||||
memset(net64.ptr, 0, net64.len);
|
||||
|
||||
expected = chunk_from_chars(0x00, 0x02, 0x01, 0x00);
|
||||
htoun16((char*)&net16 + 1, host16);
|
||||
ck_assert(chunk_equals(expected, chunk_from_thing(net16)));
|
||||
|
||||
expected = chunk_from_chars(0x00, 0x00, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00);
|
||||
htoun32((u_int16_t*)&net32 + 1, host32);
|
||||
ck_assert(chunk_equals(expected, chunk_from_thing(net32)));
|
||||
|
||||
expected = chunk_from_chars(0x00, 0x00, 0x00, 0x00,
|
||||
0x08, 0x07, 0x06, 0x05,
|
||||
0x04, 0x03, 0x02, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00);
|
||||
htoun64((u_int32_t*)net64.ptr + 1, host64);
|
||||
ck_assert(chunk_equals(expected, net64));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_untoh)
|
||||
{
|
||||
chunk_t net;
|
||||
u_int16_t host16;
|
||||
u_int32_t host32;
|
||||
u_int64_t host64;
|
||||
|
||||
net = chunk_from_chars(0x00, 0x02, 0x01, 0x00);
|
||||
host16 = untoh16(net.ptr + 1);
|
||||
ck_assert(host16 == 513);
|
||||
|
||||
net = chunk_from_chars(0x00, 0x00, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00);
|
||||
host32 = untoh32(net.ptr + 2);
|
||||
ck_assert(host32 == 67305985);
|
||||
|
||||
net = chunk_from_chars(0x00, 0x00, 0x00, 0x00, 0x08, 0x07, 0x06, 0x05,
|
||||
0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00);
|
||||
host64 = untoh64(net.ptr + 4);
|
||||
ck_assert(host64 == 578437695752307201ULL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* pad_len/round_up/down
|
||||
*/
|
||||
|
||||
START_TEST(test_round)
|
||||
{
|
||||
ck_assert_int_eq(pad_len(0, 4), 0);
|
||||
ck_assert_int_eq(pad_len(1, 4), 3);
|
||||
ck_assert_int_eq(pad_len(2, 4), 2);
|
||||
ck_assert_int_eq(pad_len(3, 4), 1);
|
||||
ck_assert_int_eq(pad_len(4, 4), 0);
|
||||
ck_assert_int_eq(pad_len(5, 4), 3);
|
||||
|
||||
ck_assert_int_eq(round_up(0, 4), 0);
|
||||
ck_assert_int_eq(round_up(1, 4), 4);
|
||||
ck_assert_int_eq(round_up(2, 4), 4);
|
||||
ck_assert_int_eq(round_up(3, 4), 4);
|
||||
ck_assert_int_eq(round_up(4, 4), 4);
|
||||
ck_assert_int_eq(round_up(5, 4), 8);
|
||||
|
||||
ck_assert_int_eq(round_down(0, 4), 0);
|
||||
ck_assert_int_eq(round_down(1, 4), 0);
|
||||
ck_assert_int_eq(round_down(2, 4), 0);
|
||||
ck_assert_int_eq(round_down(3, 4), 0);
|
||||
ck_assert_int_eq(round_down(4, 4), 4);
|
||||
ck_assert_int_eq(round_down(5, 4), 4);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* strpfx
|
||||
*/
|
||||
|
||||
static struct {
|
||||
char *str;
|
||||
char *pfx;
|
||||
bool prefix;
|
||||
bool case_prefix;
|
||||
} strpfx_data[] = {
|
||||
{"", "", TRUE, TRUE},
|
||||
{"abc", "", TRUE, TRUE},
|
||||
{"abc", "a", TRUE, TRUE},
|
||||
{"abc", "ab", TRUE, TRUE},
|
||||
{"abc", "abc", TRUE, TRUE},
|
||||
{"abc", "abcd", FALSE, FALSE},
|
||||
{"abc", "AB", FALSE, TRUE},
|
||||
{"ABC", "ab", FALSE, TRUE},
|
||||
{" abc", "abc", FALSE, FALSE},
|
||||
};
|
||||
|
||||
START_TEST(test_strpfx)
|
||||
{
|
||||
bool prefix;
|
||||
|
||||
prefix = strpfx(strpfx_data[_i].str, strpfx_data[_i].pfx);
|
||||
ck_assert(prefix == strpfx_data[_i].prefix);
|
||||
prefix = strcasepfx(strpfx_data[_i].str, strpfx_data[_i].pfx);
|
||||
ck_assert(prefix == strpfx_data[_i].case_prefix);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* memxor
|
||||
*/
|
||||
|
||||
static void do_memxor(chunk_t a, chunk_t b, chunk_t exp)
|
||||
{
|
||||
chunk_t dst;
|
||||
|
||||
dst = chunk_clonea(a);
|
||||
dst.len = b.len;
|
||||
memxor(dst.ptr, b.ptr, b.len);
|
||||
ck_assert(chunk_equals(dst, exp));
|
||||
}
|
||||
|
||||
START_TEST(test_memxor)
|
||||
{
|
||||
chunk_t a, b, dst;
|
||||
int i;
|
||||
|
||||
a = chunk_alloca(64);
|
||||
memset(a.ptr, 0, a.len);
|
||||
b = chunk_alloca(64);
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
b.ptr[i] = i;
|
||||
b.len = i;
|
||||
do_memxor(a, b, b);
|
||||
}
|
||||
b.len = 64;
|
||||
do_memxor(a, b, b);
|
||||
|
||||
dst = chunk_clonea(a);
|
||||
memxor(dst.ptr, b.ptr, b.len);
|
||||
ck_assert(chunk_equals(dst, b));
|
||||
|
||||
memxor(dst.ptr, b.ptr, 0);
|
||||
memxor(dst.ptr, b.ptr, 1);
|
||||
memxor(dst.ptr + 1, b.ptr + 1, 1);
|
||||
memxor(dst.ptr + 2, b.ptr + 2, b.len - 2);
|
||||
ck_assert(chunk_equals(dst, a));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_memxor_aligned)
|
||||
{
|
||||
u_int64_t a = 0, b = 0;
|
||||
chunk_t ca, cb;
|
||||
int i;
|
||||
|
||||
ca = chunk_from_thing(a);
|
||||
cb = chunk_from_thing(b);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
cb.ptr[i] = i + 1;
|
||||
}
|
||||
|
||||
/* 64-bit aligned */
|
||||
memxor(ca.ptr, cb.ptr, 8);
|
||||
ck_assert(a == b);
|
||||
/* 32-bit aligned source */
|
||||
a = 0;
|
||||
memxor(ca.ptr, cb.ptr + 4, 4);
|
||||
ck_assert(chunk_equals(ca, chunk_from_chars(0x05, 0x06, 0x07, 0x08,
|
||||
0x00, 0x00, 0x00, 0x00)));
|
||||
/* 16-bit aligned source */
|
||||
a = 0;
|
||||
memxor(ca.ptr, cb.ptr + 2, 6);
|
||||
ck_assert(chunk_equals(ca, chunk_from_chars(0x03, 0x04, 0x05, 0x06,
|
||||
0x07, 0x08, 0x00, 0x00)));
|
||||
/* 8-bit aligned source */
|
||||
a = 0;
|
||||
memxor(ca.ptr, cb.ptr + 1, 7);
|
||||
ck_assert(chunk_equals(ca, chunk_from_chars(0x02, 0x03, 0x04, 0x05,
|
||||
0x06, 0x07, 0x08, 0x00)));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* memstr
|
||||
*/
|
||||
|
||||
static struct {
|
||||
char *haystack;
|
||||
char *needle;
|
||||
size_t n;
|
||||
int offset;
|
||||
} memstr_data[] = {
|
||||
{NULL, NULL, 0, -1},
|
||||
{NULL, NULL, 3, -1},
|
||||
{NULL, "abc", 0, -1},
|
||||
{NULL, "abc", 3, -1},
|
||||
{"", "", 0, -1},
|
||||
{"abc", NULL, 3, -1},
|
||||
{"abc", "", 3, -1},
|
||||
{"abc", "abc", 3, 0},
|
||||
{" abc", "abc", 4, 1},
|
||||
{" abc", "abc", 3, -1},
|
||||
{"abcabc", "abc", 6, 0},
|
||||
{" abc ", "abc", 5, 1},
|
||||
};
|
||||
|
||||
START_TEST(test_memstr)
|
||||
{
|
||||
char *ret;
|
||||
|
||||
ret = memstr(memstr_data[_i].haystack, memstr_data[_i].needle, memstr_data[_i].n);
|
||||
if (memstr_data[_i].offset >= 0)
|
||||
{
|
||||
ck_assert(ret == memstr_data[_i].haystack + memstr_data[_i].offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
ck_assert(ret == NULL);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* translate
|
||||
*/
|
||||
|
||||
static struct {
|
||||
char *in;
|
||||
char *from;
|
||||
char *to;
|
||||
char *out;
|
||||
} translate_data[] = {
|
||||
{NULL, "", "", NULL},
|
||||
{"abc", "", "", "abc"},
|
||||
{"abc", "", "x", "abc"},
|
||||
{"abc", "x", "", "abc"},
|
||||
{"abc", "abc", "xyz", "xyz"},
|
||||
{"aabbcc", "abc", "xyz", "xxyyzz"},
|
||||
{"abbaccb", "abc", "xyz", "xyyxzzy"},
|
||||
{"abxyzc", "abc", "xyz", "xyxyzz"},
|
||||
{"abcdef", "abc", "xyz", "xyzdef"},
|
||||
{"aaa", "abc", "xyz", "xxx"},
|
||||
{"abc", "aaa", "xyz", "xbc"},
|
||||
{"abc", "abc", "xxx", "xxx"},
|
||||
};
|
||||
|
||||
START_TEST(test_translate)
|
||||
{
|
||||
char *str, *ret;
|
||||
|
||||
str = strdupnull(translate_data[_i].in);
|
||||
ret = translate(str, translate_data[_i].from, translate_data[_i].to);
|
||||
ck_assert(ret == str);
|
||||
if (ret != translate_data[_i].out)
|
||||
{
|
||||
ck_assert_str_eq(str, translate_data[_i].out);
|
||||
}
|
||||
free(str);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* time_printf_hook
|
||||
*/
|
||||
|
||||
static struct {
|
||||
time_t in;
|
||||
bool utc;
|
||||
char *out;
|
||||
} time_data[] = {
|
||||
{UNDEFINED_TIME, FALSE, "--- -- --:--:-- ----"},
|
||||
{UNDEFINED_TIME, TRUE , "--- -- --:--:-- UTC ----"},
|
||||
{1, FALSE, "Jan 01 01:00:01 1970"},
|
||||
{1, TRUE , "Jan 01 00:00:01 UTC 1970"},
|
||||
{1341150196, FALSE, "Jul 01 15:43:16 2012"},
|
||||
{1341150196, TRUE , "Jul 01 13:43:16 UTC 2012"},
|
||||
};
|
||||
|
||||
START_TEST(test_time_printf_hook)
|
||||
{
|
||||
char buf[32];
|
||||
int len;
|
||||
|
||||
len = snprintf(buf, sizeof(buf), "%T", &time_data[_i].in, time_data[_i].utc);
|
||||
ck_assert(len >= 0 && len < sizeof(buf));
|
||||
ck_assert_str_eq(buf, time_data[_i].out);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* time_delta_printf_hook
|
||||
*/
|
||||
|
||||
static struct {
|
||||
time_t a;
|
||||
time_t b;
|
||||
char *out;
|
||||
} time_delta_data[] = {
|
||||
{0, 0, "0 seconds"},
|
||||
{0, 1, "1 second"},
|
||||
{0, -1, "1 second"},
|
||||
{1, 0, "1 second"},
|
||||
{0, 2, "2 seconds"},
|
||||
{2, 0, "2 seconds"},
|
||||
{0, 60, "60 seconds"},
|
||||
{0, 120, "120 seconds"},
|
||||
{0, 121, "2 minutes"},
|
||||
{0, 3600, "60 minutes"},
|
||||
{0, 7200, "120 minutes"},
|
||||
{0, 7201, "2 hours"},
|
||||
{0, 86400, "24 hours"},
|
||||
{0, 172800, "48 hours"},
|
||||
{0, 172801, "2 days"},
|
||||
{172801, 86400, "24 hours"},
|
||||
};
|
||||
|
||||
START_TEST(test_time_delta_printf_hook)
|
||||
{
|
||||
char buf[16];
|
||||
int len;
|
||||
|
||||
len = snprintf(buf, sizeof(buf), "%V", &time_delta_data[_i].a, &time_delta_data[_i].b);
|
||||
ck_assert(len >= 0 && len < sizeof(buf));
|
||||
ck_assert_str_eq(buf, time_delta_data[_i].out);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* mark_from_string
|
||||
*/
|
||||
|
||||
static struct {
|
||||
char *s;
|
||||
bool ok;
|
||||
mark_t m;
|
||||
} mark_data[] = {
|
||||
{NULL, FALSE, { 0 }},
|
||||
{"", TRUE, { 0, 0xffffffff }},
|
||||
{"/", TRUE, { 0, 0 }},
|
||||
{"42", TRUE, { 42, 0xffffffff }},
|
||||
{"0x42", TRUE, { 0x42, 0xffffffff }},
|
||||
{"x", FALSE, { 0 }},
|
||||
{"42/", TRUE, { 0, 0 }},
|
||||
{"42/0", TRUE, { 0, 0 }},
|
||||
{"42/x", FALSE, { 0 }},
|
||||
{"42/42", TRUE, { 42, 42 }},
|
||||
{"42/0xff", TRUE, { 42, 0xff }},
|
||||
{"0x42/0xff", TRUE, { 0x42, 0xff }},
|
||||
{"/0xff", TRUE, { 0, 0xff }},
|
||||
{"/x", FALSE, { 0 }},
|
||||
{"x/x", FALSE, { 0 }},
|
||||
{"0xffffffff/0x0000ffff", TRUE, { 0x0000ffff, 0x0000ffff }},
|
||||
{"0xffffffff/0xffffffff", TRUE, { 0xffffffff, 0xffffffff }},
|
||||
};
|
||||
|
||||
START_TEST(test_mark_from_string)
|
||||
{
|
||||
mark_t mark;
|
||||
|
||||
if (mark_from_string(mark_data[_i].s, &mark))
|
||||
{
|
||||
ck_assert_int_eq(mark.value, mark_data[_i].m.value);
|
||||
ck_assert_int_eq(mark.mask, mark_data[_i].m.mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
ck_assert(!mark_data[_i].ok);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *utils_suite_create()
|
||||
{
|
||||
Suite *s;
|
||||
TCase *tc;
|
||||
|
||||
/* force a timezone to match non-UTC conversions */
|
||||
setenv("TZ", "Europe/Zurich", 1);
|
||||
tzset();
|
||||
|
||||
s = suite_create("utils");
|
||||
|
||||
tc = tcase_create("objects");
|
||||
tcase_add_test(tc, test_objects);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("return functions");
|
||||
tcase_add_test(tc, test_return_functions);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("timeval_add_ms");
|
||||
tcase_add_test(tc, test_timeval_add_ms);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("htoun,untoh");
|
||||
tcase_add_test(tc, test_htoun);
|
||||
tcase_add_test(tc, test_untoh);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("round");
|
||||
tcase_add_test(tc, test_round);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("string helper");
|
||||
tcase_add_loop_test(tc, test_strpfx, 0, countof(strpfx_data));
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("memxor");
|
||||
tcase_add_test(tc, test_memxor);
|
||||
tcase_add_test(tc, test_memxor_aligned);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("memstr");
|
||||
tcase_add_loop_test(tc, test_memstr, 0, countof(memstr_data));
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("translate");
|
||||
tcase_add_loop_test(tc, test_translate, 0, countof(translate_data));
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("printf_hooks");
|
||||
tcase_add_loop_test(tc, test_time_printf_hook, 0, countof(time_data));
|
||||
tcase_add_loop_test(tc, test_time_delta_printf_hook, 0, countof(time_delta_data));
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("mark_from_string");
|
||||
tcase_add_loop_test(tc, test_mark_from_string, 0, countof(mark_data));
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Martin Willi
|
||||
* Copyright (C) 2013 revosec AG
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_suite.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Check if test vectors have been successful during transform registration
|
||||
*/
|
||||
|
||||
START_TEST(test_vectors)
|
||||
{
|
||||
fail_if(lib->crypto->get_test_vector_failures(lib->crypto));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
Suite *vectors_suite_create()
|
||||
{
|
||||
Suite *s;
|
||||
TCase *tc;
|
||||
|
||||
s = suite_create("vectors");
|
||||
|
||||
tc = tcase_create("failures");
|
||||
tcase_add_test(tc, test_vectors);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
Reference in New Issue
Block a user